@xsolla/xui-field-group
v0.184.0
Published
A cross-platform wrapper that adds a label, required indicator, optional icon, description, and helper text around a form field with consistent vertical spacing.
Downloads
14,124
Readme
FieldGroup
A cross-platform wrapper that adds a label, required indicator, optional icon, description, and helper text around a form field with consistent vertical spacing.
This is a pattern component that wraps any form control or content block with a structured set of contextual elements — a label, helper text, and an optional content slot.
Field Group provides a consistent visual and semantic structure around interactive or informational content. It does not prescribe what goes inside — the content area accepts any child component, such as a text input, dropdown, toggle, date picker, or custom control.
Use Field Group whenever a form element or content block needs a label, description, or helper message. It ensures spacing, alignment, and accessibility attributes are applied consistently across different content types.
Installation
npm install @xsolla/xui-field-groupImports
import { FieldGroup } from "@xsolla/xui-field-group";Quick start
import * as React from "react";
import { FieldGroup } from "@xsolla/xui-field-group";
import { Input } from "@xsolla/xui-input";
export default function QuickStart() {
return (
<FieldGroup label="Username">
<Input placeholder="Enter username" />
</FieldGroup>
);
}API Reference
<FieldGroup>
Extends BoxProps (minus children); any layout/style prop the underlying Box accepts is forwarded.
| Prop | Type | Default | Description |
| -------------- | -------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------- |
| children | ReactNode | - | Form field component. |
| label | ReactNode | - | Label content. |
| required | boolean | — | Show a leading red asterisk. |
| description | ReactNode | - | Descriptive text rendered below the label and above the field. |
| helper | ReactNode | - | Helper text rendered below the field. |
| icon | ReactElement | - | Icon rendered after the label. Sized to match the chosen size. |
| size | "xl" \| "lg" \| "md" \| "sm" \| "xs" | "md" | Sizing token; resolves font size, line height, icon size, and gap via theme.sizing.input. |
| htmlFor | string | - | Associates the label with a form control by id. |
| marginBottom | number \| string | - | Bottom margin for vertical rhythm. |
| data-testid | string | - | Test identifier. |
| testID | string | — | Test ID for testing frameworks. On web this renders as data-testid; on React Native it renders as testID. |
Inherits ThemeOverrideProps (themeMode, themeProductContext).
If a child renders its own errorMessage, the helper margin is collapsed automatically to avoid double spacing.
Anatomy
import { FieldGroup } from "@xsolla/xui-field-group";
<FieldGroup
label="Field label"
required
description="Description text"
helper="Helper text"
size="md"
htmlFor="field-id"
>
<FormControl id="field-id" />
</FieldGroup>;Examples
Required field with helper
import * as React from "react";
import { FieldGroup } from "@xsolla/xui-field-group";
import { Input } from "@xsolla/xui-input";
export default function RequiredHelper() {
return (
<FieldGroup label="Email" required helper="We'll never share your email">
<Input type="email" placeholder="[email protected]" />
</FieldGroup>
);
}Label icon
import * as React from "react";
import { FieldGroup } from "@xsolla/xui-field-group";
import { Input } from "@xsolla/xui-input";
import { Info } from "@xsolla/xui-icons-base";
export default function LabelIcon() {
return (
<FieldGroup label="API key" icon={<Info />}>
<Input placeholder="Enter API key" />
</FieldGroup>
);
}Sizes
import * as React from "react";
import { FieldGroup } from "@xsolla/xui-field-group";
import { Input } from "@xsolla/xui-input";
export default function Sizes() {
return (
<div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
<FieldGroup size="xs" label="Extra small" helper="Helper">
<Input size="xs" placeholder="xs" />
</FieldGroup>
<FieldGroup size="sm" label="Small" helper="Helper">
<Input size="sm" placeholder="sm" />
</FieldGroup>
<FieldGroup size="md" label="Medium" helper="Helper">
<Input size="md" placeholder="md" />
</FieldGroup>
<FieldGroup size="lg" label="Large" helper="Helper">
<Input size="lg" placeholder="lg" />
</FieldGroup>
<FieldGroup size="xl" label="Extra large" helper="Helper">
<Input size="xl" placeholder="xl" />
</FieldGroup>
</div>
);
}Form layout
import * as React from "react";
import { FieldGroup } from "@xsolla/xui-field-group";
import { Input } from "@xsolla/xui-input";
import { Button } from "@xsolla/xui-button";
export default function FormLayout() {
return (
<div style={{ maxWidth: 400 }}>
<FieldGroup label="Full name" required marginBottom={16}>
<Input placeholder="Jane Doe" />
</FieldGroup>
<FieldGroup
label="Email"
required
helper="We'll never share your email"
marginBottom={16}
>
<Input type="email" placeholder="[email protected]" />
</FieldGroup>
<FieldGroup marginBottom={0}>
<Button>Submit</Button>
</FieldGroup>
</div>
);
}Accessibility
- Pass
htmlFormatching the wrapped control'sidso the label associates with the field. - Helper text reads as part of the field via the surrounding form control's
aria-describedbywhen applicable. - The required asterisk is visual only; communicate required state via the form control's
required/aria-required.
