Fieldset
A component that groups a legend, helper, and error text, ensuring accessibility.
import { OctagonAlertIcon } from 'lucide-react'
import { Field } from '~/components/ui/field'
import { Fieldset } from '~/components/ui/fieldset'
import { Icon } from '~/components/ui/icon'
import { Switch } from '~/components/ui/switch'
export const Demo = (props: Fieldset.RootProps) => {
return (
<Fieldset.Root {...props}>
<Fieldset.Legend>Notifiations</Fieldset.Legend>
<Fieldset.HelperText>Get notifcations when your are not online</Fieldset.HelperText>
<Fieldset.Control>
<Field.Root>
<Switch size="sm" defaultChecked>
Comments
</Switch>
<Field.HelperText>When someone posts a comment</Field.HelperText>
</Field.Root>
<Field.Root>
<Switch size="sm" defaultChecked>
Candidates
</Switch>
<Field.HelperText>When someone applies for a job</Field.HelperText>
</Field.Root>
</Fieldset.Control>
<Fieldset.ErrorText>
<Icon size="sm">
<OctagonAlertIcon />
</Icon>
Something went wrong
</Fieldset.ErrorText>
</Fieldset.Root>
)
}
Usage
import { Fieldset } from '~/components/ui/fieldset'
Examples
Invalid
Use the invalid
prop to indicate that the fieldset is invalid.
<Fieldset.Root invalid>
<Fieldset.Legend>Notifiations</Fieldset.Legend>
<Fieldset.HelperText>Get notifcations when your are not online</Fieldset.HelperText>
<Fieldset.Control>
<Field.Root>
<Switch size="sm">Comments</Switch>
<Field.HelperText>When someone posts a comment</Field.HelperText>
</Field.Root>
</Fieldset.Control>
<Fieldset.ErrorText>
<Icon size="sm">
<OctagonAlertIcon />
</Icon>
Something went wrong
</Fieldset.ErrorText>
</Fieldset.Root>
Installation
npx @park-ui/cli components add fieldset
1
Add Styled Primitive
Copy the code snippet below into ~/components/ui/styled/fieldset.tsx
'use client'
import type { Assign, PolymorphicProps } from '@ark-ui/react'
import { ark } from '@ark-ui/react/factory'
import { Fieldset } from '@ark-ui/react/fieldset'
import { type FieldsetVariantProps, fieldset } from 'styled-system/recipes'
import type { ComponentProps, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from './utils/create-style-context'
const { withProvider, withContext } = createStyleContext(fieldset)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
HTMLFieldSetElement,
Assign<Assign<HTMLStyledProps<'fieldset'>, Fieldset.RootProviderBaseProps>, FieldsetVariantProps>
>(Fieldset.Root, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
HTMLFieldSetElement,
Assign<Assign<HTMLStyledProps<'fieldset'>, Fieldset.RootBaseProps>, FieldsetVariantProps>
>(Fieldset.Root, 'root')
export const ErrorText = withContext<
HTMLSpanElement,
Assign<HTMLStyledProps<'span'>, Fieldset.ErrorTextBaseProps>
>(Fieldset.ErrorText, 'errorText')
export const HelperText = withContext<
HTMLSpanElement,
Assign<HTMLStyledProps<'span'>, Fieldset.HelperTextBaseProps>
>(Fieldset.HelperText, 'helperText')
export const Legend = withContext<
HTMLLegendElement,
Assign<HTMLStyledProps<'legend'>, Fieldset.LegendBaseProps>
>(Fieldset.Legend, 'legend')
export const Control = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, PolymorphicProps>
>(ark.div, 'control')
export { FieldsetContext as Context } from '@ark-ui/react/fieldset'
No snippet found
No snippet found
2
Add Re-Export
To improve the developer experience, re-export the styled primitives in~/components/ui/fieldset.tsx
.
export * as Fieldset from './styled/fieldset'
3
Integrate Recipe
If you're not using @park-ui/preset
, add the following recipe to yourpanda.config.ts
:
import { fieldsetAnatomy } from '@ark-ui/anatomy'
import { defineSlotRecipe } from '@pandacss/dev'
export const fieldset = defineSlotRecipe({
className: 'fieldset',
slots: [...fieldsetAnatomy.keys(), 'control'],
base: {
root: {
display: 'grid',
borderTopWidth: '1px',
py: '6',
columnGap: '8',
rowGap: '1.5',
gridTemplateAreas: {
base: `
"legend legend"
"helperText helperText"
"control control"
"errorText errorText"
`,
md: `
"legend control"
"helperText control"
"errorText errorText"`,
},
gridTemplateRows: 'auto 1fr',
gridTemplateColumns: '1fr auto',
width: 'full',
},
control: {
gridArea: 'control',
display: 'grid',
gap: '4',
},
legend: {
color: 'fg.default',
fontWeight: 'medium',
gridArea: 'legend',
textStyle: 'sm',
float: 'left',
'+ *': {
clear: 'both',
},
_disabled: {
color: 'fg.disabled',
},
},
helperText: {
color: 'fg.muted',
gridArea: 'helperText',
textStyle: 'sm',
_disabled: {
color: 'fg.disabled',
},
},
errorText: {
alignItems: 'center',
color: 'fg.error',
display: 'inline-flex',
gap: '2',
gridArea: 'errorText',
mt: '4',
textStyle: 'sm',
_disabled: {
color: 'fg.disabled',
},
},
},
})