A frontmatter editor whose root holds the document and field setters for the consumer's composed fields.
Lowercase, dash-separated.
1
2
3'use client';
import { useState, type ReactNode } from 'react';Installation#
pnpm dlx shadcn@latest add https://ui.zeroxsolutions.com/r/frontmatter-form.jsonUsage#
import {
FrontmatterForm,
FrontmatterFormField,
FrontmatterFormFieldControl,
FrontmatterFormFieldError,
FrontmatterFormFieldLabel,
} from '@/components/data-entry/frontmatter-form';<FrontmatterForm value={value} onValueChange={setValue}>
<FrontmatterFormField name="name">
<FrontmatterFormFieldLabel>Name</FrontmatterFormFieldLabel>
<FrontmatterFormFieldControl render={<Input placeholder="my-skill" />} />
<FrontmatterFormFieldError />
</FrontmatterFormField>
</FrontmatterForm>The consumer composes one FrontmatterFormField per key and owns every label, hint (upstream
FieldDescription), control and validation rule - the component ships no rules of its own. Use it for a
frontmatter (YAML metadata) editor; bind a non-text control, such as a Switch, through
useFrontmatterFormField instead of FrontmatterFormFieldControl.
Composition#
FrontmatterForm
`-- FrontmatterFormField
|-- FrontmatterFormFieldLabel
|-- FrontmatterFormFieldControl
`-- FrontmatterFormFieldErrorInvalid fields#
Lowercase, dash-separated.
1
2
3'use client';
import { useState, type ReactNode } from 'react';API reference#
useFrontmatterFormField#
useFrontmatterFormField(): { name: string; value: unknown; setValue: (fieldValue: unknown) => void; error: string | undefined; controlId: string; errorId: string } - reads the current field's binding. Use it to bind a
control FrontmatterFormFieldControl does not cover (a Switch, a tag input). Throws outside a
FrontmatterFormField.
FrontmatterForm#
Renders shadcn's FieldGroup and takes every prop it takes
except onChange, plus:
| Prop | Type | Default |
|---|---|---|
value | FrontmatterFormValue | required |
onValueChange | (value: FrontmatterFormValue) => void | required |
errors | Record<string, string> | {} |
A frontmatter (YAML metadata) editor, an upstream FieldGroup of fields. The root holds the document and its
field setters in context; FrontmatterFormValue is an object of arbitrary keys, values usually strings. It
sets data-slot="frontmatter-form".
FrontmatterFormField#
Renders shadcn's Field and takes every prop it takes,
plus:
| Prop | Type | Default |
|---|---|---|
name | string | required |
One field of a FrontmatterForm, bound to name: an upstream Field that carries data-invalid while the
root's errors holds name. It sets data-slot="frontmatter-form-field". Shadcn's FieldLabel has one rule
naming the field slot, for a Field nested inside a label (the checkbox-row pattern); this family nests
the other way around, so that rule never reached this part.
FrontmatterFormFieldLabel#
Renders shadcn's FieldLabel and takes every prop it
takes. Label for the current field, pointed (htmlFor) at its control. It sets
data-slot="frontmatter-form-field-label" in place of FieldLabel's own, carrying the flex-auto rule
the label would otherwise lose when FrontmatterFormField's orientation is horizontal or responsive.
FrontmatterFormFieldControl#
Clones render with the current field's id, string value, data-slot and invalid-state attributes,
which replace its own; its own onChange still runs, before the field's:
| Prop | Type | Default |
|---|---|---|
render | ReactElement<FrontmatterFormFieldControlElementProps> | required |
render is the text control to bind, such as <Input placeholder="my-skill" /> or <Textarea />; it must
accept id, value, onChange, aria-invalid and aria-describedby, picked from an input's own props
(FrontmatterFormFieldControlElementProps), plus a data-slot the type adds on top of that pick. It renders
no element of its own, so the data-slot it sets (frontmatter-form-field-control) lands on render,
replacing whatever render set for itself. A render={<InputGroupInput />} loses InputGroupInput's own
input-group-control slot this way. For a non-text control use useFrontmatterFormField instead.
FrontmatterFormFieldError#
Renders shadcn's FieldError and takes every prop it
takes. The current field's message from the root's errors; renders nothing while the field is valid. It sets
data-slot="frontmatter-form-field-error".