Field
A component that groups a label, input, helper, and error text, ensuring accessibility.
import { Field } from '~/components/ui/field'
export const Demo = (props: Field.RootProps) => {
return (
<Field.Root {...props}>
<Field.Label>Label</Field.Label>
<Field.Input placeholder="Placeholder" />
<Field.HelperText>Some additional Info</Field.HelperText>
</Field.Root>
)
}
import { Field } from '~/components/ui/field'
export const Demo = (props: Field.RootProps) => {
return (
<Field.Root {...props}>
<Field.Label>Label</Field.Label>
<Field.Input placeholder="Placeholder" />
<Field.HelperText>Some additional Info</Field.HelperText>
</Field.Root>
)
}
Usage
import { Field } from '~/components/ui/field'
Examples
Invalid
Use the invalid
prop to indicate that the field is invalid.
Please enter a valid email address
<Field.Root invalid>
<Field.Label>Email</Field.Label>
<Field.Input asChild>
<Input type="email" />
</Field.Input>
<Field.ErrorText>Please enter a valid email address</Field.ErrorText>
</Field.Root>
Disabled
Use the disabled
prop to disable the field.
<Field.Root disabled>
<Field.Label>Label</Field.Label>
<Field.Input asChild>
<Input type="email" />
</Field.Input>
</Field.Root>
Textarea
You can use the Field.Textarea
component to render a textarea.
Tell us about yourself
<Field.Root>
<Field.Label>Description</Field.Label>
<Field.Textarea asChild>
<Textarea />
</Field.Input>
<Field.HelperText>Tell us about yourself</Field.HelperText>
</Field.Root>
Installation
npx @park-ui/cli components add field
1
Add Styled Primitive
Copy the code snippet below into ~/components/ui/styled/field.tsx
'use client'
import type { Assign } from '@ark-ui/react'
import { Field } from '@ark-ui/react/field'
import { styled } from 'styled-system/jsx'
import { type FieldVariantProps, field, input, textarea } from 'styled-system/recipes'
import type { ComponentProps, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from './utils/create-style-context'
const { withProvider, withContext } = createStyleContext(field)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, Field.RootProviderBaseProps>, FieldVariantProps>
>(Field.RootProvider, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, Field.RootBaseProps>, FieldVariantProps>
>(Field.Root, 'root')
export const ErrorText = withContext<
HTMLSpanElement,
Assign<HTMLStyledProps<'span'>, Field.ErrorTextBaseProps>
>(Field.ErrorText, 'errorText')
export const HelperText = withContext<
HTMLSpanElement,
Assign<HTMLStyledProps<'span'>, Field.HelperTextBaseProps>
>(Field.HelperText, 'helperText')
export const Label = withContext<
HTMLLabelElement,
Assign<HTMLStyledProps<'label'>, Field.LabelBaseProps>
>(Field.Label, 'label')
export const Select = withContext<
HTMLSelectElement,
Assign<HTMLStyledProps<'select'>, Field.SelectBaseProps>
>(Field.Select, 'select')
export type InputProps = ComponentProps<typeof Input>
export const Input = styled(Field.Input, input)
export type TextareaProps = ComponentProps<typeof Textarea>
export const Textarea = styled(Field.Textarea, textarea)
export { FieldContext as Context } from '@ark-ui/react/field'
import { type Assign, Field } from '@ark-ui/solid'
import type { ComponentProps } from 'solid-js'
import { styled } from 'styled-system/jsx'
import { type FieldVariantProps, field, input, textarea } from 'styled-system/recipes'
import type { HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from './utils/create-style-context'
const { withProvider, withContext } = createStyleContext(field)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
Assign<Assign<HTMLStyledProps<'div'>, Field.RootProviderBaseProps>, FieldVariantProps>
>(Field.RootProvider, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
Assign<Assign<HTMLStyledProps<'div'>, Field.RootBaseProps>, FieldVariantProps>
>(Field.Root, 'root')
export const ErrorText = withContext<Assign<HTMLStyledProps<'span'>, Field.ErrorTextBaseProps>>(
Field.ErrorText,
'errorText',
)
export const HelperText = withContext<Assign<HTMLStyledProps<'span'>, Field.HelperTextBaseProps>>(
Field.HelperText,
'helperText',
)
export const Label = withContext<Assign<HTMLStyledProps<'label'>, Field.LabelBaseProps>>(
Field.Label,
'label',
)
export const Select = withContext<Assign<HTMLStyledProps<'select'>, Field.SelectBaseProps>>(
Field.Select,
'select',
)
export type InputProps = ComponentProps<typeof Input>
export const Input = styled(Field.Input, input)
export type TextareaProps = ComponentProps<typeof Textarea>
export const Textarea = styled(Field.Textarea, textarea)
export { FieldContext as Context } from '@ark-ui/solid'
No snippet found
2
Add Re-Export
To improve the developer experience, re-export the styled primitives in~/components/ui/field.tsx
.
export * as Field from './styled/field'
export * as Field from './styled/field'
3
Integrate Recipe
If you're not using @park-ui/preset
, add the following recipe to yourpanda.config.ts
:
import { fieldAnatomy } from '@ark-ui/anatomy'
import { defineSlotRecipe } from '@pandacss/dev'
export const field = defineSlotRecipe({
className: 'field',
slots: fieldAnatomy.keys(),
base: {
root: {
display: 'flex',
flexDirection: 'column',
gap: '1.5',
},
label: {
color: 'fg.default',
fontWeight: 'medium',
textStyle: 'sm',
_disabled: {
color: 'fg.disabled',
},
},
helperText: {
color: 'fg.muted',
textStyle: 'sm',
_disabled: {
color: 'fg.disabled',
},
},
errorText: {
alignItems: 'center',
color: 'fg.error',
display: 'inline-flex',
gap: '2',
textStyle: 'sm',
_disabled: {
color: 'fg.disabled',
},
},
},
})