# Field

- Page: https://jiguang132.com/resources/astryx/docs/field
- Resource: Astryx (https://jiguang132.com/resources/astryx.md)
- All guides: https://jiguang132.com/resources/astryx/docs.md

Field is a low-level wrapper for custom, native, or third-party controls that do not already provide field label, description, and status UI. Use it when you need the Field shell around a control you own; use styled Astryx inputs like TextInput, Typeahead, and Select directly when they already expose label, description, and validation props.

## Installation

```bash
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0
```

Requires React 19+, base CSS and a Theme provider. See [Setup](/resources/astryx/docs/getting-started).

## Field

Field is a low-level wrapper for custom, native, or third-party controls that do not already provide field label, description, and status UI. Use it when you need the Field shell around a control you own; use styled Astryx inputs like TextInput, Typeahead, and Select directly when they already expose label, description, and validation props.

| Prop | Type | Default | Description |
|---|---|---|---|
| label * | string |  | Label text for the field (always rendered for accessibility). |
| inputID * | string |  | ID for the input element (used for the label htmlFor attribute). |
| labelID | string |  | ID applied to the label element itself for group accessibility. |
| isGroupLabel | boolean | false | Renders the label as a span for control groups (radiogroup, checkbox list). |
| children * | ReactNode |  | The input or control to render. |
| isLabelHidden | boolean | false | Visually hide the label (still accessible to screen readers). |
| isDisabled | boolean | false | Whether the associated input is disabled. Propagates disabled styling to the label. |
| description | string |  | Description text displayed between the label and input. |
| descriptionID | string |  | ID for the description element (use for aria-describedby on the input). |
| isOptional | boolean | false | Whether the field is optional (mutually exclusive with isRequired). |
| isRequired | boolean | false | Whether the field is required (mutually exclusive with isOptional). |
| labelIcon | IconType |  | Icon to display before the label text. See `astryx docs icons` for valid semantic names. |
| labelTooltip | string |  | Tooltip text to display in an info icon at the end of the label. |
| status | {type: 'warning' \| 'error' \| 'success', message?: string, messageID?: string} |  | Status indicator with type and optional message. When message is set, displays a colored status box. messageID is for wiring aria-describedby on the input. |
| statusVariant | 'attached' \| 'detached' | 'attached' | How the status message renders relative to the input. Attached overlaps the input border; detached floats below. |
| width | SizeValue |  | Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned. Prefer this over setting width via xstyle/className/style, which only size the inner control box. Without a width, a row can shrink the whole field below the natural width of its control, so filter bars shrink instead of overflowing. |
| ref | React.Ref<HTMLDivElement> |  | Ref forwarded to the root element. |
| xstyle | StyleXStyles |  | StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}. |
| className | string |  | CSS class name(s) appended to the root element. Prefer xstyle for StyleX deduplication. |
| style | React.CSSProperties |  | Inline styles applied to the root element. Takes priority over StyleX inline styles. |

### Usage guidance

- Wrap custom controls, native inputs, or third-party widgets that need labeling, helper text, optional/required indicators, or validation status.
- Always provide a label for accessibility, even if visually hidden with isLabelHidden.
- Use inputID and descriptionID to connect the label and description to the inner control with htmlFor and aria-describedby.
- Avoid: Nest Field around styled inputs such as TextInput, Typeahead, Select, DateInput, or TextArea; those components already render their own Field shell.
- Avoid: Use the attached status variant on non-bordered controls such as sliders, switches, or checkboxes; use detached so the message does not overlap the control.
- Avoid: Set both isOptional and isRequired on the same field.
- Avoid: Hide the label without providing an alternative way for the user to understand the field purpose.

### Filter bar

```tsx
import {useState} from 'react';
import {HStack} from '@astryxdesign/core/HStack';
import {Icon} from '@astryxdesign/core/Icon';
import {Selector} from '@astryxdesign/core/Selector';
import {StackItem} from '@astryxdesign/core/Stack';
import {TextInput} from '@astryxdesign/core/TextInput';

// Every Field-based input (TextInput, Selector, DateInput, ...) can be shrunk
// by its row, so a filter bar never pushes the page sideways. Let the row wrap
// so that on a phone the search box keeps a full line and the selectors move
// below it; on wider screens everything stays on one line, with the search box
// taking the free space.
function OrdersFilterBar() {
  const [query, setQuery] = useState('');
  const [status, setStatus] = useState('Awaiting fulfillment');
  const [region, setRegion] = useState('All regions');
  const [sort, setSort] = useState('Newest first');
  return (
    <HStack gap={2} wrap="wrap" vAlign="center">
      <StackItem size="fill">
        <TextInput
          label="Search orders"
          isLabelHidden
          placeholder="Search by order or customer"
          startIcon={<Icon icon="search" />}
          value={query}
          onChange={setQuery}
        />
      </StackItem>
      <Selector
        label="Status"
        isLabelHidden
        options={['All statuses', 'Awaiting fulfillment', 'Shipped', 'Delivered', 'Returned']}
        value={status}
        onChange={setStatus}
      />
      <Selector
        label="Region"
        isLabelHidden
        options={['All regions', 'North America', 'Europe', 'Asia Pacific']}
        value={region}
        onChange={setRegion}
      />
      <Selector
        label="Sort"
        isLabelHidden
        options={['Newest first', 'Oldest first', 'Highest total']}
        value={sort}
        onChange={setSort}
      />
    </HStack>
  );
}
```

### Wrap a custom control

```tsx
function CustomSliderField() {
  return (
    <Field
      label="Confidence"
      inputID="confidence-slider"
      description="Choose how strict the review should be."
      descriptionID="confidence-help"
      status={{type: 'success', message: 'Recommended default'}}
      statusVariant="detached">
      <input
        id="confidence-slider"
        type="range"
        min={0}
        max={100}
        defaultValue={60}
        aria-describedby="confidence-help"
      />
    </Field>
  );
}
```

### Theming API

```json
{
  "targets": [
    {
      "className": "astryx-field",
      "visualProps": [
        "layout"
      ]
    },
    {
      "className": "astryx-field-label"
    },
    {
      "className": "astryx-field-status",
      "visualProps": [
        "type",
        "variant"
      ]
    },
    {
      "className": "astryx-input-status-icon",
      "visualProps": [
        "size",
        "status"
      ]
    },
    {
      "className": "astryx-input-clear-button"
    },
    {
      "className": "astryx-input-clear-icon"
    }
  ],
  "vars": [
    {
      "name": "--_field-radius",
      "description": "Border radius of input fields",
      "default": "var(--radius-element)",
      "private": true
    },
    {
      "name": "--_field-status-overlap",
      "description": "Amount an attached FieldStatus extends behind the lower half of the control. Set from the rendered control size.",
      "default": "calc(var(--size-element-md) / 2)",
      "private": true
    },
    {
      "name": "--_input-clear-hit-inset",
      "description": "Outset of the clear (✕) button's invisible hit area, applied to a ::after overlay. 0 on a fine pointer; negative on a coarse one, which grows the 20px button to the 24px touch target without changing what is drawn.",
      "default": "0px",
      "private": true
    },
    {
      "name": "--_input-clear-hit-content",
      "description": "Whether the clear (✕) button's invisible hit overlay exists. `none` on a fine pointer, so no ::after is generated and hover still reaches the glyph; `\"\"` on a coarse one, where the overlay provides the 24px touch target.",
      "default": "none",
      "private": true
    }
  ],
  "derived": [
    {
      "property": "borderRadius",
      "vars": [
        "--_field-radius"
      ]
    }
  ]
}
```

## FieldLabel



## FieldStatus



### Anatomy

- **Label**: Text identifying the field. Always rendered for accessibility, optionally hidden visually.
- **Description**: Helper text between the label and input explaining what to enter.
- **Control slot**: A custom, native, or third-party control that does not already render a field shell.
- **Status message**: Inline validation feedback showing error, warning, or success with a message.
- **Optional/Required indicator**: Badge next to the label showing whether the field is optional or required.
- **Label tooltip**: Info icon at the end of the label with a tooltip explaining the field.

## Field Label

Standalone label component with optional/required indicators and tooltip support.

| Prop | Type | Default | Description |
|---|---|---|---|
| label * | string |  | Label text. |
| inputID * | string |  | ID of the input this label is for. |
| isLabelHidden | boolean | false | Visually hide the label. |
| isDisabled | boolean | false | Whether the associated input is disabled. |
| isOptional | boolean | false | Show "Optional" indicator. |
| isRequired | boolean | false | Show "Required" indicator. |
| labelIcon | IconType |  | Icon before the label text. See `astryx docs icons` for valid semantic names. |
| labelTooltip | string |  | Tooltip text for info icon at end of label. |


## Examples

- Field Label: Standalone field labels demonstrating required, optional, tooltip, and icon variations.
- Field: A form field wrapping a text input with a label, description, and validation status.
- FieldLabel — Basic: Standalone labels with required and optional indicators and a helper description. Use when labeling a custom control that does not render its own label.
- Field — Required & Optional: Required and optional field indicators side by side. Use isRequired on fields the user must fill in, and isOptional to clarify which fields can be skipped.
- Field — Validation States: All three validation states: error, warning, and success. Use error for invalid input, warning for potential issues like reserved names, and success to confirm valid entries like API keys.
- Field — Description: Fields with helper text below the label. Use descriptions to explain format requirements, constraints, or what happens with the data, like "At least 8 characters" or "We will send a confirmation link".

---

Index of all JGuang resources: https://jiguang132.com/llms.txt
