@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.
Files changed (2) hide show
  1. package/README.md +77 -109
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -1,25 +1,27 @@
1
- # Field Group
1
+ # FieldGroup
2
2
 
3
- A cross-platform React wrapper component that adds consistent labeling, required indicators, helper text, and spacing to form fields.
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
- ## Demo
11
+ ## Imports
14
12
 
15
- ### Basic Field Group
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 BasicFieldGroup() {
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
- ### Required Field
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
- export default function RequiredField() {
39
- return (
40
- <FieldGroup label="Email" required>
41
- <Input type="email" placeholder="Enter email" />
42
- </FieldGroup>
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
- ### With Helper Text
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 HelperField() {
80
+ export default function RequiredHelper() {
55
81
  return (
56
- <FieldGroup
57
- label="Password"
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
- ### With Icon
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 IconField() {
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
- ## Anatomy
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 CompleteForm() {
113
+ export default function Sizes() {
117
114
  return (
118
- <div style={{ maxWidth: 400 }}>
119
- <FieldGroup label="Full Name" required>
120
- <Input placeholder="John Doe" />
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="Email" required helper="We'll never share your email">
123
- <Input type="email" placeholder="john@example.com" />
119
+ <FieldGroup size="sm" label="Small" helper="Helper">
120
+ <Input size="sm" placeholder="sm" />
124
121
  </FieldGroup>
125
- <FieldGroup label="Country">
126
- <Select
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="Bio" helper="Max 500 characters">
132
- <Textarea placeholder="Tell us about yourself" />
125
+ <FieldGroup size="lg" label="Large" helper="Helper">
126
+ <Input size="lg" placeholder="lg" />
133
127
  </FieldGroup>
134
- <FieldGroup marginBottom={0}>
135
- <Button>Submit</Button>
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
- ### Field Group Sizes
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 FieldGroupSizes() {
144
+ export default function FormLayout() {
150
145
  return (
151
- <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
152
- <FieldGroup size="sm" label="Small Field" required helper="Small helper">
153
- <Input size="sm" placeholder="Small input" />
146
+ <div style={{ maxWidth: 400 }}>
147
+ <FieldGroup label="Full name" required marginBottom={16}>
148
+ <Input placeholder="Jane Doe" />
154
149
  </FieldGroup>
155
- <FieldGroup size="md" label="Medium Field" required helper="Medium helper">
156
- <Input size="md" placeholder="Medium 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 size="lg" label="Large Field" required helper="Large helper">
159
- <Input size="lg" placeholder="Large input" />
153
+ <FieldGroup marginBottom={0}>
154
+ <Button>Submit</Button>
160
155
  </FieldGroup>
161
156
  </div>
162
157
  );
163
158
  }
164
159
  ```
165
160
 
166
- ## API Reference
167
-
168
- ### FieldGroup
169
-
170
- **FieldGroup Props:**
161
+ ## Accessibility
171
162
 
172
- | Prop | Type | Default | Description |
173
- | :--- | :--- | :------ | :---------- |
174
- | children | `ReactNode` | - | Form field component. |
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.149.1",
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.149.1",
17
- "@xsolla/xui-primitives-core": "0.149.1"
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",