Skip to content
CraftDocs
GitHub
Home
Home
Changelog
What's New
Guide
Guide
Getting Started
Principles
Styling Components
Theme System
Foundations
All Tokens
Color
Elevation
Icons
Motion
Shape
Spacing
Typography
Libraries
Libraries
@xds/cli
@xds/core
Themes
Themes
Theme: daily
Default Theme
Theme: matcha
Neutral Theme
Components
Components
AppShell
AspectRatio
Avatar
Avatar
AvatarStatusDot
Badge
Banner
Breadcrumbs
BreadcrumbItem
Breadcrumbs
Button
Button
IconButton
ToggleButton
ToggleButtonGroup
Calendar
Card
Carousel
Chat
ChatComposer
ChatComposerDrawer
ChatComposerInput
ChatComposerTokenElement
ChatDictationButton
ChatLayout
ChatLayoutScrollButton
ChatMessage
ChatMessageBubble
ChatMessageList
ChatMessageMetadata
ChatSendButton
ChatSystemMessage
ChatTokenizedText
ChatToolCalls
Checkbox
CheckboxInput
CheckboxList
CheckboxListItem
ClickableCard
Code
CodeBlock
Collapsible
Collapsible
CollapsibleGroup
useXDSCollapsible
CommandPalette
CommandPalette
CommandPaletteEmpty
CommandPaletteFooter
CommandPaletteGroup
CommandPaletteInput
CommandPaletteItem
CommandPaletteList
DateInput
Dialog
AlertDialog
Dialog
DialogHeader
useXDSImperativeAlertDialog
useXDSImperativeDialog
Divider
DropdownMenu
DropdownMenu
DropdownMenuDivider
DropdownMenuItem
DropdownMenuItemData
DropdownMenuSection
EmptyState
Field
Field
FieldLabel
FieldStatus
Heading
HoverCard
Icon
Kbd
Layout
Center
FormLayout
Grid
GridSpan
HStack
Layout
LayoutContainer
LayoutContent
LayoutFooter
LayoutHeader
LayoutPanel
Section
StackItem
VStack
Link
List
List
ListItem
Markdown
MetadataList
MetadataList
MetadataListItem
MobileNav
MoreMenu
NavIcon
NavMenuItem
NumberInput
OverflowList
Pagination
Popover
PowerSearch
ProgressBar
Radio
RadioList
RadioListItem
Resizable
ResizeHandle
useXDSResizable
SegmentedControl
SegmentedControl
SegmentedControlItem
SelectableCard
Selector
MultiSelector
Selector
SelectorOption
SideNav
SideNav
SideNavCollapseButton
SideNavHeading
SideNavItem
SideNavSection
Skeleton
Slider
Spinner
StatusDot
Switch
Table
BaseTable
Table
TableCell
TableHeaderCell
TableRow
useXDSTableColumnSettings
useXDSTablePagination
useXDSTableSelection
useXDSTableSelectionState
useXDSTableSortable
Tabs
Tab
TabList
TabMenu
Text
TextArea
TextInput
Thumbnail
TimeInput
Timestamp
Toast
Toast
useXDSToast
Token
Tokenizer
Toolbar
Tooltip
TopNav
TopNav
TopNavHeading
TopNavItem
TopNavMegaMenu
TopNavMegaMenuFeaturedCard
TopNavMegaMenuItem
TopNavMenu
TreeList
Typeahead
BaseTypeahead
Typeahead
TypeaheadItem
useXDSHoverCard
useXDSPopover
useXDSTooltip
Utilities
Utilities
LinkProvider
MediaTheme
SyntaxTheme
Theme
useClickableContainer
useEntryAnimation
useFocusTrap
useGridFocus
useImageMode
useInputContainer
useListFocus
useMediaQuery
useOverflow
useScrollLock
useScrollOverflow
useXDSLayer
useXDSStreamingText
Terms of UsePrivacy Policy
Type to search
↑↓Navigate↵SelectEscClose
Field@xds/core · XDSField v0.0.13

Usage

Field wraps any input control with a label, description, and validation status. Use it to build accessible forms with consistent labeling, optional/required indicators, and inline error, warning, or success feedback.
ts
import {XDSField} from '@xds/core/Field'

Best practices

GuidancePractices
DoAlways provide a label for accessibility, even if visually hidden with isLabelHidden.
DoUse the status prop with clear messages to provide inline validation feedback.
DoAdd a description when the label alone does not explain what the field expects, like format hints or constraints.
Don'tSet both isOptional and isRequired on the same field.
Don'tUse the detached status variant on bordered inputs — reserve it for checkboxes, switches, and sliders.
Don'tHide the label without providing an alternative way for the user to understand the field purpose.

Sub-components

Field is a compound component with 3 sub-components.

XDSField

Form field wrapper that provides label, description, and optional/required indicators.
PropTypeDescription
labelrequired
stringLabel text for the field (always rendered for accessibility).
inputIDrequired
stringID for the input element (used for the label htmlFor attribute).
childrenrequired
ReactNodeThe input or control to render.
isLabelHidden
boolean (default: false)Visually hide the label (still accessible to screen readers).
isDisabled
boolean (default: false)Whether the associated input is disabled. Propagates disabled styling to the label.
description
stringDescription text displayed between the label and input.
descriptionID
stringID for the description element (use for aria-describedby on the input).
isOptional
boolean (default: false)Whether the field is optional (mutually exclusive with isRequired).
isRequired
boolean (default: false)Whether the field is required (mutually exclusive with isOptional).
labelIcon
XDSIconTypeIcon to display before the label text. See `npx xds docs icons` for valid semantic names.
labelTooltip
stringTooltip text to display in an info icon at the end of the label.
status
XDSFieldStatusStatus indicator with type and optional message. When message is set, displays a colored status box.
statusVariant
'attached' | 'detached' (default: 'attached')How the status message renders relative to the input. Attached overlaps the input border; detached floats below.
ref
React.Ref<HTMLDivElement>Ref forwarded to the root element.
xstyle
StyleXStylesStyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value — not an inline style object like style={{}}.
className
stringCSS class name(s) appended to the root element. Prefer xstyle for StyleX deduplication.
style
React.CSSPropertiesInline styles applied to the root element. Takes priority over StyleX inline styles.

XDSFieldLabel

Standalone label component with optional/required indicators and tooltip support.
PropTypeDescription
labelrequired
stringLabel text.
inputIDrequired
stringID of the input this label is for.
isLabelHidden
boolean (default: false)Visually hide the label.
isDisabled
boolean (default: false)Whether the associated input is disabled.
isOptional
boolean (default: false)Show "Optional" indicator.
isRequired
boolean (default: false)Show "Required" indicator.
labelIcon
XDSIconTypeIcon before the label text. See `npx xds docs icons` for valid semantic names.
labelTooltip
stringTooltip text for info icon at end of label.

XDSFieldStatus

Status message component for form field validation feedback.
PropTypeDescription
typerequired
'error' | 'warning' | 'success'Status type.
messagerequired
stringStatus message text.
id
stringID for aria-describedby association.
variant
'attached' | 'detached' (default: 'attached')Visual variant — attached overlaps the input, detached floats below.

Examples

Common configurations, variations, and states.
Field — DescriptionFields with helper text below the label. Use descriptions to explain format requirements, constraints, or what happens with the data — like
tsx
'use client';
​
import {useState} from 'react';
import {XDSTextInput} from '@xds/core/TextInput';
import {XDSVStack} from '@xds/core/Layout';
import {XDSCenter} from '@xds/core/Center';
​
export default function FieldWithDescription() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
​
return (
<XDSCenter>
<XDSVStack gap={4}>
<XDSTextInput
label="Email"
description="We'll send a confirmation link to this address"
value={email}
onChange={setEmail}
placeholder="you@example.com"
/>
<XDSTextInput
label="Password"
description="At least 8 characters with one uppercase letter"
value={password}
onChange={setPassword}
placeholder="Create a password"
/>
</XDSVStack>
</XDSCenter>
);
}
Field — Required & OptionalRequired 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.
tsx
'use client';
​
import {useState} from 'react';
import {XDSTextInput} from '@xds/core/TextInput';
import {XDSVStack} from '@xds/core/Layout';
import {XDSCenter} from '@xds/core/Center';
​
export default function FieldRequired() {
const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
​
return (
<XDSCenter>
<XDSVStack gap={4}>
<XDSTextInput
label="Username"
isRequired
value={username}
onChange={setUsername}
placeholder="Enter your username"
/>
<XDSTextInput
label="Backup email"
isOptional
value={email}
onChange={setEmail}
placeholder="you@example.com"
/>
</XDSVStack>
</XDSCenter>
);
}
Field — Validation StatesAll 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.
tsx
'use client';
​
import {useState} from 'react';
import {XDSTextInput} from '@xds/core/TextInput';
import {XDSVStack} from '@xds/core/Layout';
import {XDSCenter} from '@xds/core/Center';
​
export default function FieldStatusVariants() {
const [email, setEmail] = useState('bad-email');
const [username, setUsername] = useState('admin');
const [apiKey, setApiKey] = useState('sk-live-abc123');
​
return (
<XDSCenter>
<XDSVStack gap={4}>
<XDSTextInput
label="Email"
description="Enter your work email"
value={email}
onChange={setEmail}
status={{
type: 'error',
message: 'Please enter a valid email address',
}}
/>
<XDSTextInput
label="Username"
description="Choose a unique username"
value={username}
onChange={setUsername}
status={{
type: 'warning',
message: 'This username is reserved for administrators',
}}
/>
<XDSTextInput
label="API Key"
description="Paste your API key"
value={apiKey}
onChange={setApiKey}
status={{type: 'success', message: 'API key is valid and active'}}
/>
</XDSVStack>
</XDSCenter>
);
}

Showcase source

tsx
'use client';
​
import {useState} from 'react';
import {XDSField} from '@xds/core/Field';
import {XDSTextInput} from '@xds/core/TextInput';
import {XDSStack} from '@xds/core/Layout';
import * as stylex from '@stylexjs/stylex';
​
const styles = stylex.create({
root: {
width: 320,
},
});
​
export default function FieldShowcase() {
const [email, setEmail] = useState('');
​
const status =
email.length > 0 && !email.includes('@')
? {type: 'error' as const, message: 'Enter a valid email address.'}
: undefined;
​
return (
<XDSStack direction="vertical" gap={3} xstyle={styles.root}>
<XDSField
label="Email"
inputID="field-email"
description="We will never share your email."
isRequired
status={status}>
<XDSTextInput
label="Email"
isLabelHidden
value={email}
onChange={setEmail}
placeholder="you@example.com"
/>
</XDSField>
</XDSStack>
);
}