@xsolla/xui-select 0.99.0 → 0.101.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 +326 -19
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -1,39 +1,346 @@
1
- # @xsolla/xui-select
1
+ # Select
2
2
 
3
- Single-value dropdown select input with optional search and configurable size/state.
3
+ A cross-platform React select component for choosing from a list of predefined options with dropdown menu. Works on both React (web) and React Native.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
+ npm install @xsolla/xui-select
9
+ # or
8
10
  yarn add @xsolla/xui-select
9
11
  ```
10
12
 
11
- ## Usage
13
+ ## Demo
14
+
15
+ ### Basic Select
16
+
17
+ ```tsx
18
+ import * as React from 'react';
19
+ import { Select } from '@xsolla/xui-select';
20
+
21
+ export default function BasicSelect() {
22
+ const [value, setValue] = React.useState('');
23
+
24
+ return (
25
+ <Select
26
+ value={value}
27
+ onChange={setValue}
28
+ options={['Option 1', 'Option 2', 'Option 3']}
29
+ placeholder="Select an option"
30
+ />
31
+ );
32
+ }
33
+ ```
34
+
35
+ ### Select with Label
36
+
37
+ ```tsx
38
+ import * as React from 'react';
39
+ import { Select } from '@xsolla/xui-select';
40
+
41
+ export default function LabeledSelect() {
42
+ const [country, setCountry] = React.useState('');
43
+
44
+ return (
45
+ <Select
46
+ label="Country"
47
+ value={country}
48
+ onChange={setCountry}
49
+ options={['United States', 'Canada', 'United Kingdom', 'Germany', 'France']}
50
+ placeholder="Select a country"
51
+ />
52
+ );
53
+ }
54
+ ```
55
+
56
+ ### Select with Object Options
57
+
58
+ ```tsx
59
+ import * as React from 'react';
60
+ import { Select } from '@xsolla/xui-select';
61
+
62
+ export default function ObjectOptionsSelect() {
63
+ const [status, setStatus] = React.useState('');
64
+
65
+ const options = [
66
+ { label: 'Active', value: 'active' },
67
+ { label: 'Pending', value: 'pending' },
68
+ { label: 'Inactive', value: 'inactive' },
69
+ ];
70
+
71
+ return (
72
+ <Select
73
+ label="Status"
74
+ value={status}
75
+ onChange={setStatus}
76
+ options={options}
77
+ placeholder="Select status"
78
+ />
79
+ );
80
+ }
81
+ ```
82
+
83
+ ### Select Sizes
12
84
 
13
85
  ```tsx
86
+ import * as React from 'react';
87
+ import { Select } from '@xsolla/xui-select';
88
+
89
+ export default function SelectSizes() {
90
+ const options = ['Small', 'Medium', 'Large'];
91
+
92
+ return (
93
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
94
+ <Select size="xs" options={options} placeholder="Extra Small" />
95
+ <Select size="sm" options={options} placeholder="Small" />
96
+ <Select size="md" options={options} placeholder="Medium (default)" />
97
+ <Select size="lg" options={options} placeholder="Large" />
98
+ <Select size="xl" options={options} placeholder="Extra Large" />
99
+ </div>
100
+ );
101
+ }
102
+ ```
103
+
104
+ ### Select with Icons
105
+
106
+ ```tsx
107
+ import * as React from 'react';
108
+ import { Select } from '@xsolla/xui-select';
109
+ import { Globe } from '@xsolla/xui-icons-base';
110
+
111
+ export default function SelectWithIcons() {
112
+ return (
113
+ <Select
114
+ iconLeft={<Globe />}
115
+ options={['English', 'Spanish', 'French', 'German']}
116
+ placeholder="Select language"
117
+ />
118
+ );
119
+ }
120
+ ```
121
+
122
+ ## Anatomy
123
+
124
+ Import the component and use it directly:
125
+
126
+ ```jsx
14
127
  import { Select } from '@xsolla/xui-select';
15
128
 
16
129
  <Select
17
- label="Country"
18
- options={['Australia', 'Canada', 'United Kingdom']}
19
- placeholder="Choose a country"
20
- onChange={(value) => console.log(value)}
130
+ label="Field Label" // Optional label above select
131
+ value={value} // Controlled selected value
132
+ onChange={setValue} // Value change handler
133
+ options={['A', 'B', 'C']} // Array of options (strings or objects)
134
+ placeholder="Select..." // Placeholder text
135
+ iconLeft={<Icon />} // Optional left icon
136
+ iconRight={<Icon />} // Optional right icon (default: ChevronDown)
137
+ filled // Whether to show filled background
138
+ state="error" // State: "default" | "disable" | "error"
139
+ errorMessage="Error message" // Error message (shown when state="error")
21
140
  />
22
141
  ```
23
142
 
24
- ## Props
143
+ ## Examples
144
+
145
+ ### Error State
146
+
147
+ ```tsx
148
+ import * as React from 'react';
149
+ import { Select } from '@xsolla/xui-select';
150
+
151
+ export default function ErrorSelect() {
152
+ return (
153
+ <Select
154
+ label="Required Field"
155
+ state="error"
156
+ errorMessage="Please select an option"
157
+ options={['Option 1', 'Option 2', 'Option 3']}
158
+ placeholder="Select an option"
159
+ />
160
+ );
161
+ }
162
+ ```
163
+
164
+ ### Disabled Select
165
+
166
+ ```tsx
167
+ import * as React from 'react';
168
+ import { Select } from '@xsolla/xui-select';
169
+
170
+ export default function DisabledSelect() {
171
+ return (
172
+ <Select
173
+ label="Disabled Field"
174
+ value="Option 1"
175
+ state="disable"
176
+ options={['Option 1', 'Option 2', 'Option 3']}
177
+ />
178
+ );
179
+ }
180
+ ```
181
+
182
+ ### Unfilled/Transparent Background
183
+
184
+ ```tsx
185
+ import * as React from 'react';
186
+ import { Select } from '@xsolla/xui-select';
187
+
188
+ export default function UnfilledSelect() {
189
+ return (
190
+ <Select
191
+ filled={false}
192
+ options={['Option 1', 'Option 2', 'Option 3']}
193
+ placeholder="Transparent background"
194
+ />
195
+ );
196
+ }
197
+ ```
198
+
199
+ ### Icon Only Select
200
+
201
+ ```tsx
202
+ import * as React from 'react';
203
+ import { Select } from '@xsolla/xui-select';
204
+ import { Settings } from '@xsolla/xui-icons';
205
+
206
+ export default function IconOnlySelect() {
207
+ return (
208
+ <Select
209
+ iconOnly
210
+ iconLeft={<Settings />}
211
+ options={['Settings', 'Preferences', 'Advanced']}
212
+ />
213
+ );
214
+ }
215
+ ```
216
+
217
+ ### Form with Select
218
+
219
+ ```tsx
220
+ import * as React from 'react';
221
+ import { Select } from '@xsolla/xui-select';
222
+ import { Input } from '@xsolla/xui-input';
223
+ import { Button } from '@xsolla/xui-button';
224
+
225
+ export default function FormWithSelect() {
226
+ const [form, setForm] = React.useState({
227
+ name: '',
228
+ category: '',
229
+ priority: '',
230
+ });
231
+
232
+ return (
233
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 16, width: 300 }}>
234
+ <Input
235
+ label="Task Name"
236
+ value={form.name}
237
+ onChangeText={(name) => setForm(prev => ({ ...prev, name }))}
238
+ placeholder="Enter task name"
239
+ />
240
+ <Select
241
+ label="Category"
242
+ value={form.category}
243
+ onChange={(category) => setForm(prev => ({ ...prev, category }))}
244
+ options={['Development', 'Design', 'Marketing', 'Sales']}
245
+ placeholder="Select category"
246
+ />
247
+ <Select
248
+ label="Priority"
249
+ value={form.priority}
250
+ onChange={(priority) => setForm(prev => ({ ...prev, priority }))}
251
+ options={[
252
+ { label: 'High', value: 'high' },
253
+ { label: 'Medium', value: 'medium' },
254
+ { label: 'Low', value: 'low' },
255
+ ]}
256
+ placeholder="Select priority"
257
+ />
258
+ <Button>Create Task</Button>
259
+ </div>
260
+ );
261
+ }
262
+ ```
263
+
264
+ ## API Reference
25
265
 
26
266
  ### Select
27
267
 
268
+ The main select component. Renders a button trigger with dropdown menu.
269
+
270
+ **Select Props:**
271
+
28
272
  | Prop | Type | Default | Description |
29
- |------|------|---------|-------------|
30
- | `options` | `(string \| SelectOption)[]` | `[]` | List of options to display in the dropdown |
31
- | `value` | `string` | | Currently selected value |
32
- | `onChange` | `(value: string) => void` | | Called when the selected value changes |
33
- | `placeholder` | `string` | `"Select"` | Placeholder text when no value is selected |
34
- | `label` | `string` | | Label displayed above the control |
35
- | `size` | `"xl" \| "lg" \| "md" \| "sm" \| "xs"` | `"md"` | Size of the control |
36
- | `state` | `"default" \| "hover" \| "focus" \| "disable" \| "error"` | `"default"` | Visual state |
37
- | `disabled` | `boolean` | `false` | Disables the control |
38
- | `errorMessage` | `string` | | Error message shown below the control |
39
- | `searchable` | `boolean` | `false` | Enables filtering options by typing |
273
+ | :--- | :--- | :------ | :---------- |
274
+ | value | `string` | - | The controlled selected value. |
275
+ | placeholder | `string` | `"Select"` | Placeholder text when no value selected. |
276
+ | onPress | `() => void` | - | Callback when select trigger is pressed. |
277
+ | size | `"xl" \| "lg" \| "md" \| "sm" \| "xs"` | `"md"` | The size of the select. |
278
+ | state | `"default" \| "hover" \| "focus" \| "disable" \| "error"` | `"default"` | The visual state of the select. |
279
+ | label | `string` | - | Label text displayed above the select. |
280
+ | disabled | `boolean` | `false` | Whether the select is disabled. Also triggered when `state="disable"`. |
281
+ | errorMessage | `string` | - | Error message displayed below the select (also sets error styling). |
282
+ | iconLeft | `ReactNode` | - | Icon displayed on the left side. |
283
+ | iconRight | `ReactNode` | `<ChevronDown />` | Icon displayed on the right side. |
284
+ | filled | `boolean` | `true` | Whether to show filled background. |
285
+ | iconOnly | `boolean` | `false` | Whether to show only icon without text. |
286
+ | options | `(string \| SelectOption)[]` | `[]` | Array of options to display. |
287
+ | onChange | `(value: string) => void` | - | Callback when value changes. |
288
+ | searchable | `boolean` | `false` | Whether to show a search input in the dropdown. |
289
+ | searchPlaceholder | `string` | `"Search"` | Placeholder text for the search input. |
290
+ | noOptionsMessage | `string` | `"No results"` | Message shown when no options match the search. |
291
+ | maxHeight | `number` | `300` | Maximum height of the dropdown in pixels. |
292
+
293
+ **SelectOption Type:**
294
+
295
+ ```typescript
296
+ interface SelectOption {
297
+ label: string; // Display text
298
+ value: any; // Value to be selected
299
+ disabled?: boolean; // Whether this option is disabled
300
+ }
301
+ ```
302
+
303
+ ## Theming
304
+
305
+ Select components use the design system theme for colors and sizing:
306
+
307
+ ```typescript
308
+ // Colors accessed via theme
309
+ theme.colors.control.input.bg // Background color
310
+ theme.colors.control.input.bgHover // Hover background
311
+ theme.colors.control.input.bgFocus // Focus background
312
+ theme.colors.control.input.bgDisable // Disabled background
313
+ theme.colors.control.input.border // Border color
314
+ theme.colors.control.input.borderFocus // Focus border color
315
+ theme.colors.control.input.borderError // Error border color
316
+ theme.colors.control.input.text // Text color
317
+ theme.colors.control.brand.primary.bg // Selected option background
318
+
319
+ // Sizing accessed via theme
320
+ theme.sizing.input(size).height
321
+ theme.sizing.input(size).paddingVertical
322
+ theme.sizing.input(size).paddingHorizontal
323
+ theme.sizing.input(size).fontSize
324
+
325
+ // Border radius
326
+ theme.radius.button
327
+ ```
328
+
329
+ **Dropdown Styling:**
330
+
331
+ | Property | Value |
332
+ | :------- | :---- |
333
+ | Max Height | 300px (configurable via `maxHeight` prop) |
334
+ | Box Shadow | 0 4px 12px rgba(0,0,0,0.1) |
335
+ | Z-Index | 1000 |
336
+ | Scroll | overflowY: auto |
337
+
338
+ ## Accessibility
339
+
340
+ - Uses semantic button element for trigger
341
+ - Dropdown menu has proper focus management
342
+ - Keyboard navigation supported (Tab, Enter, Space, Escape)
343
+ - Selected item is visually highlighted
344
+ - Auto-scrolls to selected item when opened
345
+ - Focus indicators follow WCAG guidelines
346
+ - Disabled state properly communicated to assistive technology
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-select",
3
- "version": "0.99.0",
3
+ "version": "0.101.0",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -10,8 +10,8 @@
10
10
  "build:native": "PLATFORM=native tsup"
11
11
  },
12
12
  "dependencies": {
13
- "@xsolla/xui-core": "0.99.0",
14
- "@xsolla/xui-primitives-core": "0.99.0"
13
+ "@xsolla/xui-core": "0.101.0",
14
+ "@xsolla/xui-primitives-core": "0.101.0"
15
15
  },
16
16
  "peerDependencies": {
17
17
  "react": ">=16.8.0",