Add a style tool
Paths are relative to apps/frontend/src/app/(dashboard)/editor/[projectId]/[pageId]/Components/StyleTools/.
Field-based tool
Use when each property maps to one input.
-
Open
toolDefinitions.tsxand find the group inTOOL_GROUPS(or add a{ id, title, tools: [] }group). -
Add a
fieldTool(id, title, fields)entry:fieldTool("text-emphasis", "Text emphasis", [ { kind: "select", property: "text-emphasis-style", label: "Style", options: ["none", "filled", "open", "dot", "circle"], allowCustom: true }, { kind: "color", property: "text-emphasis-color", label: "Color" }, { kind: "segmented", property: "text-emphasis-position", label: "Position", options: seg(["over right", "under right"]) }, ]), -
For
unitfields, add the property to@/Utils/Style/cssPropertyUnits.tsor passunitsexplicitly. -
Long option lists go in
toolOptions.ts. -
Run
npx tsc --noEmit,npx eslinton the folder, and check the tool in the editor on the Style, Inline Style and a matched-rule target.
Custom tool
Use when properties are coupled (layers, per-side targeting, shorthands).
-
Create
tools/MyTool.tsx. Read withuseStyleTool().controlledStyleand write withuseStyleWriter():export default function MyTool() { const { controlledStyle } = useStyleTool(); const setProperties = useStyleWriter(); return ( <PropertyRow label="Inset shadow" properties={["box-shadow"]}> <MeasureInput value={controlledStyle["box-shadow"] ?? ""} onChange={(v, live) => setProperties({ "box-shadow": v }, live)} /> </PropertyRow> ); } -
Register it:
customTool("my-tool", "My tool", ["box-shadow"], () => <MyTool />). The property list feeds the badge and search. -
Pass
livethrough from every input that reports it, so drags collapse into one undo step. -
Write several properties in one
setProperties({...})call when they belong to one user action.
Common variations
- New input type. Add a component to
../Inputs/(controlled,onChange(value, live?)), akindtoFieldSpecinPropertyField.tsx, and acasein its switch. Add the kind toWIDEif it should stack. - Shorthand vs longhand. Prefer writing longhands; shorthands overwrite sibling longhands already in the rule.
Troubleshooting
- The tool doesn’t appear in search. The words are matched against
title, group title andproperties; custom tools must list their properties. - A drag creates many undo steps. An input is calling
onChangewithoutlive: true, or the tool drops theliveargument.
Related
- Reference: Style tools framework
- Reference: Editor inputs