Skip to content

Instantly share code, notes, and snippets.

@jonathanstanley
Created October 3, 2025 00:25
Show Gist options
  • Save jonathanstanley/6050580bed595d6022e44d3d8c478a5c to your computer and use it in GitHub Desktop.
Save jonathanstanley/6050580bed595d6022e44d3d8c478a5c to your computer and use it in GitHub Desktop.
import { addPropertyControls, ControlType, FrameProps } from "framer"
import { cloneElement, isValidElement } from "react"
export default function CustomElement(props: FrameProps) {
const { style, id, children } = props
const childToRender = isValidElement(children)
? children
: isValidElement(children?.[0])
? children[0]
: null
return (
<div style={style} id={id}>
{childToRender ? (
cloneElement(childToRender, {
...childToRender.props,
style: {
...(childToRender.props.style ?? {}),
width: style?.width ?? "100%",
height: style?.height ?? "100%",
},
})
) : (
<span style={{ color: "red", fontSize: "12px" }}>
Please connect to a frame from off the canvas
</span>
)}
</div>
)
}
addPropertyControls(CustomElement, {
children: {
title: "Frame",
type: ControlType.ComponentInstance,
},
id: {
type: ControlType.String,
title: "ID",
description: "HTML id",
placeholder: "example-element-id",
},
})
{childToRender ? (
cloneElement(childToRender, {
...childToRender.props,
style: {
...(childToRender.props.style ?? {}),
width: style?.width ?? "100%",
height: style?.height ?? "100%",
},
})
) : (
<span style={{ color: "red", fontSize: "12px" }}>
Please connect to a frame from off the canvas
</span>
)}
</div>
)
}
@jonathanstanley
Copy link
Author

jonathanstanley commented Oct 3, 2025

I used this experiment to familiarize myself with Framer's Custom Code Component. Although this "works", it probably isn't useful on its own. It does highlight some of the limitations with Framer.

  1. Code Components cannot have children to drag and drop through the layers panel
  2. Code Components can have a property that allows the user to select a framer/component from off the canvas. This was its own discovery because I couldn't find any documentation of this requirement. If all your components are within the canvas, you will have an empty select list.
  3. Component overrides cannot have properties. For example, you could have an override that hardcodes an HTML element ID. But you could not let the user type an ID and use the override to set the ID.
  4. Framer injects a wrapper around the element in edit mode. So, in this example, we have to check to locate the correct child
  5. I cannot locate an authoritative or comprehensive list of libraries, or complete documentation of the "framer" import. I only find the limited developer docs. Once imported, the code seems decently commented.
  6. Since the child/children must be off canvas, they do not have any parent size to bind to (you can't use fill). But, since we're treating it as a child, this is an example a way to override the sizing so that the child receives the same size as this custom component. However, the recommended approach is RenderTarget
  7. In my case, I was wanting an ID to have a straightforward css selection. Instead, it appears you can use CSS attribute selectors using the data-framer-name property. here is what you can expect to find in the framer rendered HTML:
<div class="..." data-framer-name="Example Element Name" >

If anyone does find this helpful, or has thoughts to add, please let me know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment