How-to guidesAdd an HTML attribute tool

Add an HTML attribute tool

Paths are relative to apps/frontend/src/app/(dashboard)/editor/[projectId]/[pageId]/Components/PropsController/.

  1. Open attrToolDefinitions.tsx and pick the group in ATTR_TOOL_GROUPS.

  2. Add a fieldTool with an appliesTo predicate:

    fieldTool(
        "html-search-input",
        "Search input",
        [
            TEXT("placeholder", "Search…"),
            { kind: "idref", attr: "list", filter: (n) => n.tag === "datalist" },
            BOOL("required"),
        ],
        inputTypes("search")
    ),

    Use tags(...) for element tags, inputTypes(...) for input types, or any (ctx) => boolean. Omit it for global attributes.

  3. Prefix the id with html- so its open state doesn’t collide with a Style tool id.

  4. For attributes where an empty value has a meaning, use emptyAs (select/segmented) or emptyToggle (text). Otherwise an empty input removes the attribute.

  5. Run npx tsc --noEmit and npx eslint on the folder, then check the tool with one element, several elements of the same tag, and a mixed selection.

Common variations

  • Custom tool. Create tools/MyTool.tsx, use useAttrTool() for nodes/attributes and useAttrWriter() for writes (null removes). Register { id, title, attributes, appliesTo, render: () => <MyTool /> }; add count if the badge shouldn’t be derived from attributes.
  • Page head setting. Add a HeadFieldSpec to a headFieldTool(...) in the Page settings group, e.g. meta("Author", "author").
  • Elements other than the selection. Pass nodes={[node]} to AttrField/AttrRow, or { nodes } to setAttributes.

Troubleshooting

  • The tool never shows. ctx.tag is null for mixed-tag selections; check the predicate with a single element first.
  • A boolean attribute can’t be turned off. Use kind: "boolean"; writing "" keeps the attribute present.