@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.
- package/README.md +309 -0
- 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.
|
|
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.
|
|
17
|
-
"@xsolla/xui-icons": "0.148.
|
|
18
|
-
"@xsolla/xui-primitives-core": "0.148.
|
|
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",
|