Token导航 LogoToken导航TokenDH.com
开发权限需确认github未标认证来源可访问许可证需确认审计未展示

framer-code-components-overridesFramer 代码组件 overrides

Agent Skill

framer-code-components-overrides 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

5,090

周安装

210

GitHub Stars

126

下载量

1,663
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:framer-code-components-overrides(Framer 代码组件 overrides)
来源仓库:https://github.com/fredm00n/framerlabs
仓库路径:skills/framer-code-components-overrides
安装命令:
npx skills add https://github.com/fredm00n/framerlabs --skill framer-code-components-overrides
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/fredm00n/framerlabs --skill framer-code-components-overrides

简介

framer-code-components-overrides 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中围绕仓库状态或协作事项进行整理。
  • 通过 npx skills add 命令从指定 GitHub 仓库安装,需确认权限和维护状态。
  • 使用前应检查是否会触发联网、命令执行或文件读写操作。
  • 建议结合原始 README 和项目上下文核验具体用法和功能边界。

SKILL.md

Framer Code Development

Code Components vs Code Overrides

Code Components: Custom React components added to canvas. Support addPropertyControls.

Code Overrides: Higher-order components wrapping existing canvas elements. Do NOT support addPropertyControls.

Required Annotations

Always include at minimum:

/**
 * @framerDisableUnlink
 * @framerIntrinsicWidth 100
 * @framerIntrinsicHeight 100
 */

Full set:

  • @framerDisableUnlink — Prevents unlinking when modified
  • @framerIntrinsicWidth / @framerIntrinsicHeight — Default dimensions
  • @framerSupportedLayoutWidth / @framerSupportedLayoutHeightany, auto, fixed, any-prefer-fixed

Code Override Pattern

import type { ComponentType } from "react"
import { useState, useEffect } from "react"

/**
 * @framerDisableUnlink
 */
export function withFeatureName(Component): ComponentType {
    return (props) => {
        // State and logic here
        return <Component {...props} />
    }
}

Naming: Always use withFeatureName prefix.

Code Component Pattern

import { motion } from "framer-motion"
import { addPropertyControls, ControlType } from "framer"

/**
 * @framerDisableUnlink
 * @framerIntrinsicWidth 300
 * @framerIntrinsicHeight 200
 */
export default function MyComponent(props) {
    const { style } = props
    return <motion.div style={{ ...style }}>{/* content */}</motion.div>
}

MyComponent.defaultProps = {
    // Always define defaults
}

addPropertyControls(MyComponent, {
    // Controls here
})

Critical: Font Handling

Never access font properties individually. Always spread the entire font object.

// ❌ BROKEN - Will not work
style={{
    fontFamily: props.font.fontFamily,
    fontSize: props.font.fontSize,
}}

// ✅ CORRECT - Spread entire object
style={{
    ...props.font,
}}

Font control definition:

font: {
    type: ControlType.Font,
    controls: "extended",
    defaultValue: {
        fontFamily: "Inter",
        fontWeight: 500,
        fontSize: 16,
        lineHeight: "1.5em",
    },
}

Critical: Wrap State Updates in startTransition

All React state updates in Framer must be wrapped in startTransition():

import { startTransition } from "react"

// ❌ WRONG - May cause issues in Framer's rendering pipeline
setCount(count + 1)

// ✅ CORRECT - Always wrap state updates
startTransition(() => {
    setCount(count + 1)
})

This is Framer-specific and prevents performance issues with concurrent rendering.

Critical: Hydration Safety

Framer pre-renders on server. Browser APIs unavailable during SSR.

Two-phase rendering pattern:

const [isClient, setIsClient] = useState(false)

useEffect(() => {
    setIsClient(true)
}, [])

if (!isClient) {
    return <Component {...props} /> // SSR-safe fallback
}

// Client-only logic here

Never access directly at render time:

  • window, document, navigator
  • localStorage, sessionStorage
  • window.innerWidth, window.innerHeight

Critical: Canvas vs Preview Detection

import { RenderTarget } from "framer"

const isOnCanvas = RenderTarget.current() === RenderTarget.canvas

// Show debug only in editor
{isOnCanvas && <DebugOverlay />}

Use for:

  • Debug overlays
  • Disabling heavy effects in editor
  • Preview toggles

Property Controls Reference

See references/property-controls.md for complete control types and patterns.

Common Patterns

See references/patterns.md for implementations: shared state, keyboard detection, show-once logic, scroll effects, magnetic hover, animation triggers.

Variant Control in Overrides

Cannot read variant names from props (may be hashed). Manage internally:

export function withVariantControl(Component): ComponentType {
    return (props) => {
        const [currentVariant, setCurrentVariant] = useState("variant-1")

        // Logic to change variant
        setCurrentVariant("variant-2")

        return <Component {...props} variant={currentVariant} />
    }
}

Scroll Detection Constraint

Framer's scroll detection uses viewport-based IntersectionObserver. Applying overflow: scroll to containers breaks this detection.

For scroll-triggered animations, use:

const observer = new IntersectionObserver(
    (entries) => {
        entries.forEach((entry) => {
            if (entry.isIntersecting && !hasEntered) {
                setHasEntered(true)
            }
        })
    },
    { threshold: 0.1 }
)

WebGL in Framer

See references/webgl-shaders.md for shader implementation patterns including transparency handling.

NPM Package Imports

Standard import (preferred):

import { Component } from "package-name"

Force specific version via CDN when Framer cache is stuck:

import { Component } from "https://esm.sh/package-name@1.2.3?external=react,react-dom"

Always include ?external=react,react-dom for React components.

HLS Video Streaming (.m3u8)

Chrome/Firefox do not natively support HLS streams. A plain <video src="...m3u8"> will either fail or play the lowest quality rendition permanently. Safari handles HLS natively.

Fix: Use HLS.js via dynamic import with silent fallback:

let HlsModule = null
let hlsImportAttempted = false

async function loadHls() {
    if (hlsImportAttempted) return HlsModule
    hlsImportAttempted = true
    try {
        const mod = await import("https://esm.sh/hls.js@1?external=react,react-dom")
        HlsModule = mod.default || mod
    } catch {
        HlsModule = null // Fallback to native video
    }
    return HlsModule
}

function attachHls(videoEl, src) {
    if (typeof window === "undefined") return null // SSR guard
    const Hls = HlsModule
    if (src.includes(".m3u8") && Hls?.isSupported()) {
        const hls = new Hls({ startLevel: -1, capLevelToPlayerSize: true })
        hls.loadSource(src)
        hls.attachMedia(videoEl)
        hls.on(Hls.Events.MANIFEST_PARSED, () => videoEl.play().catch(() => {}))
        hls.on(Hls.Events.ERROR, (_, data) => {
            if (data.fatal) {
                data.type === Hls.ErrorTypes.NETWORK_ERROR
                    ? hls.startLoad()
                    : hls.destroy()
            }
        })
        return hls
    }
    videoEl.src = src // MP4/webm or Safari native HLS
    videoEl.play().catch(() => {})
    return null
}

Key points:

  • Dynamic import avoids breaking the component if CDN is unreachable
  • capLevelToPlayerSize: true prevents loading 4K for a 400px player
  • Must destroy HLS instances on cleanup to prevent memory leaks
  • Use cancelled flag in effects to prevent stale attachment after fast navigation
  • Works on Framer canvas and published site

Common Pitfalls

IssueCauseFix
Font styles not applyingAccessing font props individuallySpread entire font object: ...props.font
Hydration mismatchBrowser API in renderUse isClient state pattern
Override props undefinedExpecting property controlsOverrides don't support addPropertyControls
Scroll animation brokenoverflow: scroll on containerUse IntersectionObserver on viewport
Shader attach errorNull shader from compilation failureCheck createShader() return before attachShader()
Component display nameNeed custom name in Framer UIComponent.displayName = "Name"
TypeScript Timeout errorsUsing NodeJS.Timeout typeUse number instead — browser environment
Overlay stuck under contentStacking context from parentUse React Portal to render at document.body level
Easing feels same for all curvesNot tracking initial distanceTrack initialDiff when target changes for progress calculation
HLS video permanently pixelated.m3u8 in Chrome without HLS.jsUse HLS.js dynamic import pattern (see HLS section above)

Mobile Optimization

For particle systems and heavy animations:

  • Implement resize debouncing (500ms default)
  • Add size change threshold (15% minimum)
  • Handle orientation changes with dedicated listener
  • Use touchAction: "none" to prevent scroll interference

CMS Content Timing

CMS content loads asynchronously after hydration. Processing sequence:

  1. SSR: Placeholder content
  2. Hydration: React attaches
  3. CMS Load: Real content (~50-200ms)

Add delay before processing CMS data:

useEffect(() => {
    if (isClient && props.children) {
        const timer = setTimeout(() => {
            processContent(props.children)
        }, 100)
        return () => clearTimeout(timer)
    }
}, [isClient, props.children])

Text Manipulation in Overrides

Framer text uses deeply nested structure. Process recursively:

const processChildren = (children) => {
    if (typeof children === "string") {
        return processText(children)
    }
    if (isValidElement(children)) {
        return cloneElement(children, {
            ...children.props,
            children: processChildren(children.props.children)
        })
    }
    if (Array.isArray(children)) {
        return children.map(child => processChildren(child))
    }
    return children
}

Animation Best Practices

Separate positioning from animation:

<motion.div
    style={{
        position: "absolute",
        left: `${offset}px`,  // Static positioning
        x: animatedValue,     // Animation transform
    }}
/>

Split animation phases for natural motion:

// Up: snappy pop
transition={{ duration: 0.15, ease: [0, 0, 0.39, 2.99] }}

// Down: smooth settle
transition={{ duration: 0.15, ease: [0.25, 0.46, 0.45, 0.94] }}

Safari SVG Fix

Force GPU acceleration for smooth SVG animations:

style={{
    willChange: "transform",
    transform: "translateZ(0)",
    backfaceVisibility: "hidden",
}}

Z-Index Stacking Context & React Portals

Problem: Components with position: absolute inherit their parent's stacking context. Even with z-index: 9999, they can't appear above elements outside the parent.

Solution: Use React Portal to render at document.body level:

import { createPortal } from "react-dom"

export default function ComponentWithOverlay(props) {
    const [showOverlay, setShowOverlay] = useState(false)

    return (
        <div style={{ position: "relative" }}>
            {/* Main component content */}

            {/* Overlay rendered outside parent hierarchy */}
            {showOverlay && createPortal(
                <div style={{
                    position: "fixed",  // Fixed to viewport
                    inset: 0,
                    zIndex: 9999,
                    background: "rgba(0, 0, 0, 0.8)",
                }}>
                    {/* Overlay content */}
                </div>,
                document.body
            )}
        </div>
    )
}

Key differences:

  • position: "fixed" positions relative to viewport, not parent
  • Portal breaks out of component's DOM hierarchy and stacking context
  • Works for modals, tooltips, popovers, loading overlays

Canvas vs Published: Portals work in both canvas editor and published site. No RenderTarget check needed.

Loading States with Scroll Lock

Pattern: Show loading overlay and prevent page scroll until content is ready.

const [isLoading, setIsLoading] = useState(true)
const [fadeOut, setFadeOut] = useState(false)

// Prevent scroll while loading (published site only)
useEffect(() => {
    const isPublished = RenderTarget.current() !== "CANVAS"
    if (!isPublished || !isLoading) return

    const originalOverflow = document.body.style.overflow
    document.body.style.overflow = "hidden"

    return () => {
        document.body.style.overflow = originalOverflow
    }
}, [isLoading])

// Two-phase hide: fade-out → remove from DOM
const hideLoader = () => {
    setFadeOut(true)
    setTimeout(() => setIsLoading(false), 300) // Match CSS transition
}

Scroll to top on load (fixes variant sequence issues):

useEffect(() => {
    const isPublished = RenderTarget.current() !== "CANVAS"
    if (isPublished) {
        window.scrollTo(0, 0)
    }
}, [])

Easing Curves with Lerp Animations

Problem: Exponential lerp (value += diff * speed) naturally gives ease-out. Need to track initial distance to implement other curves.

Solution: Track initialDiff when animation starts:

const animated = useRef({
    property: {
        current: 0,
        target: 0,
        initialDiff: 0,  // Track for easing calculations
    }
})

// When target changes, store initial distance
const updateTarget = (newTarget) => {
    const entry = animated.current.property
    entry.initialDiff = Math.abs(newTarget - entry.current)
    entry.target = newTarget
}

// Apply easing in animation loop
const applyEasing = (easingCurve) => {
    const v = animated.current.property
    const diff = v.target - v.current
    let speed = 0.05  // Base speed

    if (easingCurve !== "ease-out") {
        // Calculate progress: 0 at start, 1 near target
        const diffMagnitude = Math.abs(diff)
        const progress = v.initialDiff > 0
            ? Math.max(0, Math.min(1, 1 - (diffMagnitude / v.initialDiff)))
            : 1

        if (easingCurve === "ease-in") {
            // Start slow, end fast (cubic)
            speed *= (0.05 + Math.pow(progress, 3) * 10)
        } else if (easingCurve === "ease-in-out") {
            // Slow-fast-slow (smootherstep)
            const smoothed = progress * progress * progress *
                (progress * (progress * 6 - 15) + 10)
            speed *= (0.2 + smoothed * 3)
        }
    }
    // ease-out: use default exponential decay

    v.current += diff * speed
}

Why aggressive curves? Exponential lerp naturally slows down approaching target. To create noticeable ease-in, need extreme multipliers (0.05x → 10x) to overcome the natural decay.

Property control:

easingCurve: {
    type: ControlType.Enum,
    title: "Easing Curve",
    options: ["ease-out", "ease-in", "ease-in-out"],
    optionTitles: ["Ease Out", "Ease In", "Ease In/Out"],
    defaultValue: "ease-out",
}

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

34.69%
按下载量换算577

Claude

29.28%
按下载量换算487

Cursor

20.77%
按下载量换算345

Gemini CLI

9.87%
按下载量换算164

安全审计

暂无安全审计结果可展示。

权限和风险

权限需确认

当前来源未能明确判断权限范围,默认进入异常复核队列。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills