@xsolla/xui-multi-select 0.150.0 → 0.152.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 +136 -146
  2. package/package.json +5 -5
package/README.md CHANGED
@@ -1,142 +1,45 @@
1
- # Multi Select
1
+ # MultiSelect
2
2
 
3
- A cross-platform React multi-select component that allows users to select multiple options from a dropdown list with checkboxes.
3
+ A cross-platform multi-select control that lets users pick multiple options from a dropdown list.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
8
  npm install @xsolla/xui-multi-select
9
- # or
10
- yarn add @xsolla/xui-multi-select
11
9
  ```
12
10
 
13
- ## Demo
14
-
15
- ### Basic Multi Select
11
+ ## Imports
16
12
 
17
13
  ```tsx
18
- import * as React from 'react';
19
14
  import { MultiSelect } from '@xsolla/xui-multi-select';
20
-
21
- export default function BasicMultiSelect() {
22
- const [selected, setSelected] = React.useState<string[]>([]);
23
-
24
- return (
25
- <MultiSelect
26
- options={['React', 'Vue', 'Angular', 'Svelte']}
27
- value={selected}
28
- onChange={setSelected}
29
- placeholder="Select frameworks"
30
- />
31
- );
32
- }
15
+ import type {
16
+ MultiSelectProps,
17
+ MultiSelectOption,
18
+ MultiSelectValue,
19
+ MultiSelectVariant,
20
+ MultiSelectSize,
21
+ MultiSelectState,
22
+ } from '@xsolla/xui-multi-select';
33
23
  ```
34
24
 
35
- ### With Label
25
+ ## Quick start
36
26
 
37
27
  ```tsx
38
- import * as React from 'react';
39
- import { MultiSelect } from '@xsolla/xui-multi-select';
28
+ const options = [
29
+ { label: 'React', value: 'react' },
30
+ { label: 'Vue', value: 'vue' },
31
+ { label: 'Angular', value: 'angular' },
32
+ ];
40
33
 
41
- export default function LabeledMultiSelect() {
42
- const [selected, setSelected] = React.useState<string[]>(['Marketing']);
43
-
44
- return (
45
- <MultiSelect
46
- label="Departments"
47
- options={['Engineering', 'Marketing', 'Sales', 'Design', 'HR']}
48
- value={selected}
49
- onChange={setSelected}
50
- placeholder="Select departments"
51
- />
52
- );
53
- }
54
- ```
55
-
56
- ### Multi Select Sizes
57
-
58
- ```tsx
59
- import * as React from 'react';
60
- import { MultiSelect } from '@xsolla/xui-multi-select';
61
-
62
- export default function MultiSelectSizes() {
63
- const options = ['Option 1', 'Option 2', 'Option 3'];
64
-
65
- return (
66
- <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
67
- <MultiSelect options={options} size="xs" placeholder="Extra Small" />
68
- <MultiSelect options={options} size="sm" placeholder="Small" />
69
- <MultiSelect options={options} size="md" placeholder="Medium" />
70
- <MultiSelect options={options} size="lg" placeholder="Large" />
71
- <MultiSelect options={options} size="xl" placeholder="Extra Large" />
72
- </div>
73
- );
74
- }
75
- ```
76
-
77
- ## Anatomy
78
-
79
- ```jsx
80
- import { MultiSelect } from '@xsolla/xui-multi-select';
34
+ const [selected, setSelected] = useState<MultiSelectValue>([]);
81
35
 
82
36
  <MultiSelect
83
- options={['a', 'b', 'c']} // Available options
84
- value={selectedArray} // Currently selected values
85
- onChange={setSelected} // Selection change handler
86
- placeholder="Select..." // Placeholder text
87
- label="Label" // Label above select
88
- size="md" // Size variant
89
- disabled={false} // Disabled state
90
- />
91
- ```
92
-
93
- ## Examples
94
-
95
- ### Form Integration
96
-
97
- ```tsx
98
- import * as React from 'react';
99
- import { MultiSelect } from '@xsolla/xui-multi-select';
100
- import { Button } from '@xsolla/xui-button';
101
-
102
- export default function FormMultiSelect() {
103
- const [skills, setSkills] = React.useState<string[]>([]);
104
-
105
- const handleSubmit = () => {
106
- console.log('Selected skills:', skills);
107
- };
108
-
109
- return (
110
- <div style={{ display: 'flex', flexDirection: 'column', gap: 16, width: 300 }}>
111
- <MultiSelect
112
- label="Skills"
113
- options={['JavaScript', 'TypeScript', 'Python', 'Go', 'Rust', 'Java']}
114
- value={skills}
115
- onChange={setSkills}
116
- placeholder="Select your skills"
117
- />
118
- <Button onPress={handleSubmit}>Submit</Button>
119
- </div>
120
- );
121
- }
122
- ```
123
-
124
- ### Disabled State
125
-
126
- ```tsx
127
- import * as React from 'react';
128
- import { MultiSelect } from '@xsolla/xui-multi-select';
129
-
130
- export default function DisabledMultiSelect() {
131
- return (
132
- <MultiSelect
133
- options={['Option 1', 'Option 2', 'Option 3']}
134
- value={['Option 1']}
135
- disabled
136
- placeholder="Disabled select"
137
- />
138
- );
139
- }
37
+ label="Frameworks"
38
+ options={options}
39
+ value={selected}
40
+ onChange={setSelected}
41
+ placeholder="Select frameworks"
42
+ />;
140
43
  ```
141
44
 
142
45
  ### External panel (B2B grouped select)
@@ -186,33 +89,120 @@ Add backdrop, click-outside, and Escape handling in your layout as needed (see S
186
89
 
187
90
  ## API Reference
188
91
 
189
- ### MultiSelect
190
-
191
- **MultiSelect Props:**
92
+ ### `<MultiSelect>`
192
93
 
193
94
  | Prop | Type | Default | Description |
194
- | :--- | :--- | :------ | :---------- |
195
- | options | `string[]` | - | **Required.** Available options. |
196
- | value | `string[]` | `[]` | Currently selected values. |
197
- | onChange | `(value: string[]) => void` | - | Selection change handler. |
198
- | placeholder | `string` | - | Placeholder when nothing selected. |
199
- | size | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Component size. |
200
- | label | `string` | - | Label above select. |
201
- | disabled | `boolean` | `false` | Disabled state. |
202
- | dropdownMenu | `boolean` | `true` | When `false`, hides the built-in list; use with an external picker (e.g. B2B Group select). |
203
- | onTriggerPress | `() => void` | - | When `dropdownMenu` is false: called when the user activates the field (toggle external panel). |
204
- | menuOpen | `boolean` | `false` | When `dropdownMenu` is false: drives open/chevron state for the control. |
205
- | menuMinWidth | `number` | `540` | When `dropdownMenu` is false: field `min-width` in px (aligned with `GroupSelect`). |
206
-
207
- ## Display Behavior
208
-
209
- - When no items selected: Shows placeholder
210
- - When items selected: Shows "N selected" text
211
- - Dropdown shows checkboxes for each option
212
- - Checked items are visually indicated
95
+ | --- | --- | --- | --- |
96
+ | `options` | `MultiSelectOption[]` | | Available options. |
97
+ | `value` | `MultiSelectValue` | `[]` | Selected values. |
98
+ | `onChange` | `(values: MultiSelectValue) => void` | | Fired when the selection changes. |
99
+ | `placeholder` | `string` | `'Select'` | Placeholder shown when empty. |
100
+ | `label` | `string` | | Label rendered above the control. |
101
+ | `size` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Control size. |
102
+ | `state` | `'default' \| 'hover' \| 'focus' \| 'disable' \| 'error'` | | Forced visual state. |
103
+ | `disabled` | `boolean` | `false` | Disable the control. |
104
+ | `errorMessage` | `string` | | Error message; also marks the control invalid. |
105
+ | `variant` | `'tag' \| 'text'` | `'tag'` | How selected options are displayed. |
106
+ | `flexible` | `boolean` | `true` | When `true` the control grows with content; otherwise fixed-height. |
107
+ | `removeTagsButtons` | `boolean` | `true` | Show a remove button on each tag. |
108
+ | `extraClear` | `boolean` | `false` | Show a clear-all button. |
109
+ | `maxHeight` | `number` | `300` | Maximum dropdown height in pixels. |
110
+ | `iconLeft` | `ReactNode` | | Icon rendered on the left of the control. |
111
+ | `iconRight` | `ReactNode` | | Icon on the right (overrides the default caret). |
112
+ | `dropdownMenu` | `boolean` | `true` | When `false`, hides the built-in list and disables click-to-open; use with an external picker (e.g. `GroupSelect`) wired to the same `value` / `onChange`. |
113
+ | `onTriggerPress` | `() => void` | — | When `dropdownMenu` is `false`: fired when the user activates the field. Typically toggles the external panel. |
114
+ | `menuOpen` | `boolean` | `false` | When `dropdownMenu` is `false`: drives chevron direction and layering like the built-in open state. |
115
+ | `menuMinWidth` | `number` | `540` | When `dropdownMenu` is `false`: field `min-width` in px (matches `GroupSelect`). Use `0` for no minimum. |
116
+
117
+ Inherits `ThemeOverrideProps` (`themeMode`, `themeProductContext`).
118
+
119
+ ### Types
120
+
121
+ ```ts
122
+ type MultiSelectValue = (string | number)[];
123
+ type MultiSelectVariant = 'tag' | 'text';
124
+ type MultiSelectSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
125
+ type MultiSelectState = 'default' | 'hover' | 'focus' | 'disable' | 'error';
126
+
127
+ interface MultiSelectOption {
128
+ label: ReactNode;
129
+ value: string | number;
130
+ disabled?: boolean;
131
+ }
132
+ ```
133
+
134
+ ## Examples
135
+
136
+ ### Sizes
137
+
138
+ ```tsx
139
+ const options = [
140
+ { label: 'React', value: 'react' },
141
+ { label: 'Vue', value: 'vue' },
142
+ { label: 'Angular', value: 'angular' },
143
+ ];
144
+
145
+ <MultiSelect options={options} size="xs" placeholder="Extra small" />
146
+ <MultiSelect options={options} size="sm" placeholder="Small" />
147
+ <MultiSelect options={options} size="md" placeholder="Medium" />
148
+ <MultiSelect options={options} size="lg" placeholder="Large" />
149
+ <MultiSelect options={options} size="xl" placeholder="Extra large" />
150
+ ```
151
+
152
+ ### Text variant with clear-all
153
+
154
+ ```tsx
155
+ const options = [
156
+ { label: 'React', value: 'react' },
157
+ { label: 'Vue', value: 'vue' },
158
+ { label: 'Angular', value: 'angular' },
159
+ ];
160
+
161
+ const [selected, setSelected] = useState<MultiSelectValue>([]);
162
+
163
+ <MultiSelect
164
+ options={options}
165
+ value={selected}
166
+ onChange={setSelected}
167
+ variant="text"
168
+ extraClear
169
+ />;
170
+ ```
171
+
172
+ ### Error state
173
+
174
+ ```tsx
175
+ const options = [
176
+ { label: 'Design', value: 'design' },
177
+ { label: 'Engineering', value: 'engineering' },
178
+ { label: 'Product', value: 'product' },
179
+ ];
180
+
181
+ const [skills, setSkills] = useState<MultiSelectValue>([]);
182
+
183
+ <MultiSelect
184
+ label="Skills"
185
+ options={options}
186
+ value={skills}
187
+ onChange={setSkills}
188
+ errorMessage="Please select at least one skill"
189
+ />;
190
+ ```
191
+
192
+ ### Disabled
193
+
194
+ ```tsx
195
+ const options = [
196
+ { label: 'React', value: 'react' },
197
+ { label: 'Vue', value: 'vue' },
198
+ { label: 'Angular', value: 'angular' },
199
+ ];
200
+
201
+ <MultiSelect options={options} value={['react']} disabled />;
202
+ ```
213
203
 
214
204
  ## Accessibility
215
205
 
216
- - Uses checkbox pattern for selections
217
- - Dropdown is keyboard navigable
218
- - Selection state announced to screen readers
206
+ - Selection is rendered as a checkbox list inside the dropdown.
207
+ - The dropdown is keyboard navigable; selection state is announced to assistive technology.
208
+ - An `errorMessage` marks the control as invalid for screen readers.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-multi-select",
3
- "version": "0.150.0",
3
+ "version": "0.152.0",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -10,10 +10,10 @@
10
10
  "build:native": "PLATFORM=native tsup"
11
11
  },
12
12
  "dependencies": {
13
- "@xsolla/xui-checkbox": "0.150.0",
14
- "@xsolla/xui-core": "0.150.0",
15
- "@xsolla/xui-dropdown": "0.150.0",
16
- "@xsolla/xui-primitives-core": "0.150.0"
13
+ "@xsolla/xui-checkbox": "0.152.0",
14
+ "@xsolla/xui-core": "0.152.0",
15
+ "@xsolla/xui-dropdown": "0.152.0",
16
+ "@xsolla/xui-primitives-core": "0.152.0"
17
17
  },
18
18
  "peerDependencies": {
19
19
  "react": ">=16.8.0",