@xsolla/xui-field-group 0.149.1 → 0.151.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -109
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,25 +1,27 @@
|
|
|
1
|
-
#
|
|
1
|
+
# FieldGroup
|
|
2
2
|
|
|
3
|
-
A cross-platform
|
|
3
|
+
A cross-platform wrapper that adds a label, required indicator, optional icon, and helper text around a form field with consistent vertical spacing.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install @xsolla/xui-field-group
|
|
9
|
-
# or
|
|
10
|
-
yarn add @xsolla/xui-field-group
|
|
11
9
|
```
|
|
12
10
|
|
|
13
|
-
##
|
|
11
|
+
## Imports
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
```tsx
|
|
14
|
+
import { FieldGroup } from '@xsolla/xui-field-group';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
16
18
|
|
|
17
19
|
```tsx
|
|
18
20
|
import * as React from 'react';
|
|
19
21
|
import { FieldGroup } from '@xsolla/xui-field-group';
|
|
20
22
|
import { Input } from '@xsolla/xui-input';
|
|
21
23
|
|
|
22
|
-
export default function
|
|
24
|
+
export default function QuickStart() {
|
|
23
25
|
return (
|
|
24
26
|
<FieldGroup label="Username">
|
|
25
27
|
<Input placeholder="Enter username" />
|
|
@@ -28,42 +30,63 @@ export default function BasicFieldGroup() {
|
|
|
28
30
|
}
|
|
29
31
|
```
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
## API Reference
|
|
34
|
+
|
|
35
|
+
### `<FieldGroup>`
|
|
36
|
+
|
|
37
|
+
Extends `BoxProps` (minus `children`); any layout/style prop the underlying `Box` accepts is forwarded.
|
|
38
|
+
|
|
39
|
+
| Prop | Type | Default | Description |
|
|
40
|
+
| --- | --- | --- | --- |
|
|
41
|
+
| `children` | `ReactNode` | - | Form field component. |
|
|
42
|
+
| `label` | `ReactNode` | - | Label content. |
|
|
43
|
+
| `required` | `boolean` | — | Show a leading red asterisk. |
|
|
44
|
+
| `helper` | `ReactNode` | - | Helper text rendered below the field. |
|
|
45
|
+
| `icon` | `ReactElement` | - | Icon rendered after the label. Sized to match the chosen `size`. |
|
|
46
|
+
| `size` | `"xl" \| "lg" \| "md" \| "sm" \| "xs"` | `"md"` | Sizing token; resolves font size, line height, icon size, and gap via `theme.sizing.input`. |
|
|
47
|
+
| `htmlFor` | `string` | - | Associates the label with a form control by id. |
|
|
48
|
+
| `marginBottom` | `number \| string` | - | Bottom margin for vertical rhythm. |
|
|
49
|
+
| `data-testid` | `string` | - | Test identifier. |
|
|
50
|
+
|
|
51
|
+
Inherits `ThemeOverrideProps` (`themeMode`, `themeProductContext`).
|
|
52
|
+
|
|
53
|
+
If a child renders its own `errorMessage`, the helper margin is collapsed automatically to avoid double spacing.
|
|
54
|
+
|
|
55
|
+
## Anatomy
|
|
32
56
|
|
|
33
57
|
```tsx
|
|
34
|
-
import * as React from 'react';
|
|
35
58
|
import { FieldGroup } from '@xsolla/xui-field-group';
|
|
36
|
-
import { Input } from '@xsolla/xui-input';
|
|
37
59
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
60
|
+
<FieldGroup
|
|
61
|
+
label="Field label"
|
|
62
|
+
required
|
|
63
|
+
helper="Helper text"
|
|
64
|
+
size="md"
|
|
65
|
+
htmlFor="field-id"
|
|
66
|
+
>
|
|
67
|
+
<FormControl id="field-id" />
|
|
68
|
+
</FieldGroup>
|
|
45
69
|
```
|
|
46
70
|
|
|
47
|
-
|
|
71
|
+
## Examples
|
|
72
|
+
|
|
73
|
+
### Required field with helper
|
|
48
74
|
|
|
49
75
|
```tsx
|
|
50
76
|
import * as React from 'react';
|
|
51
77
|
import { FieldGroup } from '@xsolla/xui-field-group';
|
|
52
78
|
import { Input } from '@xsolla/xui-input';
|
|
53
79
|
|
|
54
|
-
export default function
|
|
80
|
+
export default function RequiredHelper() {
|
|
55
81
|
return (
|
|
56
|
-
<FieldGroup
|
|
57
|
-
|
|
58
|
-
helper="Must be at least 8 characters"
|
|
59
|
-
>
|
|
60
|
-
<Input type="password" placeholder="Enter password" />
|
|
82
|
+
<FieldGroup label="Email" required helper="We'll never share your email">
|
|
83
|
+
<Input type="email" placeholder="you@example.com" />
|
|
61
84
|
</FieldGroup>
|
|
62
85
|
);
|
|
63
86
|
}
|
|
64
87
|
```
|
|
65
88
|
|
|
66
|
-
###
|
|
89
|
+
### Label icon
|
|
67
90
|
|
|
68
91
|
```tsx
|
|
69
92
|
import * as React from 'react';
|
|
@@ -71,127 +94,72 @@ import { FieldGroup } from '@xsolla/xui-field-group';
|
|
|
71
94
|
import { Input } from '@xsolla/xui-input';
|
|
72
95
|
import { Info } from '@xsolla/xui-icons-base';
|
|
73
96
|
|
|
74
|
-
export default function
|
|
97
|
+
export default function LabelIcon() {
|
|
75
98
|
return (
|
|
76
|
-
<FieldGroup
|
|
77
|
-
label="API Key"
|
|
78
|
-
icon={<Info />}
|
|
79
|
-
>
|
|
99
|
+
<FieldGroup label="API key" icon={<Info />}>
|
|
80
100
|
<Input placeholder="Enter API key" />
|
|
81
101
|
</FieldGroup>
|
|
82
102
|
);
|
|
83
103
|
}
|
|
84
104
|
```
|
|
85
105
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
```jsx
|
|
89
|
-
import { FieldGroup } from '@xsolla/xui-field-group';
|
|
90
|
-
|
|
91
|
-
<FieldGroup
|
|
92
|
-
label="Field Label" // Label text
|
|
93
|
-
required={false} // Show required asterisk
|
|
94
|
-
helper="Helper text" // Helper text below field
|
|
95
|
-
icon={<Icon />} // Icon next to label
|
|
96
|
-
size="md" // Size variant
|
|
97
|
-
marginBottom={16} // Bottom margin (spacing)
|
|
98
|
-
htmlFor="field-id" // Associate with form field
|
|
99
|
-
>
|
|
100
|
-
<FormField /> // Form control component
|
|
101
|
-
</FieldGroup>
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Examples
|
|
105
|
-
|
|
106
|
-
### Form with Field Groups
|
|
106
|
+
### Sizes
|
|
107
107
|
|
|
108
108
|
```tsx
|
|
109
109
|
import * as React from 'react';
|
|
110
110
|
import { FieldGroup } from '@xsolla/xui-field-group';
|
|
111
111
|
import { Input } from '@xsolla/xui-input';
|
|
112
|
-
import { Select } from '@xsolla/xui-select';
|
|
113
|
-
import { Textarea } from '@xsolla/xui-textarea';
|
|
114
|
-
import { Button } from '@xsolla/xui-button';
|
|
115
112
|
|
|
116
|
-
export default function
|
|
113
|
+
export default function Sizes() {
|
|
117
114
|
return (
|
|
118
|
-
<div style={{
|
|
119
|
-
<FieldGroup label="
|
|
120
|
-
<Input
|
|
115
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
|
116
|
+
<FieldGroup size="xs" label="Extra small" helper="Helper">
|
|
117
|
+
<Input size="xs" placeholder="xs" />
|
|
121
118
|
</FieldGroup>
|
|
122
|
-
<FieldGroup label="
|
|
123
|
-
<Input
|
|
119
|
+
<FieldGroup size="sm" label="Small" helper="Helper">
|
|
120
|
+
<Input size="sm" placeholder="sm" />
|
|
124
121
|
</FieldGroup>
|
|
125
|
-
<FieldGroup label="
|
|
126
|
-
<
|
|
127
|
-
options={['United States', 'Canada', 'United Kingdom']}
|
|
128
|
-
placeholder="Select country"
|
|
129
|
-
/>
|
|
122
|
+
<FieldGroup size="md" label="Medium" helper="Helper">
|
|
123
|
+
<Input size="md" placeholder="md" />
|
|
130
124
|
</FieldGroup>
|
|
131
|
-
<FieldGroup label="
|
|
132
|
-
<
|
|
125
|
+
<FieldGroup size="lg" label="Large" helper="Helper">
|
|
126
|
+
<Input size="lg" placeholder="lg" />
|
|
133
127
|
</FieldGroup>
|
|
134
|
-
<FieldGroup
|
|
135
|
-
<
|
|
128
|
+
<FieldGroup size="xl" label="Extra large" helper="Helper">
|
|
129
|
+
<Input size="xl" placeholder="xl" />
|
|
136
130
|
</FieldGroup>
|
|
137
131
|
</div>
|
|
138
132
|
);
|
|
139
133
|
}
|
|
140
134
|
```
|
|
141
135
|
|
|
142
|
-
###
|
|
136
|
+
### Form layout
|
|
143
137
|
|
|
144
138
|
```tsx
|
|
145
139
|
import * as React from 'react';
|
|
146
140
|
import { FieldGroup } from '@xsolla/xui-field-group';
|
|
147
141
|
import { Input } from '@xsolla/xui-input';
|
|
142
|
+
import { Button } from '@xsolla/xui-button';
|
|
148
143
|
|
|
149
|
-
export default function
|
|
144
|
+
export default function FormLayout() {
|
|
150
145
|
return (
|
|
151
|
-
<div style={{
|
|
152
|
-
<FieldGroup
|
|
153
|
-
<Input
|
|
146
|
+
<div style={{ maxWidth: 400 }}>
|
|
147
|
+
<FieldGroup label="Full name" required marginBottom={16}>
|
|
148
|
+
<Input placeholder="Jane Doe" />
|
|
154
149
|
</FieldGroup>
|
|
155
|
-
<FieldGroup
|
|
156
|
-
<Input
|
|
150
|
+
<FieldGroup label="Email" required helper="We'll never share your email" marginBottom={16}>
|
|
151
|
+
<Input type="email" placeholder="jane@example.com" />
|
|
157
152
|
</FieldGroup>
|
|
158
|
-
<FieldGroup
|
|
159
|
-
<
|
|
153
|
+
<FieldGroup marginBottom={0}>
|
|
154
|
+
<Button>Submit</Button>
|
|
160
155
|
</FieldGroup>
|
|
161
156
|
</div>
|
|
162
157
|
);
|
|
163
158
|
}
|
|
164
159
|
```
|
|
165
160
|
|
|
166
|
-
##
|
|
167
|
-
|
|
168
|
-
### FieldGroup
|
|
169
|
-
|
|
170
|
-
**FieldGroup Props:**
|
|
161
|
+
## Accessibility
|
|
171
162
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
| label | `string` | - | Label text. |
|
|
176
|
-
| required | `boolean` | `false` | Show required asterisk (*). |
|
|
177
|
-
| helper | `string` | - | Helper text below field. |
|
|
178
|
-
| icon | `ReactElement` | - | Icon next to label. |
|
|
179
|
-
| size | `"sm" \| "md" \| "lg"` | `"md"` | Size variant. |
|
|
180
|
-
| marginBottom | `number` | Based on size | Bottom margin for spacing. |
|
|
181
|
-
| htmlFor | `string` | - | Associate label with field by ID. |
|
|
182
|
-
| data-testid | `string` | - | Test identifier. |
|
|
183
|
-
|
|
184
|
-
## Size Specifications
|
|
185
|
-
|
|
186
|
-
| Size | Label Font | Label Line Height | Helper Font | Margin Bottom |
|
|
187
|
-
| :--- | :--------- | :---------------- | :---------- | :------------ |
|
|
188
|
-
| sm | 10px | 16px | 12px | 8px |
|
|
189
|
-
| md | 12px | 20px | 12px | 16px |
|
|
190
|
-
| lg | 14px | 24px | 12px | 24px |
|
|
191
|
-
|
|
192
|
-
## Behavior
|
|
193
|
-
|
|
194
|
-
- Required asterisk (*) appears before label in red
|
|
195
|
-
- Icon appears after label with appropriate spacing
|
|
196
|
-
- Helper text appears below the field content
|
|
197
|
-
- Consistent vertical rhythm with configurable margins
|
|
163
|
+
- Pass `htmlFor` matching the wrapped control's `id` so the label associates with the field.
|
|
164
|
+
- Helper text reads as part of the field via the surrounding form control's `aria-describedby` when applicable.
|
|
165
|
+
- The required asterisk is visual only; communicate required state via the form control's `required`/`aria-required`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xsolla/xui-field-group",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.151.0",
|
|
4
4
|
"main": "./web/index.js",
|
|
5
5
|
"module": "./web/index.mjs",
|
|
6
6
|
"types": "./web/index.d.ts",
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"test:coverage": "vitest run --coverage"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@xsolla/xui-core": "0.
|
|
17
|
-
"@xsolla/xui-primitives-core": "0.
|
|
16
|
+
"@xsolla/xui-core": "0.151.0",
|
|
17
|
+
"@xsolla/xui-primitives-core": "0.151.0"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"react": ">=16.8.0",
|