@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.
- package/README.md +136 -146
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,142 +1,45 @@
|
|
|
1
|
-
#
|
|
1
|
+
# MultiSelect
|
|
2
2
|
|
|
3
|
-
A cross-platform
|
|
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
|
-
##
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
25
|
+
## Quick start
|
|
36
26
|
|
|
37
27
|
```tsx
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
const options = [
|
|
29
|
+
{ label: 'React', value: 'react' },
|
|
30
|
+
{ label: 'Vue', value: 'vue' },
|
|
31
|
+
{ label: 'Angular', value: 'angular' },
|
|
32
|
+
];
|
|
40
33
|
|
|
41
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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 | `
|
|
196
|
-
| value | `
|
|
197
|
-
| onChange | `(
|
|
198
|
-
| placeholder | `string` |
|
|
199
|
-
|
|
|
200
|
-
|
|
|
201
|
-
|
|
|
202
|
-
|
|
|
203
|
-
|
|
|
204
|
-
|
|
|
205
|
-
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
-
|
|
212
|
-
|
|
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
|
-
-
|
|
217
|
-
-
|
|
218
|
-
-
|
|
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.
|
|
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.
|
|
14
|
-
"@xsolla/xui-core": "0.
|
|
15
|
-
"@xsolla/xui-dropdown": "0.
|
|
16
|
-
"@xsolla/xui-primitives-core": "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",
|