diff --git a/docs/content/2.customization/1.config.md b/docs/content/2.customization/1.config.md index 854a5df..1775d84 100644 --- a/docs/content/2.customization/1.config.md +++ b/docs/content/2.customization/1.config.md @@ -143,6 +143,12 @@ This feature is in development! * @default true */ wFull?: boolean + /** + * Generate default labels from field names globally. Set to `false` to disable auto-generated labels. + * Manually set titles via `meta().title` will still render regardless of this setting. + * @default true + */ + enableDefaultTitles?: boolean } ``` diff --git a/docs/content/2.customization/2.fields.md b/docs/content/2.customization/2.fields.md index 2173bc2..c649d66 100644 --- a/docs/content/2.customization/2.fields.md +++ b/docs/content/2.customization/2.fields.md @@ -17,9 +17,10 @@ Fields below are used to customize the [FormField](https://ui.nuxt.com/component They map directly to properties inside `UFormField` Nuxt UI component. ::field-group - ::field{name="title" type="string"} + ::field{name="title" type="string | null"} Field label displayed in the form's label row. Maps directly to `UFormField.label`.\ - If not provided, it defaults to the field name with capitalization and spaces. + If not provided, it defaults to the field name with capitalization and spaces.\ + Set to `null` to hide the label for this specific field. :: ::field{name="required" type="string"} diff --git a/playground/app/components/MyForm.vue b/playground/app/components/MyForm.vue index 76a6774..3fd79a4 100644 --- a/playground/app/components/MyForm.vue +++ b/playground/app/components/MyForm.vue @@ -53,6 +53,9 @@ const schema = z.object({ multiple_input: z .array(z.enum(ENUM_MULTIPLE)) .meta({ title: 'Multiple Enum Input' }), + title_null_field: z.string() + .optional() + .meta({ title: null }), }) function onSubmit(data: Record) { diff --git a/playground/tests/e2e/basic.test.ts b/playground/tests/e2e/basic.test.ts index 5b4f545..e8aaa06 100644 --- a/playground/tests/e2e/basic.test.ts +++ b/playground/tests/e2e/basic.test.ts @@ -1,5 +1,11 @@ import { expect, test } from '@nuxt/test-utils/playwright' +test('title null field has no label', async ({ page }) => { + await page.goto('/', { waitUntil: 'networkidle' }) + + await expect(page.getByLabel('Title null field')).not.toBeVisible() +}) + test('test very basic form', async ({ page }) => { await page.goto('/', { waitUntil: 'networkidle' }) diff --git a/src/runtime/components/AutoFormPrimitive.vue b/src/runtime/components/AutoFormPrimitive.vue index f0a8432..5fa8a4e 100644 --- a/src/runtime/components/AutoFormPrimitive.vue +++ b/src/runtime/components/AutoFormPrimitive.vue @@ -81,7 +81,7 @@ const fields = computed(() => { formField: { name: key, slots: findSlots(key), - ...parseMeta(meta, key), + ...parseMeta(meta, key, appConfig.value), }, component: meta?.input?.component ?? result.component, props: defu(defaultProps, meta?.input?.props, result.componentProps ?? {}), @@ -97,9 +97,15 @@ function findSlots(key: string): string[] { .map(name => name.slice(key.length + 1)) } -function parseMeta(meta: any, key: string) { +function parseMeta(meta: any, key: string, config: AutoFormConfig) { + const enableDefaultTitles = config?.theme?.enableDefaultTitles !== false + const label = typeof meta.title === 'string' + ? meta.title + : meta.title === undefined && enableDefaultTitles + ? upperFirst(splitByCase(key).join(' ').toLowerCase()) + : undefined return { - label: meta.title ?? upperFirst(splitByCase(key).join(' ').toLowerCase()), + label, required: meta.required, description: meta.description, hint: meta.hint, diff --git a/src/runtime/types/index.d.ts b/src/runtime/types/index.d.ts index e1171f7..71a1da4 100644 --- a/src/runtime/types/index.d.ts +++ b/src/runtime/types/index.d.ts @@ -37,6 +37,12 @@ export interface AutoFormConfig { * @default true */ wFull?: boolean + /** + * Generate default labels from field names globally. Set to `false` to disable auto-generated labels. + * Manually set titles via `meta().title` will still render regardless of this setting. + * @default true + */ + enableDefaultTitles?: boolean } /** diff --git a/src/runtime/types/zod.d.ts b/src/runtime/types/zod.d.ts index 94bbc9b..43eaf27 100644 --- a/src/runtime/types/zod.d.ts +++ b/src/runtime/types/zod.d.ts @@ -36,12 +36,13 @@ declare module 'zod' { /** * Field label displayed in the form's label row. * Maps directly to `UFormField.label`. + * Set to `null` to hide the label for this field. * * @remarks Added by `nuxt-auto-form` * @default Field name in PascalCase with spaces * @see https://ui.nuxt.com/components/form-field#description */ - title?: string + title?: string | null /** * Marks the field as required in the UI (asterisk, aria-required).