@sanity/form-toolkit

3.0.63.0.7
dist/form-schema/index.js.map
~dist/form-schema/index.js.mapModified
+1−1
Index: package/dist/form-schema/index.js.map
===================================================================
--- package/dist/form-schema/index.js.map
+++ package/dist/form-schema/index.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.js","names":["FaWpforms","defineField","defineType","SchemaTypeDefinition","FieldsOption","formType","fields","name","title","type","icon","description","validation","Rule","required","options","source","of","initialValue","StringInputProps","useFormValue","FormField","validationTypesByFieldType","ValidationType","props","$","_c","t0","path","slice","type","schemaType","options","t1","renderDefault","t2","list","LuTextCursorInput","defineField","defineType","ValidationType","ValidationContextDocument","fields","Array","name","type","validationTypesByFieldType","Record","fieldTypeTitle","fieldType","charAt","toUpperCase","slice","formFieldType","title","icon","options","list","Object","keys","map","value","description","validation","Rule","required","custom","context","test","doc","document","allFieldNames","field","nameCount","filter","n","length","reservedNames","includes","toLowerCase","initialValue","hidden","parent","validationTypes","of","components","input","preview","select","subtitle","label","prepare","SchemaTypeDefinition","FieldsOption","formType","formFieldType","schema","fields","types","definePlugin","FieldDefinition","schema","FieldsOption","Array","FormSchemaPluginOptions","fields","formSchema","options","name"],"sources":["../../src/form-schema/schema-types/form.ts","../../src/form-schema/components/validation-type.tsx","../../src/form-schema/schema-types/form-field.ts","../../src/form-schema/schema-types/index.ts","../../src/form-schema/index.ts"],"sourcesContent":["import {FaWpforms} from 'react-icons/fa'\nimport {defineField, defineType, type SchemaTypeDefinition} from 'sanity'\n\nimport type {FieldsOption} from '..'\n\nexport const formType = (fields: FieldsOption): SchemaTypeDefinition => {\n  // const fieldsOf =\n  //   fields && fields.length ? [{type: 'formField'}, ...fields] : [{type: 'formField'}]\n  return defineType({\n    name: 'form',\n    title: 'Form',\n    type: 'document',\n    icon: FaWpforms,\n    fields: [\n      defineField({\n        name: 'title',\n        title: 'Form Title',\n        type: 'string',\n        description: 'Internal title for the form',\n        validation: (Rule) => Rule.required(),\n      }),\n      defineField({\n        name: 'id',\n        title: 'Form ID',\n        type: 'slug',\n        options: {\n          source: 'title',\n        },\n        // validation: (Rule) => Rule.required(),\n      }),\n      defineField({\n        name: 'fields',\n        title: 'Form Fields',\n        type: 'array',\n        of: [{type: 'formField'}, ...fields],\n      }),\n      defineField({\n        name: 'submitButton',\n        title: 'Submit Button',\n        type: 'object',\n        fields: [\n          defineField({\n            name: 'text',\n            title: 'Button Text',\n            type: 'string',\n            initialValue: 'Submit',\n          }),\n        ],\n      }),\n    ],\n  })\n}\n","import type {StringInputProps} from 'sanity'\nimport {useFormValue} from 'sanity'\n\nimport type {FormField} from '../../form-renderer/components/types'\nimport {validationTypesByFieldType} from '../schema-types/form-field'\n\nexport const ValidationType = (props: StringInputProps) => {\n  // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- parent value shape is defined by the formField schema type\n  const {type} = useFormValue(props.path.slice(0, 2)) as FormField\n  if (!type || !props.schemaType?.options) return props.renderDefault(props)\n  return props.renderDefault({\n    ...props,\n    schemaType: {\n      ...props.schemaType,\n      options: {...props.schemaType.options, list: validationTypesByFieldType[type]},\n    },\n  })\n}\n","import {LuTextCursorInput} from 'react-icons/lu'\nimport {defineField, defineType} from 'sanity'\n\nimport {ValidationType} from '../components/validation-type'\ninterface ValidationContextDocument {\n  fields?: Array<{\n    name: string\n    type?: string\n  }>\n}\n\n// Validation options by field type\nexport const validationTypesByFieldType: Record<string, string[]> = {\n  'checkbox': ['minSelectedCount', 'maxSelectedCount'],\n  'color': [],\n  'date': ['minDate', 'maxDate'],\n  'datetime-local': ['minDate', 'maxDate'],\n  'email': ['pattern'],\n  'file': ['maxSize', 'fileType'],\n  'hidden': [],\n  'number': ['min', 'max'],\n  // password: ['minLength', 'pattern'],\n  'radio': [],\n  'range': ['min', 'max', 'step'],\n  'select': [],\n  'tel': ['pattern'],\n  'text': ['minLength', 'maxLength', 'pattern'],\n  'textarea': ['minLength', 'maxLength'],\n  'time': [],\n  'url': ['pattern'],\n}\nconst fieldTypeTitle = (fieldType: string): string => {\n  switch (fieldType) {\n    case 'datetime-local':\n      return 'Date & Time'\n    case 'textarea':\n      return 'Text Area'\n    case 'tel':\n      return 'Phone Number'\n    default:\n      return fieldType.charAt(0).toUpperCase() + fieldType.slice(1)\n  }\n}\n\nexport const formFieldType = defineType({\n  name: 'formField',\n  title: 'Form Field',\n  type: 'object',\n  icon: LuTextCursorInput,\n  fields: [\n    defineField({\n      name: 'type',\n      title: 'Field Type',\n      type: 'string',\n      options: {\n        list: Object.keys(validationTypesByFieldType).map((type) => {\n          return {title: fieldTypeTitle(type), value: type}\n        }),\n      },\n    }),\n    defineField({\n      name: 'label',\n      title: 'Field Label',\n      type: 'string',\n    }),\n    defineField({\n      name: 'name',\n      title: 'Field Name',\n      type: 'string',\n      description:\n        'Must start with a letter and contain only letters, numbers, underscores, or hyphens. Must be unique within the form.',\n      validation: (Rule) =>\n        Rule.required().custom((name, context) => {\n          if (!name) {\n            return 'Required'\n          }\n          // Check format (HTML ID/name rules)\n          if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)) {\n            return 'Field name must start with a letter and contain only letters, numbers, underscores, or hyphens'\n          }\n\n          // Check uniqueness across all fields\n          // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- document shape is defined by the form schema type\n          const doc = context.document as ValidationContextDocument\n          const allFieldNames = doc?.fields?.map((field) => field.name) || []\n\n          // Count occurrences of this name\n          const nameCount = allFieldNames.filter((n) => n === name).length\n\n          // If we find more than one occurrence (including current field), it's not unique\n          if (nameCount > 1) {\n            return 'Field name must be unique across all form fields'\n          }\n\n          // Check for reserved HTML form attributes\n          const reservedNames = [\n            'action',\n            'method',\n            'target',\n            'enctype',\n            'accept-charset',\n            'autocomplete',\n            'novalidate',\n            'rel',\n            'submit',\n            'reset',\n          ]\n          if (reservedNames.includes(name.toLowerCase())) {\n            return 'This name is reserved for HTML form attributes. Please choose a different name.'\n          }\n\n          return true\n        }),\n    }),\n    defineField({\n      name: 'required',\n      title: 'Required',\n      type: 'boolean',\n      initialValue: false,\n    }),\n    defineField({\n      name: 'validation',\n      title: 'Validation Rules',\n      type: 'array',\n      hidden: ({parent}) => {\n        if (!parent?.type) return true\n        const validationTypes = validationTypesByFieldType[parent.type]\n        return !validationTypes || validationTypes.length === 0\n      },\n      of: [\n        {\n          type: 'object',\n          fields: [\n            defineField({\n              name: 'type',\n              title: 'Validation Type',\n              type: 'string',\n              options: {\n                // TODO: I think this needs to be a custom input component?\n                // list: ({parent}) => (parent?.type ? validationTypesByFieldType[parent.type] : []),\n                list: [],\n              },\n              components: {\n                input: ValidationType,\n              },\n            }),\n            defineField({\n              name: 'value',\n              title: 'Value',\n              type: 'string',\n            }),\n            defineField({\n              name: 'message',\n              title: 'Error Message',\n              type: 'string',\n            }),\n          ],\n          preview: {\n            select: {\n              title: 'type',\n              subtitle: 'value',\n            },\n          },\n        },\n      ],\n    }),\n    defineField({\n      name: 'choices',\n      title: 'Choices',\n      type: 'array',\n      hidden: ({parent}) => {\n        return !['select', 'radio', 'checkbox'].includes(parent?.type)\n      },\n      of: [\n        {\n          type: 'object',\n          fields: [\n            defineField({\n              name: 'label',\n              title: 'Label',\n              type: 'string',\n            }),\n            defineField({\n              name: 'value',\n              title: 'Value',\n              type: 'string',\n            }),\n          ],\n        },\n      ],\n    }),\n    defineField({\n      name: 'options',\n      title: 'Field Options',\n      type: 'object',\n      hidden: ({parent}) => {\n        return ['select', 'radio', 'checkbox', 'file'].includes(parent?.type)\n      },\n      fields: [\n        defineField({\n          name: 'placeholder',\n          title: 'Placeholder',\n          type: 'string',\n        }),\n        defineField({\n          name: 'defaultValue',\n          title: 'Default Value',\n          type: 'string',\n        }),\n      ],\n    }),\n  ],\n  preview: {\n    select: {\n      label: 'label',\n      name: 'name',\n      type: 'type',\n    },\n    prepare({label, name, type}) {\n      return {\n        title: label || name,\n        subtitle: type,\n      }\n    },\n  },\n})\n","import type {SchemaTypeDefinition} from 'sanity'\n\nimport type {FieldsOption} from '..'\nimport {formType} from './form'\nimport {formFieldType} from './form-field'\n\nexport const schema = (fields: FieldsOption): {types: SchemaTypeDefinition[]} => {\n  return {types: [formType(fields), formFieldType]}\n}\n","import {definePlugin, type FieldDefinition} from 'sanity'\n\n// import {structureTool} from 'sanity/structure'\n// import {FormRenderer} from './components/form-renderer'\nimport {schema} from './schema-types'\n// import {defaultDocumentNode} from './structure'\n\n/**\n * Usage in `sanity.config.ts` (or .js)\n *\n * ```ts\n * import {defineConfig} from 'sanity'\n * import {formSchema} from '@sanity/form-toolkit'\n *\n * export default defineConfig({\n *   // ...\n *   plugins: [formSchema()],\n * })\n * ```\n */\nexport type FieldsOption = Array<FieldDefinition>\ninterface FormSchemaPluginOptions {\n  /**\n   * Array of field definitions to be used in the form schema.\n   */\n  fields?: FieldsOption\n}\n\nexport const formSchema = definePlugin<FormSchemaPluginOptions | void>((options) => {\n  return {\n    name: 'form-toolkit_form-schema',\n    schema: schema(options?.fields ?? []),\n    // plugins: [structureTool({defaultDocumentNode})],\n  }\n})\n"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"index.js","names":["FaWpforms","defineField","defineType","SchemaTypeDefinition","FieldsOption","formType","fields","name","title","type","icon","description","validation","Rule","required","options","source","of","initialValue","StringInputProps","useFormValue","FormField","validationTypesByFieldType","ValidationType","props","$","_c","t0","path","slice","type","schemaType","options","t1","renderDefault","t2","list","LuTextCursorInput","defineField","defineType","ValidationType","ValidationContextDocument","fields","Array","name","type","validationTypesByFieldType","Record","fieldTypeTitle","fieldType","charAt","toUpperCase","slice","formFieldType","title","icon","options","list","Object","keys","map","value","description","validation","Rule","required","custom","context","test","doc","document","allFieldNames","field","nameCount","filter","n","length","reservedNames","includes","toLowerCase","initialValue","hidden","parent","validationTypes","of","components","input","preview","select","subtitle","label","prepare","SchemaTypeDefinition","FieldsOption","formType","formFieldType","schema","fields","types","definePlugin","FieldDefinition","schema","FieldsOption","Array","FormSchemaPluginOptions","fields","formSchema","options","name"],"sources":["../../src/form-schema/schema-types/form.ts","../../src/form-schema/components/validation-type.tsx","../../src/form-schema/schema-types/form-field.ts","../../src/form-schema/schema-types/index.ts","../../src/form-schema/index.ts"],"sourcesContent":["import {FaWpforms} from 'react-icons/fa'\nimport {defineField, defineType, type SchemaTypeDefinition} from 'sanity'\n\nimport type {FieldsOption} from '..'\n\nexport const formType = (fields: FieldsOption): SchemaTypeDefinition => {\n  // const fieldsOf =\n  //   fields && fields.length ? [{type: 'formField'}, ...fields] : [{type: 'formField'}]\n  return defineType({\n    name: 'form',\n    title: 'Form',\n    type: 'document',\n    icon: FaWpforms,\n    fields: [\n      defineField({\n        name: 'title',\n        title: 'Form Title',\n        type: 'string',\n        description: 'Internal title for the form',\n        validation: (Rule) => Rule.required(),\n      }),\n      defineField({\n        name: 'id',\n        title: 'Form ID',\n        type: 'slug',\n        options: {\n          source: 'title',\n        },\n        // validation: (Rule) => Rule.required(),\n      }),\n      defineField({\n        name: 'fields',\n        title: 'Form Fields',\n        type: 'array',\n        of: [{type: 'formField'}, ...fields],\n      }),\n      defineField({\n        name: 'submitButton',\n        title: 'Submit Button',\n        type: 'object',\n        fields: [\n          defineField({\n            name: 'text',\n            title: 'Button Text',\n            type: 'string',\n            initialValue: 'Submit',\n          }),\n        ],\n      }),\n    ],\n  })\n}\n","import type {StringInputProps} from 'sanity'\nimport {useFormValue} from 'sanity'\n\nimport type {FormField} from '../../form-renderer/components/types'\nimport {validationTypesByFieldType} from '../schema-types/form-field'\n\nexport const ValidationType = (props: StringInputProps) => {\n  // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- parent value shape is defined by the formField schema type\n  const {type} = useFormValue(props.path.slice(0, 2)) as FormField\n  if (!type || !props.schemaType?.options) return props.renderDefault(props)\n  return props.renderDefault({\n    ...props,\n    schemaType: {\n      ...props.schemaType,\n      options: {...props.schemaType.options, list: validationTypesByFieldType[type]},\n    },\n  })\n}\n","import {LuTextCursorInput} from 'react-icons/lu'\nimport {defineField, defineType} from 'sanity'\n\nimport {ValidationType} from '../components/validation-type'\ninterface ValidationContextDocument {\n  fields?: Array<{\n    name: string\n    type?: string\n  }>\n}\n\n// Validation options by field type\nexport const validationTypesByFieldType: Record<string, string[]> = {\n  'checkbox': ['minSelectedCount', 'maxSelectedCount'],\n  'color': [],\n  'date': ['minDate', 'maxDate'],\n  'datetime-local': ['minDate', 'maxDate'],\n  'email': ['pattern'],\n  'file': ['maxSize', 'fileType'],\n  'hidden': [],\n  'number': ['min', 'max'],\n  // password: ['minLength', 'pattern'],\n  'radio': [],\n  'range': ['min', 'max', 'step'],\n  'select': [],\n  'tel': ['pattern'],\n  'text': ['minLength', 'maxLength', 'pattern'],\n  'textarea': ['minLength', 'maxLength'],\n  'time': [],\n  'url': ['pattern'],\n}\nconst fieldTypeTitle = (fieldType: string): string => {\n  switch (fieldType) {\n    case 'datetime-local':\n      return 'Date & Time'\n    case 'textarea':\n      return 'Text Area'\n    case 'tel':\n      return 'Phone Number'\n    default:\n      return fieldType.charAt(0).toUpperCase() + fieldType.slice(1)\n  }\n}\n\nexport const formFieldType = defineType({\n  name: 'formField',\n  title: 'Form Field',\n  type: 'object',\n  icon: LuTextCursorInput,\n  fields: [\n    defineField({\n      name: 'type',\n      title: 'Field Type',\n      type: 'string',\n      options: {\n        list: Object.keys(validationTypesByFieldType).map((type) => {\n          return {title: fieldTypeTitle(type), value: type}\n        }),\n      },\n    }),\n    defineField({\n      name: 'label',\n      title: 'Field Label',\n      type: 'string',\n    }),\n    defineField({\n      name: 'name',\n      title: 'Field Name',\n      type: 'string',\n      description:\n        'Must start with a letter and contain only letters, numbers, underscores, or hyphens. Must be unique within the form.',\n      validation: (Rule) =>\n        Rule.required().custom((name, context) => {\n          if (!name) {\n            return 'Required'\n          }\n          // Check format (HTML ID/name rules)\n          if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)) {\n            return 'Field name must start with a letter and contain only letters, numbers, underscores, or hyphens'\n          }\n\n          // Check uniqueness across all fields\n          // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- document shape is defined by the form schema type\n          const doc = context.document as ValidationContextDocument\n          const allFieldNames = doc?.fields?.map((field) => field.name) || []\n\n          // Count occurrences of this name\n          const nameCount = allFieldNames.filter((n) => n === name).length\n\n          // If we find more than one occurrence (including current field), it's not unique\n          if (nameCount > 1) {\n            return 'Field name must be unique across all form fields'\n          }\n\n          // Check for reserved HTML form attributes\n          const reservedNames = [\n            'action',\n            'method',\n            'target',\n            'enctype',\n            'accept-charset',\n            'autocomplete',\n            'novalidate',\n            'rel',\n            'submit',\n            'reset',\n          ]\n          if (reservedNames.includes(name.toLowerCase())) {\n            return 'This name is reserved for HTML form attributes. Please choose a different name.'\n          }\n\n          return true\n        }),\n    }),\n    defineField({\n      name: 'required',\n      title: 'Required',\n      type: 'boolean',\n      initialValue: false,\n    }),\n    defineField({\n      name: 'validation',\n      title: 'Validation Rules',\n      type: 'array',\n      hidden: ({parent}) => {\n        if (!parent?.type) return true\n        const validationTypes = validationTypesByFieldType[parent.type]\n        return !validationTypes || validationTypes.length === 0\n      },\n      of: [\n        {\n          type: 'object',\n          fields: [\n            defineField({\n              name: 'type',\n              title: 'Validation Type',\n              type: 'string',\n              options: {\n                // TODO: I think this needs to be a custom input component?\n                // list: ({parent}) => (parent?.type ? validationTypesByFieldType[parent.type] : []),\n                list: [],\n              },\n              components: {\n                input: ValidationType,\n              },\n            }),\n            defineField({\n              name: 'value',\n              title: 'Value',\n              type: 'string',\n            }),\n            defineField({\n              name: 'message',\n              title: 'Error Message',\n              type: 'string',\n            }),\n          ],\n          preview: {\n            select: {\n              title: 'type',\n              subtitle: 'value',\n            },\n          },\n        },\n      ],\n    }),\n    defineField({\n      name: 'choices',\n      title: 'Choices',\n      type: 'array',\n      hidden: ({parent}) => {\n        return !['select', 'radio', 'checkbox'].includes(parent?.type)\n      },\n      of: [\n        {\n          type: 'object',\n          fields: [\n            defineField({\n              name: 'label',\n              title: 'Label',\n              type: 'string',\n            }),\n            defineField({\n              name: 'value',\n              title: 'Value',\n              type: 'string',\n            }),\n          ],\n        },\n      ],\n    }),\n    defineField({\n      name: 'options',\n      title: 'Field Options',\n      type: 'object',\n      hidden: ({parent}) => {\n        return ['select', 'radio', 'checkbox', 'file'].includes(parent?.type)\n      },\n      fields: [\n        defineField({\n          name: 'placeholder',\n          title: 'Placeholder',\n          type: 'string',\n        }),\n        defineField({\n          name: 'defaultValue',\n          title: 'Default Value',\n          type: 'string',\n        }),\n      ],\n    }),\n  ],\n  preview: {\n    select: {\n      label: 'label',\n      name: 'name',\n      type: 'type',\n    },\n    prepare({label, name, type}) {\n      return {\n        title: label || name,\n        subtitle: type,\n      }\n    },\n  },\n})\n","import type {SchemaTypeDefinition} from 'sanity'\n\nimport type {FieldsOption} from '..'\nimport {formType} from './form'\nimport {formFieldType} from './form-field'\n\nexport const schema = (fields: FieldsOption): {types: SchemaTypeDefinition[]} => {\n  return {types: [formType(fields), formFieldType]}\n}\n","import {definePlugin, type FieldDefinition} from 'sanity'\n\n// import {structureTool} from 'sanity/structure'\n// import {FormRenderer} from './components/form-renderer'\nimport {schema} from './schema-types'\n// import {defaultDocumentNode} from './structure'\n\n/**\n * Usage in `sanity.config.ts` (or .js)\n *\n * ```ts\n * import {defineConfig} from 'sanity'\n * import {formSchema} from '@sanity/form-toolkit'\n *\n * export default defineConfig({\n *   // ...\n *   plugins: [formSchema()],\n * })\n * ```\n */\nexport type FieldsOption = Array<FieldDefinition>\ninterface FormSchemaPluginOptions {\n  /**\n   * Array of field definitions to be used in the form schema.\n   */\n  fields?: FieldsOption\n}\n\nexport const formSchema = definePlugin<FormSchemaPluginOptions | void>((options) => {\n  return {\n    name: 'form-toolkit_form-schema',\n    schema: schema(options?.fields ?? []),\n    // plugins: [structureTool({defaultDocumentNode})],\n  }\n})\n"],"mappings":"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"}
\ No newline at end of file