Field

The form input primitive. Extends Text with theme-driven variants and sizes for inputs, textareas, and selects.

Field extends Text, so it accepts every Text and Box prop. It renders an input by default and adds a variant prop mapped to theme.skins.field and a $size prop mapped to theme.skins.field.sizes. Use it for text inputs, textareas, selects, checkboxes and range sliders.

Import#

typescript
import { Field } from "@reactberry/system/elements";

Usage#

typescript
import { useState } from "react";
import { Box, Field, Text } from "@reactberry/system/elements";

export default function EmailInput() {
  const [email, setEmail] = useState("");

  return (
    <Box display="flex" flexDirection="column" gap="xs">
      <Text as="label" htmlFor="email" fontSize="s" fontWeight="500">
        Email
      </Text>
      <Field id="email" type="email" required value={email} onChange={(event) => setEmail(event.target.value)} width="100%" />
    </Box>
  );
}

Examples#

Select and textarea#

Pass as="select" or as="textarea". Selects get a chevron and right padding.

Sizes#

$size picks a size from theme.skins.field.sizes.

Range and checkbox#

type="range" gets a custom track and thumb. Checkboxes and radios have no transition or hover shadow; pass $size="" to drop the size padding.

API#

Field#

PropTypeDefaultDescription
as
"input" | "textarea" | "select" | ElementType
"input"

Element or component to render.

variant
string
"default"

Dot path into theme.skins.field. Not passed to the DOM.

$size
string
"medium"

Dot path into theme.skins.field.sizes. Pass "" to opt out of size styles.

shape
string
"rounded"

Key in theme.shapes. Not passed to the DOM.

type
string
"text"

Input type. "range", "checkbox" and "radio" get extra styles.

placeholder
string
""

Placeholder text.

autoComplete
string
—

Native autocomplete hint.

disabled
boolean
—

Sets opacity: 0.5 and pointer-events: none, and is passed to the native element.

Field also accepts every Text and Box prop, plus native attributes such as value, onChange, name and required. Defaults are applied before your props, so any of them can be overridden; display="inline-flex" is also set. A 0.2s ease transition is applied, except on checkboxes and radios.

Element-specific styling:

  • as="select" — removes native appearance and adds a chevron background with right padding
  • type="range" — custom track and thumb using theme.colors.primary, full width, no border or padding
  • type="checkbox" or type="radio" — disables the transition and hover shadow to avoid flicker

Variant reference#

Variants resolve by dot path. The default light theme defines:

  • default — bordered, base background, brand border on focus
  • primary — tinted brand background with a thicker border
  • ghost — no border, background, or radius; with ghost.dark
  • outline — surface background with border; with outline.required, outline.prefilled
  • underline — dashed bottom border only; with underline.required, underline.prefilled
  • select — surface background tuned for selects
  • checked — for checkbox and radio inputs

The dark theme defines default, primary, subtle, ghost, outline, underline, and checked.

ghost, outline, and underline style invalid values through the :user-invalid and :invalid:not(:placeholder-shown) pseudo-classes, so native validation attributes (required, pattern, type="email") drive the error state.

Size reference#

All sizes use font-weight: 400.

  • xsmall — height 2rem, font 0.875rem; xsmall.select uses height 1.75rem
  • small — height 2.25rem, font 1rem
  • medium — no fixed height, padding 0.5rem 0.75rem, font 1rem
  • large — no fixed height, padding 0.5rem 0.75rem, font 1.125rem

In the light theme, small, medium, and large also have a .prefix entry (for example medium.prefix) with extra left padding for a leading icon.

Accessibility#

  • Field renders a native input, textarea or select, so keyboard and form behaviour come from the browser.
  • There is no built-in label. Pair it with <Text as="label" htmlFor={id}> or pass aria-label.
  • The range thumb shows a 3px outline when focused.

Notes#

  • There is no invalid or error prop. Use native validation, or pass aria-invalid and adjust variant or borderColor yourself.
  • Field is not full width by default. Pass width="100%" where needed.
  • For labelled fields with descriptions and errors, see the FieldSet block.