@xsolla/xui-checkbox 0.148.0 → 0.148.1

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 +309 -0
  2. package/package.json +4 -4
package/README.md ADDED
@@ -0,0 +1,309 @@
1
+ # Checkbox
2
+
3
+ A cross-platform React checkbox component with label, description, indeterminate state, and validation support. Works on both React (web) and React Native.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @xsolla/xui-checkbox
9
+ # or
10
+ yarn add @xsolla/xui-checkbox
11
+ ```
12
+
13
+ ## Demo
14
+
15
+ ### Basic Checkbox
16
+
17
+ ```tsx
18
+ import * as React from 'react';
19
+ import { Checkbox } from '@xsolla/xui-checkbox';
20
+
21
+ export default function BasicCheckbox() {
22
+ const [checked, setChecked] = React.useState(false);
23
+
24
+ return (
25
+ <Checkbox
26
+ checked={checked}
27
+ onChange={(e) => setChecked(e.target.checked)}
28
+ >
29
+ Accept terms and conditions
30
+ </Checkbox>
31
+ );
32
+ }
33
+ ```
34
+
35
+ ### Checkbox with Description
36
+
37
+ ```tsx
38
+ import * as React from 'react';
39
+ import { Checkbox } from '@xsolla/xui-checkbox';
40
+
41
+ export default function CheckboxWithDescription() {
42
+ const [checked, setChecked] = React.useState(false);
43
+
44
+ return (
45
+ <Checkbox
46
+ checked={checked}
47
+ onChange={(e) => setChecked(e.target.checked)}
48
+ description="You will receive notifications about updates and promotions"
49
+ >
50
+ Subscribe to newsletter
51
+ </Checkbox>
52
+ );
53
+ }
54
+ ```
55
+
56
+ ### Checkbox Sizes
57
+
58
+ ```tsx
59
+ import * as React from 'react';
60
+ import { Checkbox } from '@xsolla/xui-checkbox';
61
+
62
+ export default function CheckboxSizes() {
63
+ return (
64
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
65
+ <Checkbox size="sm">Small checkbox</Checkbox>
66
+ <Checkbox size="md">Medium checkbox (default)</Checkbox>
67
+ <Checkbox size="lg">Large checkbox</Checkbox>
68
+ <Checkbox size="xl">Extra large checkbox</Checkbox>
69
+ </div>
70
+ );
71
+ }
72
+ ```
73
+
74
+ ### Indeterminate State
75
+
76
+ ```tsx
77
+ import * as React from 'react';
78
+ import { Checkbox } from '@xsolla/xui-checkbox';
79
+
80
+ export default function IndeterminateCheckbox() {
81
+ const [items, setItems] = React.useState([
82
+ { id: 1, label: 'Item 1', checked: true },
83
+ { id: 2, label: 'Item 2', checked: false },
84
+ { id: 3, label: 'Item 3', checked: true },
85
+ ]);
86
+
87
+ const allChecked = items.every((item) => item.checked);
88
+ const someChecked = items.some((item) => item.checked);
89
+
90
+ const handleSelectAll = () => {
91
+ setItems(items.map((item) => ({ ...item, checked: !allChecked })));
92
+ };
93
+
94
+ return (
95
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
96
+ <Checkbox
97
+ checked={allChecked}
98
+ indeterminate={someChecked && !allChecked}
99
+ onChange={handleSelectAll}
100
+ >
101
+ Select all
102
+ </Checkbox>
103
+ <div style={{ marginLeft: 24, display: 'flex', flexDirection: 'column', gap: 8 }}>
104
+ {items.map((item) => (
105
+ <Checkbox
106
+ key={item.id}
107
+ checked={item.checked}
108
+ onChange={(e) => {
109
+ setItems(items.map((i) =>
110
+ i.id === item.id ? { ...i, checked: e.target.checked } : i
111
+ ));
112
+ }}
113
+ >
114
+ {item.label}
115
+ </Checkbox>
116
+ ))}
117
+ </div>
118
+ </div>
119
+ );
120
+ }
121
+ ```
122
+
123
+ ## Anatomy
124
+
125
+ Import the component and use it directly:
126
+
127
+ ```jsx
128
+ import { Checkbox } from '@xsolla/xui-checkbox';
129
+
130
+ <Checkbox
131
+ checked={checked} // Controlled checked state
132
+ onChange={handleChange} // Change handler
133
+ indeterminate={false} // Indeterminate/mixed state
134
+ size="md" // Size variant
135
+ description="Help text" // Description below label
136
+ errorMessage="Error text" // Error message
137
+ disabled={false} // Disabled state
138
+ >
139
+ Label text
140
+ </Checkbox>
141
+ ```
142
+
143
+ ## Examples
144
+
145
+ ### Error State
146
+
147
+ ```tsx
148
+ import * as React from 'react';
149
+ import { Checkbox } from '@xsolla/xui-checkbox';
150
+
151
+ export default function ErrorCheckbox() {
152
+ return (
153
+ <Checkbox
154
+ checked={false}
155
+ errorMessage="You must accept the terms to continue"
156
+ >
157
+ I accept the terms and conditions
158
+ </Checkbox>
159
+ );
160
+ }
161
+ ```
162
+
163
+ ### Disabled Checkbox
164
+
165
+ ```tsx
166
+ import * as React from 'react';
167
+ import { Checkbox } from '@xsolla/xui-checkbox';
168
+
169
+ export default function DisabledCheckbox() {
170
+ return (
171
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
172
+ <Checkbox disabled>Disabled unchecked</Checkbox>
173
+ <Checkbox disabled checked>Disabled checked</Checkbox>
174
+ <Checkbox disabled indeterminate>Disabled indeterminate</Checkbox>
175
+ </div>
176
+ );
177
+ }
178
+ ```
179
+
180
+ ### Form Integration
181
+
182
+ ```tsx
183
+ import * as React from 'react';
184
+ import { Checkbox } from '@xsolla/xui-checkbox';
185
+ import { Button } from '@xsolla/xui-button';
186
+
187
+ export default function FormCheckbox() {
188
+ const [preferences, setPreferences] = React.useState({
189
+ marketing: false,
190
+ updates: true,
191
+ newsletter: false,
192
+ });
193
+
194
+ const handleChange = (key: string) => (e: { target: { checked: boolean } }) => {
195
+ setPreferences((prev) => ({ ...prev, [key]: e.target.checked }));
196
+ };
197
+
198
+ return (
199
+ <form onSubmit={(e) => { e.preventDefault(); console.log(preferences); }}>
200
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
201
+ <Checkbox
202
+ name="marketing"
203
+ checked={preferences.marketing}
204
+ onChange={handleChange('marketing')}
205
+ >
206
+ Receive marketing emails
207
+ </Checkbox>
208
+ <Checkbox
209
+ name="updates"
210
+ checked={preferences.updates}
211
+ onChange={handleChange('updates')}
212
+ >
213
+ Receive product updates
214
+ </Checkbox>
215
+ <Checkbox
216
+ name="newsletter"
217
+ checked={preferences.newsletter}
218
+ onChange={handleChange('newsletter')}
219
+ >
220
+ Subscribe to newsletter
221
+ </Checkbox>
222
+ <Button type="submit">Save Preferences</Button>
223
+ </div>
224
+ </form>
225
+ );
226
+ }
227
+ ```
228
+
229
+ ## API Reference
230
+
231
+ ### Checkbox
232
+
233
+ The main checkbox component with label support.
234
+
235
+ **Checkbox Props:**
236
+
237
+ | Prop | Type | Default | Description |
238
+ | :--- | :--- | :------ | :---------- |
239
+ | children | `ReactNode` | - | Label content displayed next to the checkbox. |
240
+ | checked | `boolean` | `false` | Whether the checkbox is checked. |
241
+ | indeterminate | `boolean` | `false` | Whether to show indeterminate (mixed) state. |
242
+ | size | `"sm" \| "md" \| "lg" \| "xl"` | `"md"` | Size of the checkbox. |
243
+ | disabled | `boolean` | `false` | Whether the checkbox is disabled. |
244
+ | description | `string` | - | Description text displayed below the label. |
245
+ | errorMessage | `string` | - | Error message displayed below (shows error styling). |
246
+ | error | `boolean` | `false` | Show error styling without message. |
247
+ | name | `string` | - | HTML name attribute for form submission. |
248
+ | value | `string` | - | HTML value attribute for form submission. |
249
+ | onChange | `(e: { target: { checked: boolean; name?: string; value?: string } }) => void` | - | Change event handler. |
250
+ | id | `string` | - | HTML id attribute. |
251
+ | aria-label | `string` | - | Accessible label for screen readers. |
252
+
253
+ **Checkbox Ref Methods:**
254
+
255
+ | Method | Description |
256
+ | :----- | :---------- |
257
+ | `focus()` | Programmatically focus the checkbox. |
258
+ | `blur()` | Programmatically blur the checkbox. |
259
+
260
+ **Size Configuration:**
261
+
262
+ | Size | Checkbox | Icon | Gap | Label font/line | Description font/line |
263
+ | :--- | :------- | :--- | :-- | :-------------- | :-------------------- |
264
+ | sm | 16px | 10px | 6px | 14 / 16 | 12 / 14 |
265
+ | md | 18px | 12px | 8px | 16 / 18 | 14 / 16 |
266
+ | lg | 20px | 14px | 10px | 18 / 20 | 16 / 18 |
267
+ | xl | 24px | 16px | 12px | 20 / 22 | 18 / 20 |
268
+
269
+ Frame border is 1px with 4px radius at every size.
270
+
271
+ ## Theming
272
+
273
+ Checkbox uses the design system theme for colors:
274
+
275
+ ```typescript
276
+ // Box fill / icon (checked + indeterminate)
277
+ theme.colors.control.check.bg // Checked background
278
+ theme.colors.control.check.bgHover // Checked background (hover)
279
+ theme.colors.control.check.bgDisable // Disabled background
280
+ theme.colors.control.check.border // Checked border
281
+ theme.colors.control.check.borderHover // Checked border (hover)
282
+ theme.colors.control.check.icon // Checkmark / minus icon
283
+
284
+ // Box fill / border (unchecked)
285
+ theme.colors.control.faint.bg // Unchecked background
286
+ theme.colors.control.faint.bgHover // Unchecked background (hover)
287
+ theme.colors.control.faint.border // Unchecked border
288
+ theme.colors.control.faint.borderHover // Unchecked border (hover)
289
+
290
+ // Text
291
+ theme.colors.control.text.primary // Label text
292
+ theme.colors.control.text.disable // Disabled label / icon / description
293
+ theme.colors.content.tertiary // Description text
294
+ theme.colors.content.alert.primary // Error message text
295
+
296
+ // Validation + focus
297
+ theme.colors.border.alert // Error-state border
298
+ theme.colors.border.brand // Focus ring outline
299
+ ```
300
+
301
+ ## Accessibility
302
+
303
+ - `role="checkbox"` with `aria-checked` reflecting state (`"true"`, `"false"`, `"mixed"`).
304
+ - Keyboard: Tab to focus, Space or Enter to toggle.
305
+ - Visible focus ring: 2px solid `border.brand` outline with 2px offset.
306
+ - `aria-invalid` set when `error` or `errorMessage` is supplied.
307
+ - `aria-describedby` links the label to description and error nodes when present.
308
+ - `aria-labelledby` links the control to its visible label; `aria-label` is used when there is no visible label.
309
+ - Disabled checkboxes use `aria-disabled="true"` and are removed from the tab order.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-checkbox",
3
- "version": "0.148.0",
3
+ "version": "0.148.1",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -13,9 +13,9 @@
13
13
  "test:coverage": "vitest run --coverage"
14
14
  },
15
15
  "dependencies": {
16
- "@xsolla/xui-core": "0.148.0",
17
- "@xsolla/xui-icons": "0.148.0",
18
- "@xsolla/xui-primitives-core": "0.148.0"
16
+ "@xsolla/xui-core": "0.148.1",
17
+ "@xsolla/xui-icons": "0.148.1",
18
+ "@xsolla/xui-primitives-core": "0.148.1"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "react": ">=16.8.0",