{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "fieldkit",
  "homepage": "https://fieldkit.muturi.dev",
  "items": [
    {
      "name": "form",
      "type": "registry:block",
      "title": "Form",
      "description": "Form, the schema helpers and their shared code.",
      "dependencies": [
        "@tanstack/react-form",
        "zod",
        "libphonenumber-js",
        "date-fns",
        "@zxcvbn-ts/core",
        "@zxcvbn-ts/language-common",
        "@zxcvbn-ts/language-en",
        "lucide-react",
        "@base-ui/react"
      ],
      "registryDependencies": [
        "field",
        "alert",
        "button",
        "collapsible"
      ],
      "files": [
        {
          "path": "src/components/form/form.tsx",
          "type": "registry:component",
          "target": "components/form/form.tsx"
        },
        {
          "path": "src/components/form/form-storage.tsx",
          "type": "registry:component",
          "target": "components/form/form-storage.tsx"
        },
        {
          "path": "src/components/form/form-submit-toast.tsx",
          "type": "registry:component",
          "target": "components/form/form-submit-toast.tsx"
        },
        {
          "path": "src/components/ui/toast.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/lib/form-config.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/lib/form-storage.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/lib/field-schemas.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/lib/field-required.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/lib/form-conditions.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/lib/schema-walk.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/lib/form-diff.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/lib/form-presets.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/lib/date-values.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/lib/countries.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/lib/email-domains.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/lib/password-score.ts",
          "type": "registry:lib"
        }
      ]
    },
    {
      "name": "form-text",
      "type": "registry:block",
      "title": "FormText",
      "description": "Single-line text.",
      "dependencies": [],
      "registryDependencies": [
        "input",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-text.tsx",
          "type": "registry:component",
          "target": "components/form/form-text.tsx"
        }
      ]
    },
    {
      "name": "form-email",
      "type": "registry:block",
      "title": "FormEmail",
      "description": "Email with typo hints, domain checks and code verification.",
      "dependencies": [
        "input-otp"
      ],
      "registryDependencies": [
        "input-group",
        "input-otp",
        "badge",
        "button",
        "spinner",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-email.tsx",
          "type": "registry:component",
          "target": "components/form/form-email.tsx"
        },
        {
          "path": "src/components/form/form-verification.tsx",
          "type": "registry:component",
          "target": "components/form/form-verification.tsx"
        }
      ]
    },
    {
      "name": "form-phone",
      "type": "registry:block",
      "title": "FormPhone",
      "description": "Country picker and number, checked for the chosen country.",
      "dependencies": [
        "react-phone-number-input",
        "@tanstack/react-virtual",
        "cmdk",
        "input-otp"
      ],
      "registryDependencies": [
        "input",
        "button",
        "input-otp",
        "badge",
        "popover",
        "command",
        "spinner",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-phone.tsx",
          "type": "registry:component",
          "target": "components/form/form-phone.tsx"
        },
        {
          "path": "src/components/ui/phone-input.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/option-list.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/form/form-verification.tsx",
          "type": "registry:component",
          "target": "components/form/form-verification.tsx"
        }
      ]
    },
    {
      "name": "form-password",
      "type": "registry:block",
      "title": "FormPassword",
      "description": "Show toggle and an optional strength meter.",
      "dependencies": [],
      "registryDependencies": [
        "input-group",
        "tooltip",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-password.tsx",
          "type": "registry:component",
          "target": "components/form/form-password.tsx"
        },
        {
          "path": "src/components/form/password-strength.tsx",
          "type": "registry:component",
          "target": "components/form/password-strength.tsx"
        }
      ]
    },
    {
      "name": "form-url",
      "type": "registry:block",
      "title": "FormUrl",
      "description": "Web address. Adds https:// when it is missing.",
      "dependencies": [],
      "registryDependencies": [
        "input",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-url.tsx",
          "type": "registry:component",
          "target": "components/form/form-url.tsx"
        }
      ]
    },
    {
      "name": "form-textarea",
      "type": "registry:block",
      "title": "FormTextarea",
      "description": "Multi-line text with a character counter.",
      "dependencies": [],
      "registryDependencies": [
        "textarea",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-textarea.tsx",
          "type": "registry:component",
          "target": "components/form/form-textarea.tsx"
        }
      ]
    },
    {
      "name": "form-rich-text",
      "type": "registry:block",
      "title": "FormRichText",
      "description": "Formatted text, stored as HTML.",
      "dependencies": [
        "@tiptap/core",
        "@tiptap/react",
        "@tiptap/pm",
        "@tiptap/starter-kit",
        "@tiptap/extensions",
        "@tiptap/extension-link",
        "@tiptap/extension-text-align",
        "@tiptap/extension-highlight",
        "@tiptap/extension-subscript",
        "@tiptap/extension-superscript",
        "@tiptap/extension-text-style",
        "@tiptap/extension-code-block-lowlight",
        "lowlight",
        "@base-ui/react",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "skeleton",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-rich-text.tsx",
          "type": "registry:component",
          "target": "components/form/form-rich-text.tsx"
        },
        {
          "path": "src/components/form/rich-text-view.tsx",
          "type": "registry:component",
          "target": "components/form/rich-text-view.tsx"
        },
        {
          "path": "src/components/editor/bubble-menu/index.tsx",
          "type": "registry:component",
          "target": "components/editor/bubble-menu/index.tsx"
        },
        {
          "path": "src/components/editor/bubble-menu/language-selector.tsx",
          "type": "registry:component",
          "target": "components/editor/bubble-menu/language-selector.tsx"
        },
        {
          "path": "src/components/editor/bubble-menu/utils.ts",
          "type": "registry:component",
          "target": "components/editor/bubble-menu/utils.ts"
        },
        {
          "path": "src/components/editor/controls/rte-controls.tsx",
          "type": "registry:component",
          "target": "components/editor/controls/rte-controls.tsx"
        },
        {
          "path": "src/components/editor/controls/rte-control.tsx",
          "type": "registry:component",
          "target": "components/editor/controls/rte-control.tsx"
        },
        {
          "path": "src/components/editor/controls/rte-image-control.tsx",
          "type": "registry:component",
          "target": "components/editor/controls/rte-image-control.tsx"
        },
        {
          "path": "src/components/editor/controls/rte-link-control.tsx",
          "type": "registry:component",
          "target": "components/editor/controls/rte-link-control.tsx"
        },
        {
          "path": "src/components/editor/controls/rte-twitter-control.tsx",
          "type": "registry:component",
          "target": "components/editor/controls/rte-twitter-control.tsx"
        },
        {
          "path": "src/components/editor/controls/rte-youtube-control.tsx",
          "type": "registry:component",
          "target": "components/editor/controls/rte-youtube-control.tsx"
        },
        {
          "path": "src/components/editor/format-toolbar.tsx",
          "type": "registry:component",
          "target": "components/editor/format-toolbar.tsx"
        },
        {
          "path": "src/components/editor/extensions/code-block.ts",
          "type": "registry:component",
          "target": "components/editor/extensions/code-block.ts"
        },
        {
          "path": "src/components/editor/extensions/file-attachment.tsx",
          "type": "registry:component",
          "target": "components/editor/extensions/file-attachment.tsx"
        },
        {
          "path": "src/components/editor/extensions/file-drop.ts",
          "type": "registry:component",
          "target": "components/editor/extensions/file-drop.ts"
        },
        {
          "path": "src/components/editor/extensions/image-beside.ts",
          "type": "registry:component",
          "target": "components/editor/extensions/image-beside.ts"
        },
        {
          "path": "src/components/editor/extensions/index.ts",
          "type": "registry:component",
          "target": "components/editor/extensions/index.ts"
        },
        {
          "path": "src/components/editor/extensions/link.ts",
          "type": "registry:component",
          "target": "components/editor/extensions/link.ts"
        },
        {
          "path": "src/components/editor/extensions/rich-text-kit.ts",
          "type": "registry:component",
          "target": "components/editor/extensions/rich-text-kit.ts"
        },
        {
          "path": "src/components/editor/extensions/resizable-node-view.tsx",
          "type": "registry:component",
          "target": "components/editor/extensions/resizable-node-view.tsx"
        },
        {
          "path": "src/components/editor/icons.tsx",
          "type": "registry:component",
          "target": "components/editor/icons.tsx"
        },
        {
          "path": "src/components/editor/icon-types.ts",
          "type": "registry:component",
          "target": "components/editor/icon-types.ts"
        },
        {
          "path": "src/components/editor/index.ts",
          "type": "registry:component",
          "target": "components/editor/index.ts"
        },
        {
          "path": "src/components/editor/labels.ts",
          "type": "registry:component",
          "target": "components/editor/labels.ts"
        },
        {
          "path": "src/components/editor/language-icons.tsx",
          "type": "registry:component",
          "target": "components/editor/language-icons.tsx"
        },
        {
          "path": "src/components/editor/rte-content.tsx",
          "type": "registry:component",
          "target": "components/editor/rte-content.tsx"
        },
        {
          "path": "src/components/editor/rte-context.ts",
          "type": "registry:component",
          "target": "components/editor/rte-context.ts"
        },
        {
          "path": "src/components/editor/rte-footer.tsx",
          "type": "registry:component",
          "target": "components/editor/rte-footer.tsx"
        },
        {
          "path": "src/components/editor/rte-text-editor.tsx",
          "type": "registry:component",
          "target": "components/editor/rte-text-editor.tsx"
        },
        {
          "path": "src/components/editor/style.css",
          "type": "registry:component",
          "target": "components/editor/style.css"
        },
        {
          "path": "src/components/editor/types.ts",
          "type": "registry:component",
          "target": "components/editor/types.ts"
        },
        {
          "path": "src/components/editor/typeset.css",
          "type": "registry:component",
          "target": "components/editor/typeset.css"
        },
        {
          "path": "src/components/editor/ui/button.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/button.tsx"
        },
        {
          "path": "src/components/editor/ui/dialog.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/dialog.tsx"
        },
        {
          "path": "src/components/editor/ui/index.ts",
          "type": "registry:component",
          "target": "components/editor/ui/index.ts"
        },
        {
          "path": "src/components/editor/ui/input.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/input.tsx"
        },
        {
          "path": "src/components/editor/ui/radio-group.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/radio-group.tsx"
        },
        {
          "path": "src/components/editor/ui/popover.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/popover.tsx"
        },
        {
          "path": "src/components/editor/ui/rte-button-group.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/rte-button-group.tsx"
        },
        {
          "path": "src/components/editor/ui/rte-button.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/rte-button.tsx"
        },
        {
          "path": "src/components/editor/ui/rte-dropdown-divider.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/rte-dropdown-divider.tsx"
        },
        {
          "path": "src/components/editor/ui/rte-dropdown-icon.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/rte-dropdown-icon.tsx"
        },
        {
          "path": "src/components/editor/ui/rte-dropdown-item.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/rte-dropdown-item.tsx"
        },
        {
          "path": "src/components/editor/ui/rte-dropdown.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/rte-dropdown.tsx"
        },
        {
          "path": "src/components/editor/ui/rte-icon.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/rte-icon.tsx"
        },
        {
          "path": "src/components/editor/ui/rte-overlay.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/rte-overlay.tsx"
        },
        {
          "path": "src/components/editor/ui/rte-separator.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/rte-separator.tsx"
        },
        {
          "path": "src/components/editor/ui/toggle.tsx",
          "type": "registry:component",
          "target": "components/editor/ui/toggle.tsx"
        },
        {
          "path": "src/components/editor/ui/utils.ts",
          "type": "registry:component",
          "target": "components/editor/ui/utils.ts"
        }
      ],
      "css": {
        "@import \"@/components/editor/style.css\"": {},
        "@import \"@/components/editor/typeset.css\"": {}
      }
    },
    {
      "name": "form-number",
      "type": "registry:block",
      "title": "FormNumber",
      "description": "Numbers with min, max and whole-number checks. Empty is null.",
      "dependencies": [],
      "registryDependencies": [
        "input",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-number.tsx",
          "type": "registry:component",
          "target": "components/form/form-number.tsx"
        }
      ]
    },
    {
      "name": "form-slider",
      "type": "registry:block",
      "title": "FormSlider",
      "description": "A value, or two, inside a range.",
      "dependencies": [],
      "registryDependencies": [
        "slider",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-slider.tsx",
          "type": "registry:component",
          "target": "components/form/form-slider.tsx"
        }
      ]
    },
    {
      "name": "form-date",
      "type": "registry:block",
      "title": "FormDate",
      "description": "Type or pick a date. The calendar blocks what the schema rejects.",
      "dependencies": [
        "react-day-picker"
      ],
      "registryDependencies": [
        "input-group",
        "popover",
        "calendar",
        "input",
        "label",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-date.tsx",
          "type": "registry:component",
          "target": "components/form/form-date.tsx"
        },
        {
          "path": "src/components/form/date-input.tsx",
          "type": "registry:component",
          "target": "components/form/date-input.tsx"
        }
      ]
    },
    {
      "name": "form-date-time",
      "type": "registry:block",
      "title": "FormDateTime",
      "description": "Date and time inside a window, saved in UTC.",
      "dependencies": [
        "react-day-picker",
        "@tanstack/react-virtual",
        "cmdk"
      ],
      "registryDependencies": [
        "input-group",
        "calendar",
        "select",
        "popover",
        "command",
        "spinner",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-date-time.tsx",
          "type": "registry:component",
          "target": "components/form/form-date-time.tsx"
        },
        {
          "path": "src/components/form/date-input.tsx",
          "type": "registry:component",
          "target": "components/form/date-input.tsx"
        },
        {
          "path": "src/components/ui/option-list.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/picker-trigger.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "form-date-range",
      "type": "registry:block",
      "title": "FormDateRange",
      "description": "Start and end dates. The end must come after the start.",
      "dependencies": [
        "react-day-picker",
        "@tanstack/react-virtual",
        "cmdk"
      ],
      "registryDependencies": [
        "input-group",
        "calendar",
        "popover",
        "command",
        "spinner",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-date-range.tsx",
          "type": "registry:component",
          "target": "components/form/form-date-range.tsx"
        },
        {
          "path": "src/components/form/date-input.tsx",
          "type": "registry:component",
          "target": "components/form/date-input.tsx"
        },
        {
          "path": "src/components/ui/option-list.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/picker-trigger.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/hooks/use-mobile.ts",
          "type": "registry:hook"
        }
      ]
    },
    {
      "name": "form-select",
      "type": "registry:block",
      "title": "FormSelect",
      "description": "One option from a list of any size.",
      "dependencies": [
        "@tanstack/react-virtual",
        "cmdk"
      ],
      "registryDependencies": [
        "select",
        "input-group",
        "popover",
        "command",
        "spinner",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-select.tsx",
          "type": "registry:component",
          "target": "components/form/form-select.tsx"
        },
        {
          "path": "src/components/ui/option-list.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/picker-trigger.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "form-country",
      "type": "registry:block",
      "title": "FormCountry",
      "description": "Searchable country list with flags, saved as an ISO code.",
      "dependencies": [
        "react-phone-number-input",
        "@tanstack/react-virtual",
        "cmdk"
      ],
      "registryDependencies": [
        "input",
        "button",
        "input-group",
        "popover",
        "command",
        "spinner",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-country.tsx",
          "type": "registry:component",
          "target": "components/form/form-country.tsx"
        },
        {
          "path": "src/components/ui/phone-input.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/option-list.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/picker-trigger.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "form-multi-select",
      "type": "registry:block",
      "title": "FormMultiSelect",
      "description": "Several options, shown as chips.",
      "dependencies": [
        "@tanstack/react-virtual",
        "cmdk"
      ],
      "registryDependencies": [
        "badge",
        "input-group",
        "popover",
        "command",
        "spinner",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-multi-select.tsx",
          "type": "registry:component",
          "target": "components/form/form-multi-select.tsx"
        },
        {
          "path": "src/components/ui/option-list.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/picker-trigger.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "form-combobox",
      "type": "registry:block",
      "title": "FormCombobox",
      "description": "Searchable list, with remote search and new entries.",
      "dependencies": [
        "@tanstack/react-virtual",
        "cmdk"
      ],
      "registryDependencies": [
        "input-group",
        "popover",
        "command",
        "spinner",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-combobox.tsx",
          "type": "registry:component",
          "target": "components/form/form-combobox.tsx"
        },
        {
          "path": "src/components/ui/option-list.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/picker-trigger.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "form-radio-group",
      "type": "registry:block",
      "title": "FormRadioGroup",
      "description": "One choice, every option visible.",
      "dependencies": [],
      "registryDependencies": [
        "radio-group",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-radio-group.tsx",
          "type": "registry:component",
          "target": "components/form/form-radio-group.tsx"
        }
      ]
    },
    {
      "name": "form-checkbox-group",
      "type": "registry:block",
      "title": "FormCheckboxGroup",
      "description": "Several choices, every option visible.",
      "dependencies": [],
      "registryDependencies": [
        "checkbox",
        "radio-group",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-checkbox-group.tsx",
          "type": "registry:component",
          "target": "components/form/form-checkbox-group.tsx"
        },
        {
          "path": "src/components/form/form-radio-group.tsx",
          "type": "registry:component",
          "target": "components/form/form-radio-group.tsx"
        }
      ]
    },
    {
      "name": "form-checkbox",
      "type": "registry:block",
      "title": "FormCheckbox",
      "description": "One yes or no, like accepting terms.",
      "dependencies": [],
      "registryDependencies": [
        "checkbox",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-checkbox.tsx",
          "type": "registry:component",
          "target": "components/form/form-checkbox.tsx"
        }
      ]
    },
    {
      "name": "form-switch",
      "type": "registry:block",
      "title": "FormSwitch",
      "description": "On or off for a setting.",
      "dependencies": [],
      "registryDependencies": [
        "switch",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-switch.tsx",
          "type": "registry:component",
          "target": "components/form/form-switch.tsx"
        }
      ]
    },
    {
      "name": "form-otp",
      "type": "registry:block",
      "title": "FormOtp",
      "description": "One-time code that fills from paste and SMS.",
      "dependencies": [
        "input-otp"
      ],
      "registryDependencies": [
        "button",
        "spinner",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-otp.tsx",
          "type": "registry:component",
          "target": "components/form/form-otp.tsx"
        },
        {
          "path": "src/components/ui/input-otp.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "form-file",
      "type": "registry:block",
      "title": "FormFile",
      "description": "Drop zone with type, size and count rules.",
      "dependencies": [
        "react-dropzone"
      ],
      "registryDependencies": [
        "button",
        "dialog",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-file.tsx",
          "type": "registry:component",
          "target": "components/form/form-file.tsx"
        },
        {
          "path": "src/components/ui/dropzone.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/lib/dropzone-files.ts",
          "type": "registry:lib"
        }
      ]
    },
    {
      "name": "form-layout",
      "type": "registry:block",
      "title": "FormLayout",
      "description": "Card or plain layout with a title and actions row.",
      "dependencies": [],
      "registryDependencies": [
        "card",
        "field",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-layout.tsx",
          "type": "registry:component",
          "target": "components/form/form-layout.tsx"
        }
      ]
    },
    {
      "name": "form-frame",
      "type": "registry:block",
      "title": "FormFrame",
      "description": "Show a form as a page, a dialog or an expandable screen.",
      "dependencies": [],
      "registryDependencies": [
        "button",
        "dialog",
        "@fieldkit/expandable-screen",
        "@fieldkit/form-layout",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-frame.tsx",
          "type": "registry:component",
          "target": "components/form/form-frame.tsx"
        }
      ]
    },
    {
      "name": "form-row",
      "type": "registry:block",
      "title": "FormRow",
      "description": "Put 1 to 3 fields side by side.",
      "dependencies": [],
      "registryDependencies": [],
      "files": [
        {
          "path": "src/components/form/form-row.tsx",
          "type": "registry:component",
          "target": "components/form/form-row.tsx"
        }
      ]
    },
    {
      "name": "form-submit",
      "type": "registry:block",
      "title": "FormSubmit and FormReset",
      "description": "Submit with a spinner. In edit mode both wait for a change.",
      "dependencies": [],
      "registryDependencies": [
        "button",
        "spinner",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-submit.tsx",
          "type": "registry:component",
          "target": "components/form/form-submit.tsx"
        },
        {
          "path": "src/components/form/form-reset.tsx",
          "type": "registry:component",
          "target": "components/form/form-reset.tsx"
        },
        {
          "path": "src/components/ui/loading-swap.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "form-rating",
      "type": "registry:block",
      "title": "FormRating",
      "description": "A score from 1 to a set maximum.",
      "dependencies": [],
      "registryDependencies": [
        "toggle-group",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-rating.tsx",
          "type": "registry:component",
          "target": "components/form/form-rating.tsx"
        }
      ]
    },
    {
      "name": "form-leave-guard",
      "type": "registry:block",
      "title": "FormLeaveGuard",
      "description": "Ask before leaving with unsaved changes. Needs TanStack Router.",
      "dependencies": [
        "@tanstack/react-router"
      ],
      "registryDependencies": [
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/form-leave-guard.tsx",
          "type": "registry:component",
          "target": "components/form/form-leave-guard.tsx"
        }
      ]
    },
    {
      "name": "json-form",
      "type": "registry:block",
      "title": "JsonForm and JsonFormView",
      "description": "Render a form, or a read-only record, from a JSON spec.",
      "dependencies": [
        "zod",
        "date-fns",
        "lucide-react"
      ],
      "registryDependencies": [
        "alert",
        "badge",
        "card",
        "field",
        "separator",
        "table",
        "@fieldkit/form-frame",
        "@fieldkit/form-layout",
        "@fieldkit/form-row",
        "@fieldkit/form-submit",
        "@fieldkit/form-text",
        "@fieldkit/form-email",
        "@fieldkit/form-phone",
        "@fieldkit/form-password",
        "@fieldkit/form-url",
        "@fieldkit/form-textarea",
        "@fieldkit/form-rich-text",
        "@fieldkit/form-number",
        "@fieldkit/form-slider",
        "@fieldkit/form-date",
        "@fieldkit/form-date-time",
        "@fieldkit/form-date-range",
        "@fieldkit/form-select",
        "@fieldkit/form-country",
        "@fieldkit/form-multi-select",
        "@fieldkit/form-combobox",
        "@fieldkit/form-radio-group",
        "@fieldkit/form-checkbox-group",
        "@fieldkit/form-checkbox",
        "@fieldkit/form-switch",
        "@fieldkit/form-otp",
        "@fieldkit/form-file",
        "@fieldkit/form-rating",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/json-form.tsx",
          "type": "registry:component",
          "target": "components/form/json-form.tsx"
        },
        {
          "path": "src/components/form/json-form-steps.tsx",
          "type": "registry:component",
          "target": "components/form/json-form-steps.tsx"
        },
        {
          "path": "src/components/form/form-stepper.tsx",
          "type": "registry:component",
          "target": "components/form/form-stepper.tsx"
        },
        {
          "path": "src/components/form/json-record.tsx",
          "type": "registry:component",
          "target": "components/form/json-record.tsx"
        },
        {
          "path": "src/lib/form-spec.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/lib/spec-values.ts",
          "type": "registry:lib"
        }
      ]
    },
    {
      "name": "form-storage-server",
      "type": "registry:block",
      "title": "Form storage server helpers",
      "description": "Presign S3 or R2 uploads and check submissions against the form spec.",
      "dependencies": [
        "aws4fetch",
        "zod"
      ],
      "registryDependencies": [
        "@fieldkit/json-form",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/lib/form-storage-server.ts",
          "type": "registry:lib"
        }
      ]
    },
    {
      "name": "spec-builder",
      "type": "registry:block",
      "title": "SpecBuilder and SpecPreview",
      "description": "A compact builder for JSON form specs, with a live preview.",
      "dependencies": [
        "@dnd-kit/core",
        "@dnd-kit/sortable",
        "lucide-react",
        "shiki",
        "@shikijs/langs"
      ],
      "registryDependencies": [
        "alert",
        "alert-dialog",
        "badge",
        "button",
        "card",
        "checkbox",
        "collapsible",
        "command",
        "dialog",
        "empty",
        "field",
        "input",
        "input-group",
        "popover",
        "select",
        "sheet",
        "switch",
        "tabs",
        "toggle-group",
        "@fieldkit/json-form",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/spec-builder.tsx",
          "type": "registry:component",
          "target": "components/form/spec-builder.tsx"
        },
        {
          "path": "src/components/form/spec-preview.tsx",
          "type": "registry:component",
          "target": "components/form/spec-preview.tsx"
        },
        {
          "path": "src/lib/spec-outline.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/components/builder/field-types.ts",
          "type": "registry:component",
          "target": "components/builder/field-types.ts"
        },
        {
          "path": "src/components/ui/action-button.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/loading-swap.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/code-snippet.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/code-block.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/lib/highlighter.ts",
          "type": "registry:lib"
        }
      ]
    },
    {
      "name": "view-designer",
      "type": "registry:block",
      "title": "ViewDesigner",
      "description": "Design how one response reads, from blocks.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "card",
        "checkbox",
        "select",
        "@fieldkit/spec-builder",
        "@fieldkit/form"
      ],
      "files": [
        {
          "path": "src/components/form/view-designer.tsx",
          "type": "registry:component",
          "target": "components/form/view-designer.tsx"
        }
      ]
    },
    {
      "name": "expandable-screen",
      "type": "registry:ui",
      "title": "ExpandableScreen",
      "description": "A trigger that opens an expandable screen.",
      "dependencies": [
        "motion",
        "lucide-react"
      ],
      "registryDependencies": [
        "button"
      ],
      "files": [
        {
          "path": "src/components/ui/expandable-screen.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "sync",
      "type": "registry:item",
      "title": "Sync",
      "description": "Updates the installed fieldkit items from the registry.",
      "files": [
        {
          "path": "src/registry/fieldkit-sync.mjs",
          "type": "registry:file",
          "target": "~/scripts/fieldkit-sync.mjs"
        }
      ]
    },
    {
      "name": "member-form",
      "type": "registry:block",
      "title": "Member form",
      "description": "The member form example. Needs TanStack Router.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "@fieldkit/form",
        "@fieldkit/form-layout",
        "@fieldkit/form-row",
        "@fieldkit/form-submit",
        "@fieldkit/form-leave-guard",
        "@fieldkit/form-text",
        "@fieldkit/form-email",
        "@fieldkit/form-phone",
        "@fieldkit/form-select",
        "@fieldkit/form-date",
        "@fieldkit/form-textarea",
        "@fieldkit/form-file",
        "@fieldkit/form-switch"
      ],
      "files": [
        {
          "path": "src/examples/member-form.tsx",
          "type": "registry:component",
          "target": "examples/member-form.tsx"
        },
        {
          "path": "src/examples/member-form-previews.tsx",
          "type": "registry:component",
          "target": "examples/member-form-previews.tsx"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "signup-form",
      "type": "registry:block",
      "title": "Sign-up form",
      "description": "The sign-up form example.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "@fieldkit/form",
        "@fieldkit/form-layout",
        "@fieldkit/form-submit",
        "@fieldkit/form-text",
        "@fieldkit/form-email",
        "@fieldkit/form-phone",
        "@fieldkit/form-password"
      ],
      "files": [
        {
          "path": "src/examples/signup-form.tsx",
          "type": "registry:component",
          "target": "examples/signup-form.tsx"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "signin-form",
      "type": "registry:block",
      "title": "Sign-in form",
      "description": "The sign-in form example.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "@fieldkit/form",
        "@fieldkit/form-layout",
        "@fieldkit/form-submit",
        "@fieldkit/form-email",
        "@fieldkit/form-password"
      ],
      "files": [
        {
          "path": "src/examples/signin-form.tsx",
          "type": "registry:component",
          "target": "examples/signin-form.tsx"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "booking-form",
      "type": "registry:block",
      "title": "Booking form",
      "description": "The booking form example.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "@fieldkit/form",
        "@fieldkit/form-layout",
        "@fieldkit/form-row",
        "@fieldkit/form-submit",
        "@fieldkit/form-date",
        "@fieldkit/form-date-range",
        "@fieldkit/form-date-time"
      ],
      "files": [
        {
          "path": "src/examples/booking-form.tsx",
          "type": "registry:component",
          "target": "examples/booking-form.tsx"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "address-form",
      "type": "registry:block",
      "title": "Address form",
      "description": "The address form example.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "@fieldkit/form",
        "@fieldkit/form-layout",
        "@fieldkit/form-row",
        "@fieldkit/form-submit",
        "@fieldkit/form-text",
        "@fieldkit/form-country",
        "@fieldkit/form-phone"
      ],
      "files": [
        {
          "path": "src/examples/address-form.tsx",
          "type": "registry:component",
          "target": "examples/address-form.tsx"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "age-form",
      "type": "registry:block",
      "title": "Number field",
      "description": "The number field example.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "@fieldkit/form",
        "@fieldkit/form-layout",
        "@fieldkit/form-submit",
        "@fieldkit/form-number"
      ],
      "files": [
        {
          "path": "src/examples/age-form.tsx",
          "type": "registry:component",
          "target": "examples/age-form.tsx"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "feedback-form",
      "type": "registry:block",
      "title": "Feedback form",
      "description": "The feedback form example.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "@fieldkit/form",
        "@fieldkit/form-layout",
        "@fieldkit/form-submit",
        "@fieldkit/form-radio-group",
        "@fieldkit/form-select",
        "@fieldkit/form-textarea",
        "@fieldkit/form-file",
        "@fieldkit/form-switch",
        "@fieldkit/form-email"
      ],
      "files": [
        {
          "path": "src/examples/feedback-form.tsx",
          "type": "registry:component",
          "target": "examples/feedback-form.tsx"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "nps-form",
      "type": "registry:block",
      "title": "NPS survey",
      "description": "The nps survey example.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "@fieldkit/form",
        "@fieldkit/form-layout",
        "@fieldkit/form-submit",
        "@fieldkit/form-radio-group",
        "@fieldkit/form-textarea"
      ],
      "files": [
        {
          "path": "src/examples/nps-form.tsx",
          "type": "registry:component",
          "target": "examples/nps-form.tsx"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "bug-report-form",
      "type": "registry:block",
      "title": "Bug report",
      "description": "The bug report example.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "@fieldkit/form",
        "@fieldkit/form-layout",
        "@fieldkit/form-row",
        "@fieldkit/form-submit",
        "@fieldkit/form-text",
        "@fieldkit/form-radio-group",
        "@fieldkit/form-select",
        "@fieldkit/form-url",
        "@fieldkit/form-textarea",
        "@fieldkit/form-file"
      ],
      "files": [
        {
          "path": "src/examples/bug-report-form.tsx",
          "type": "registry:component",
          "target": "examples/bug-report-form.tsx"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "contact-form",
      "type": "registry:block",
      "title": "Contact form",
      "description": "The contact form example.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "@fieldkit/form",
        "@fieldkit/form-layout",
        "@fieldkit/form-submit",
        "@fieldkit/form-text",
        "@fieldkit/form-email",
        "@fieldkit/form-select",
        "@fieldkit/form-textarea",
        "@fieldkit/form-checkbox"
      ],
      "files": [
        {
          "path": "src/examples/contact-form.tsx",
          "type": "registry:component",
          "target": "examples/contact-form.tsx"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "job-application-form",
      "type": "registry:block",
      "title": "Job application",
      "description": "The job application example.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "@fieldkit/form",
        "@fieldkit/form-layout",
        "@fieldkit/form-row",
        "@fieldkit/form-submit",
        "@fieldkit/form-frame",
        "@fieldkit/form-text",
        "@fieldkit/form-email",
        "@fieldkit/form-phone",
        "@fieldkit/form-url",
        "@fieldkit/form-number",
        "@fieldkit/form-date",
        "@fieldkit/form-file",
        "@fieldkit/form-checkbox"
      ],
      "files": [
        {
          "path": "src/examples/job-application-form.tsx",
          "type": "registry:component",
          "target": "examples/job-application-form.tsx"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "registration-form",
      "type": "registry:block",
      "title": "Registration form",
      "description": "A compact builder with dynamic values and a live preview.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "@fieldkit/form",
        "@fieldkit/json-form",
        "@fieldkit/spec-builder",
        "@fieldkit/form-text",
        "@fieldkit/form-email",
        "@fieldkit/form-phone",
        "@fieldkit/form-select",
        "@fieldkit/form-radio-group",
        "@fieldkit/form-checkbox-group",
        "@fieldkit/form-textarea",
        "@fieldkit/form-checkbox"
      ],
      "files": [
        {
          "path": "src/examples/registration-builder.tsx",
          "type": "registry:component",
          "target": "examples/registration-builder.tsx"
        },
        {
          "path": "src/examples/registration-data.ts",
          "type": "registry:component",
          "target": "examples/registration-data.ts"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "registration-responses",
      "type": "registry:block",
      "title": "Responses",
      "description": "Read responses as a summary, cards, a table or a custom view.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "empty",
        "sheet",
        "@fieldkit/form",
        "@fieldkit/json-form",
        "@fieldkit/form-text",
        "@fieldkit/form-email",
        "@fieldkit/form-phone",
        "@fieldkit/form-select",
        "@fieldkit/form-radio-group",
        "@fieldkit/form-checkbox-group",
        "@fieldkit/form-textarea",
        "@fieldkit/form-checkbox"
      ],
      "files": [
        {
          "path": "src/examples/registration-responses.tsx",
          "type": "registry:component",
          "target": "examples/registration-responses.tsx"
        },
        {
          "path": "src/examples/registration-data.ts",
          "type": "registry:component",
          "target": "examples/registration-data.ts"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "registration-views",
      "type": "registry:block",
      "title": "Response views",
      "description": "Design your own layout for one response.",
      "dependencies": [
        "zod"
      ],
      "registryDependencies": [
        "field",
        "@fieldkit/form",
        "@fieldkit/json-form",
        "@fieldkit/spec-builder",
        "@fieldkit/view-designer",
        "@fieldkit/form-text",
        "@fieldkit/form-email",
        "@fieldkit/form-phone",
        "@fieldkit/form-select",
        "@fieldkit/form-radio-group",
        "@fieldkit/form-checkbox-group",
        "@fieldkit/form-textarea",
        "@fieldkit/form-checkbox"
      ],
      "files": [
        {
          "path": "src/examples/registration-views.tsx",
          "type": "registry:component",
          "target": "examples/registration-views.tsx"
        },
        {
          "path": "src/examples/registration-data.ts",
          "type": "registry:component",
          "target": "examples/registration-data.ts"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        }
      ]
    },
    {
      "name": "builder",
      "type": "registry:block",
      "title": "Form builder",
      "description": "Drag-and-drop form builder that writes the form code.",
      "dependencies": [
        "@dnd-kit/core",
        "@dnd-kit/sortable",
        "shiki",
        "@shikijs/langs",
        "motion",
        "lucide-react",
        "class-variance-authority"
      ],
      "registryDependencies": [
        "alert-dialog",
        "button",
        "card",
        "collapsible",
        "dialog",
        "empty",
        "field",
        "input",
        "input-group",
        "item",
        "scroll-area",
        "separator",
        "skeleton",
        "spinner",
        "switch",
        "tabs",
        "textarea",
        "toggle-group",
        "@fieldkit/form",
        "@fieldkit/form-frame",
        "@fieldkit/json-form",
        "@fieldkit/form-text",
        "@fieldkit/form-email",
        "@fieldkit/form-phone",
        "@fieldkit/form-password",
        "@fieldkit/form-url",
        "@fieldkit/form-textarea",
        "@fieldkit/form-rich-text",
        "@fieldkit/form-number",
        "@fieldkit/form-slider",
        "@fieldkit/form-date",
        "@fieldkit/form-date-time",
        "@fieldkit/form-date-range",
        "@fieldkit/form-select",
        "@fieldkit/form-country",
        "@fieldkit/form-multi-select",
        "@fieldkit/form-combobox",
        "@fieldkit/form-radio-group",
        "@fieldkit/form-checkbox-group",
        "@fieldkit/form-checkbox",
        "@fieldkit/form-switch",
        "@fieldkit/form-otp",
        "@fieldkit/form-file",
        "@fieldkit/form-rating"
      ],
      "files": [
        {
          "path": "src/components/builder/builder-state.ts",
          "type": "registry:component",
          "target": "components/builder/builder-state.ts"
        },
        {
          "path": "src/components/builder/builder.tsx",
          "type": "registry:component",
          "target": "components/builder/builder.tsx"
        },
        {
          "path": "src/components/builder/canvas-dialogs.tsx",
          "type": "registry:component",
          "target": "components/builder/canvas-dialogs.tsx"
        },
        {
          "path": "src/components/builder/canvas.tsx",
          "type": "registry:component",
          "target": "components/builder/canvas.tsx"
        },
        {
          "path": "src/components/builder/config-form.tsx",
          "type": "registry:component",
          "target": "components/builder/config-form.tsx"
        },
        {
          "path": "src/components/builder/example-templates.ts",
          "type": "registry:component",
          "target": "components/builder/example-templates.ts"
        },
        {
          "path": "src/components/builder/field-settings.tsx",
          "type": "registry:component",
          "target": "components/builder/field-settings.tsx"
        },
        {
          "path": "src/components/builder/field-types.ts",
          "type": "registry:component",
          "target": "components/builder/field-types.ts"
        },
        {
          "path": "src/components/builder/generate-code.ts",
          "type": "registry:component",
          "target": "components/builder/generate-code.ts"
        },
        {
          "path": "src/components/builder/palette.tsx",
          "type": "registry:component",
          "target": "components/builder/palette.tsx"
        },
        {
          "path": "src/components/builder/saved-forms.ts",
          "type": "registry:component",
          "target": "components/builder/saved-forms.ts"
        },
        {
          "path": "src/components/builder/spec-guide.ts",
          "type": "registry:component",
          "target": "components/builder/spec-guide.ts"
        },
        {
          "path": "src/components/builder/types.ts",
          "type": "registry:component",
          "target": "components/builder/types.ts"
        },
        {
          "path": "src/components/form/form-layout.tsx",
          "type": "registry:component",
          "target": "components/form/form-layout.tsx"
        },
        {
          "path": "src/components/form/form-row.tsx",
          "type": "registry:component",
          "target": "components/form/form-row.tsx"
        },
        {
          "path": "src/components/form/form-submit.tsx",
          "type": "registry:component",
          "target": "components/form/form-submit.tsx"
        },
        {
          "path": "src/components/ui/expandable-screen.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/loading-swap.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/code-block.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/code-snippet.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/components/ui/submitted-values.tsx",
          "type": "registry:ui"
        },
        {
          "path": "src/lib/highlighter.ts",
          "type": "registry:lib"
        },
        {
          "path": "src/lib/preview-links.ts",
          "type": "registry:lib"
        }
      ]
    }
  ]
}
