The designer is built with a flexible layer system that allows you to create custom layers. This guide will show you how to build and use your own layer types.
Layer Type
A layer type in designer is an object that defines the properties of a layer and how it is rendered.
Here's the type definition for a layer type:
type LayerType = {
type: string
name: string
icon: ReactNode
defaultValues: Omit<Layer, "id" | "type">
render: (layer: LayerWithStyles) => React.ReactNode
keybinding?: Keybinding
}Creating a Custom Layer
We'll create a new custom layer type called shape. It will be a circle shape that can be resized and rotated.
Create a new file called src/layers/shape.tsx and add the following code.
Let's start by defining the layer type.
import { type LayerType } from "@shadcn/designer";
import { IconCircle } from "@tabler/icons-react";
export const shapeLayer = {
type: "shape",
name: "Shape",
icon: <IconCircle />,
defaultValues: {
name: "Shape",
value: "circle",
cssVars: {
"--width": "100px",
"--height": "100px",
"--background-color": "#000000",
"--border-radius": "50%",
},
},
keybinding: {
key: "s",
label: "S",
labelMac: "S",
description: "Add Shape",
group: "New Layer",
},
render: (layer) => {
return (
<div
style={{
aspectRatio: "1/1",
...layer.contentStyle,
}}
/>
);
},
} satisfies LayerType;The shapeLayer is a custom layer type that can be used in the designer. It has a type of shape, a name of Shape, an icon of a circle, a default value of a circle, a keybinding of s for Shape, and a render function that renders a div with the content style.
We have set the default value of the layer to a circle.
Using Custom Layers
To use your custom layer, you need to extend the default layer types and pass them to the Designer component:
Extending the default layer types ensures you can add, remove and override existing layer types easily.
import { Designer, DEFAULT_LAYER_TYPES } from "@shadcn/designer"
import { shapeLayer } from "./layers/shape";
function MyDesigner() {
// Extend the default layer types with your custom layer
const layerTypes = [...DEFAULT_LAYER_TYPES, shapeLayer]
return (
<Designer
layerTypes={layerTypes}
>
<DesignerContent>
<DesignerCanvas>
<DesignerFrame />
</DesignerCanvas>
</DesignerContent>
</Designer>
)
}The designer will take care of automatically adding the new layer type, handle rendering, keyboard shortcuts, and more. If you provide an icon, it will also show up in the <DesignerToolbar />.
Click on the circle icon in the toolbar to add a new shape layer to the canvas. You can also press S on your keyboard to add a new shape layer.
Best Practices
- Unique Type: Always use a unique
typeidentifier for your layer. - Default Values: Provide sensible default values for the layer name, value, and CSS variables.
- Keyboard Shortcuts: Add keyboard shortcuts for better user experience.
- Rendering: Ensure you use the
layer.contentStyleto style the layer.
Remember to test your layers thoroughly with the designer's transformation tools.
Custom Layer Action
Now that we have a custom layer, let's add a custom action to the layer. We'll add a custom action to change the color of the shape.
Let's create a ActionShapeColor component inside src/actions/shape-color.tsx and add the following code.
import { Action, ActionControls, ActionLabel } from "@shadcn/designer/ui";
export function ActionShapeColor() {
return (
<Action>
<ActionLabel>Color</ActionLabel>
<ActionControls>
// Control here.
</ActionControls>
</Action>
);
}To change the color of the shape, we use the CSS variable --background-color. The designer package provides two functions to help us create a custom action to change the color of the shape: createLayerCssVarAction and useLayerCssVarAction.
import { Action, ActionControls, ActionLabel } from "@shadcn/designer/ui";
import { createLayerCssVarAction, useLayerCssVarAction } from "@shadcn/designer";
const backgroundColor = createLayerCssVarAction("--background-color", "#000000");
export function ActionShapeColor() {
const [value, setValue] = useLayerCssVarAction(backgroundColor);
return (
<Action>
<ActionLabel>Color</ActionLabel>
<ActionControls>
<button onClick={() => setValue("#ff0000")}>Red</button>
</ActionControls>
</Action>
);
}Import the ActionShapeColor component into your src/App.tsx file and add the ActionShapeColor component to the <DesignerPane /> with the showForLayerTypes prop set to ["shape"].
We use the showForLayerTypes prop to only show the pane when shape layers are selected.
If you're following along from the Installation guide, add the code to the <PanelRight /> component in src/panel-right.tsx file.
import { Designer, DesignerContent, DesignerCanvas, DesignerFrame, DesignerPanel, DesignerPane, DesignerPaneTitle, DesignerPaneContent } from "@shadcn/designer";
import "@shadcn/designer/styles.css";
import { ActionShapeColor } from "./actions/shape-color";
export default function App() {
return (
<Designer>
<DesignerContent>
<DesignerCanvas>
<DesignerFrame />
</DesignerCanvas>
<DesignerPanel>
<DesignerPane showForLayerTypes={["shape"]}>
<DesignerPaneTitle>Shape</DesignerPaneTitle>
<DesignerPaneContent>
<ActionShapeColor />
</DesignerPaneContent>
</DesignerPane>
</DesignerPanel>
</DesignerContent>
</Designer>
)
}Add a new Shape layer to the canvas by clicking on the circle icon in the toolbar. You should see a new Color action in the right panel. Click on the Red button to change the color of the shape to red.
If you add more than one shape layer to the canvas, you can drag to select multiple layers and change the color of all of them at once.
Next Steps
- See the Custom Layers section for more examples of custom layers with complex actions and controls.
- Learn how to use the theme system to customize the designer's appearance.
- Learn how to use the unit system.
- Learn more about the designer components and hooks.