@xsolla/xui-multi-select 0.149.0-pr270.1777888548 → 0.149.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 +0 -49
- package/native/index.d.mts +0 -23
- package/native/index.d.ts +0 -23
- package/native/index.js +135 -159
- package/native/index.js.map +1 -1
- package/native/index.mjs +135 -159
- package/native/index.mjs.map +1 -1
- package/package.json +5 -5
- package/web/index.d.mts +0 -23
- package/web/index.d.ts +0 -23
- package/web/index.js +135 -159
- package/web/index.js.map +1 -1
- package/web/index.mjs +135 -159
- package/web/index.mjs.map +1 -1
package/README.md
CHANGED
|
@@ -139,51 +139,6 @@ export default function DisabledMultiSelect() {
|
|
|
139
139
|
}
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
-
### External panel (B2B grouped select)
|
|
143
|
-
|
|
144
|
-
When the option list is rendered elsewhere (for example [`@xsolla/xui-b2b-group-select`](./b2b-group-select.md)), set **`dropdownMenu={false}`** so the control does not open the built-in list. Wire the same **`value`** / **`onChange`** to both components; use **`onTriggerPress`** to toggle your panel, **`menuOpen`** for chevron/open styling, and **`menuMinWidth`** (default **540**, aligned with `GROUP_SELECT_MIN_PANEL_WIDTH`) so the field matches the panel width.
|
|
145
|
-
|
|
146
|
-
```tsx
|
|
147
|
-
import * as React from 'react';
|
|
148
|
-
import { MultiSelect } from '@xsolla/xui-multi-select';
|
|
149
|
-
import {
|
|
150
|
-
GroupSelect,
|
|
151
|
-
GROUP_SELECT_MIN_PANEL_WIDTH,
|
|
152
|
-
type GroupSelectGroup,
|
|
153
|
-
} from '@xsolla/xui-b2b-group-select';
|
|
154
|
-
|
|
155
|
-
const groups: GroupSelectGroup[] = [/* ... */];
|
|
156
|
-
const flatOptions = groups.flatMap((g) =>
|
|
157
|
-
g.items.map((it) => ({ value: it.id, label: it.label }))
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
export default function GroupedFieldShell() {
|
|
161
|
-
const [value, setValue] = React.useState<string[]>([]);
|
|
162
|
-
const [open, setOpen] = React.useState(false);
|
|
163
|
-
|
|
164
|
-
return (
|
|
165
|
-
<>
|
|
166
|
-
<MultiSelect
|
|
167
|
-
options={flatOptions}
|
|
168
|
-
value={value}
|
|
169
|
-
onChange={(v) => setValue(v.map(String))}
|
|
170
|
-
placeholder="Select regions"
|
|
171
|
-
size="sm"
|
|
172
|
-
dropdownMenu={false}
|
|
173
|
-
menuOpen={open}
|
|
174
|
-
menuMinWidth={GROUP_SELECT_MIN_PANEL_WIDTH}
|
|
175
|
-
onTriggerPress={() => setOpen((o) => !o)}
|
|
176
|
-
/>
|
|
177
|
-
{open && (
|
|
178
|
-
<GroupSelect groups={groups} value={value} onChange={setValue} />
|
|
179
|
-
)}
|
|
180
|
-
</>
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Add backdrop, click-outside, and Escape handling in your layout as needed (see Storybook).
|
|
186
|
-
|
|
187
142
|
## API Reference
|
|
188
143
|
|
|
189
144
|
### MultiSelect
|
|
@@ -199,10 +154,6 @@ Add backdrop, click-outside, and Escape handling in your layout as needed (see S
|
|
|
199
154
|
| size | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Component size. |
|
|
200
155
|
| label | `string` | - | Label above select. |
|
|
201
156
|
| 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
157
|
|
|
207
158
|
## Display Behavior
|
|
208
159
|
|
package/native/index.d.mts
CHANGED
|
@@ -83,29 +83,6 @@ interface MultiSelectProps extends ThemeOverrideProps {
|
|
|
83
83
|
* @default 300
|
|
84
84
|
*/
|
|
85
85
|
maxHeight?: number;
|
|
86
|
-
/**
|
|
87
|
-
* When false, the built-in options list and backdrop are not shown and the control
|
|
88
|
-
* does not open on click. Use with an external picker (e.g. grouped select) wired
|
|
89
|
-
* to the same `value` / `onChange`.
|
|
90
|
-
* @default true
|
|
91
|
-
*/
|
|
92
|
-
dropdownMenu?: boolean;
|
|
93
|
-
/**
|
|
94
|
-
* When `dropdownMenu` is false: fired when the user activates the field (same gesture
|
|
95
|
-
* that would open the built-in list). Typically toggle an external panel.
|
|
96
|
-
*/
|
|
97
|
-
onTriggerPress?: () => void;
|
|
98
|
-
/**
|
|
99
|
-
* When `dropdownMenu` is false: whether an external menu/panel is open — drives
|
|
100
|
-
* chevron direction and control layering like the built-in open state.
|
|
101
|
-
*/
|
|
102
|
-
menuOpen?: boolean;
|
|
103
|
-
/**
|
|
104
|
-
* When `dropdownMenu` is false: `min-width` of the field in px so it aligns with
|
|
105
|
-
* a typical grouped panel (default **540**, same as `GroupSelect`). Use `0` for
|
|
106
|
-
* no minimum. Ignored when the built-in dropdown is enabled.
|
|
107
|
-
*/
|
|
108
|
-
menuMinWidth?: number;
|
|
109
86
|
}
|
|
110
87
|
|
|
111
88
|
declare const MultiSelect: react.ForwardRefExoticComponent<MultiSelectProps & react.RefAttributes<HTMLDivElement>>;
|
package/native/index.d.ts
CHANGED
|
@@ -83,29 +83,6 @@ interface MultiSelectProps extends ThemeOverrideProps {
|
|
|
83
83
|
* @default 300
|
|
84
84
|
*/
|
|
85
85
|
maxHeight?: number;
|
|
86
|
-
/**
|
|
87
|
-
* When false, the built-in options list and backdrop are not shown and the control
|
|
88
|
-
* does not open on click. Use with an external picker (e.g. grouped select) wired
|
|
89
|
-
* to the same `value` / `onChange`.
|
|
90
|
-
* @default true
|
|
91
|
-
*/
|
|
92
|
-
dropdownMenu?: boolean;
|
|
93
|
-
/**
|
|
94
|
-
* When `dropdownMenu` is false: fired when the user activates the field (same gesture
|
|
95
|
-
* that would open the built-in list). Typically toggle an external panel.
|
|
96
|
-
*/
|
|
97
|
-
onTriggerPress?: () => void;
|
|
98
|
-
/**
|
|
99
|
-
* When `dropdownMenu` is false: whether an external menu/panel is open — drives
|
|
100
|
-
* chevron direction and control layering like the built-in open state.
|
|
101
|
-
*/
|
|
102
|
-
menuOpen?: boolean;
|
|
103
|
-
/**
|
|
104
|
-
* When `dropdownMenu` is false: `min-width` of the field in px so it aligns with
|
|
105
|
-
* a typical grouped panel (default **540**, same as `GroupSelect`). Use `0` for
|
|
106
|
-
* no minimum. Ignored when the built-in dropdown is enabled.
|
|
107
|
-
*/
|
|
108
|
-
menuMinWidth?: number;
|
|
109
86
|
}
|
|
110
87
|
|
|
111
88
|
declare const MultiSelect: react.ForwardRefExoticComponent<MultiSelectProps & react.RefAttributes<HTMLDivElement>>;
|
package/native/index.js
CHANGED
|
@@ -1926,7 +1926,6 @@ var MultiSelectControl = (0, import_react8.forwardRef)(
|
|
|
1926
1926
|
iconRight,
|
|
1927
1927
|
disabled = false,
|
|
1928
1928
|
extraClear = false,
|
|
1929
|
-
width,
|
|
1930
1929
|
themeMode,
|
|
1931
1930
|
themeProductContext
|
|
1932
1931
|
}, ref) => {
|
|
@@ -1975,7 +1974,6 @@ var MultiSelectControl = (0, import_react8.forwardRef)(
|
|
|
1975
1974
|
Box,
|
|
1976
1975
|
{
|
|
1977
1976
|
ref,
|
|
1978
|
-
width,
|
|
1979
1977
|
backgroundColor,
|
|
1980
1978
|
borderColor,
|
|
1981
1979
|
borderWidth: borderColor !== "transparent" ? 1 : 0,
|
|
@@ -1987,7 +1985,7 @@ var MultiSelectControl = (0, import_react8.forwardRef)(
|
|
|
1987
1985
|
alignItems: "center",
|
|
1988
1986
|
gap: 8,
|
|
1989
1987
|
style: {
|
|
1990
|
-
cursor: isDisable ? "not-allowed" :
|
|
1988
|
+
cursor: isDisable ? "not-allowed" : "pointer",
|
|
1991
1989
|
boxSizing: "border-box",
|
|
1992
1990
|
height: flexible ? "auto" : sizeStyles.height,
|
|
1993
1991
|
position: "relative",
|
|
@@ -1995,7 +1993,7 @@ var MultiSelectControl = (0, import_react8.forwardRef)(
|
|
|
1995
1993
|
// Above backdrop when open
|
|
1996
1994
|
},
|
|
1997
1995
|
onPress: isDisable ? void 0 : onClick,
|
|
1998
|
-
hoverStyle: !isDisable &&
|
|
1996
|
+
hoverStyle: !isDisable && !isFocus && !isOpen && !isError ? {
|
|
1999
1997
|
backgroundColor: inputColors.bgHover,
|
|
2000
1998
|
borderColor: inputColors.borderHover
|
|
2001
1999
|
} : void 0,
|
|
@@ -2151,7 +2149,6 @@ var useMultiSelect = ({
|
|
|
2151
2149
|
|
|
2152
2150
|
// src/MultiSelect.tsx
|
|
2153
2151
|
var import_jsx_runtime733 = require("react/jsx-runtime");
|
|
2154
|
-
var EXTERNAL_MENU_MIN_WIDTH_DEFAULT = 540;
|
|
2155
2152
|
var MultiSelect = (0, import_react10.forwardRef)(
|
|
2156
2153
|
({
|
|
2157
2154
|
options,
|
|
@@ -2170,10 +2167,6 @@ var MultiSelect = (0, import_react10.forwardRef)(
|
|
|
2170
2167
|
iconLeft,
|
|
2171
2168
|
iconRight,
|
|
2172
2169
|
maxHeight = 300,
|
|
2173
|
-
dropdownMenu = true,
|
|
2174
|
-
onTriggerPress,
|
|
2175
|
-
menuOpen = false,
|
|
2176
|
-
menuMinWidth,
|
|
2177
2170
|
themeMode,
|
|
2178
2171
|
themeProductContext
|
|
2179
2172
|
}, ref) => {
|
|
@@ -2201,10 +2194,10 @@ var MultiSelect = (0, import_react10.forwardRef)(
|
|
|
2201
2194
|
onChange
|
|
2202
2195
|
});
|
|
2203
2196
|
(0, import_react10.useEffect)(() => {
|
|
2204
|
-
if (isDisable
|
|
2197
|
+
if (isDisable) {
|
|
2205
2198
|
onClose();
|
|
2206
2199
|
}
|
|
2207
|
-
}, [isDisable,
|
|
2200
|
+
}, [isDisable, onClose]);
|
|
2208
2201
|
const menuItems = options.map((opt) => {
|
|
2209
2202
|
const id = String(opt.value);
|
|
2210
2203
|
const checked = values.map(String).includes(id);
|
|
@@ -2221,155 +2214,138 @@ var MultiSelect = (0, import_react10.forwardRef)(
|
|
|
2221
2214
|
const newValues = checked ? [...values, value2] : values.filter((v) => v !== value2);
|
|
2222
2215
|
onChoose(newValues.map(String));
|
|
2223
2216
|
};
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2217
|
+
return /* @__PURE__ */ (0, import_jsx_runtime733.jsxs)(Box, { flexDirection: "column", gap: sizeStyles.fieldGap, children: [
|
|
2218
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
|
|
2219
|
+
Text,
|
|
2220
|
+
{
|
|
2221
|
+
color: theme.colors.content.secondary,
|
|
2222
|
+
fontSize: sizeStyles.fontSize - 2,
|
|
2223
|
+
fontWeight: "500",
|
|
2224
|
+
children: label
|
|
2225
|
+
}
|
|
2226
|
+
),
|
|
2227
|
+
/* @__PURE__ */ (0, import_jsx_runtime733.jsxs)(
|
|
2228
|
+
Box,
|
|
2229
|
+
{
|
|
2230
|
+
ref,
|
|
2231
|
+
style: {
|
|
2232
|
+
position: "relative"
|
|
2233
|
+
},
|
|
2234
|
+
children: [
|
|
2235
|
+
/* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
|
|
2236
|
+
MultiSelectControl,
|
|
2237
|
+
{
|
|
2238
|
+
ref: controlRef,
|
|
2239
|
+
isOpen,
|
|
2240
|
+
isFocus,
|
|
2241
|
+
isError,
|
|
2242
|
+
size,
|
|
2243
|
+
state,
|
|
2244
|
+
disabled: isDisable,
|
|
2245
|
+
onClick: onSelectClick,
|
|
2246
|
+
removeValue: onRemove,
|
|
2247
|
+
removeAllValues: onRemoveAll,
|
|
2248
|
+
stateList,
|
|
2249
|
+
selectedItems,
|
|
2250
|
+
variant,
|
|
2251
|
+
flexible,
|
|
2252
|
+
placeholder,
|
|
2253
|
+
removeTagsButtons,
|
|
2254
|
+
iconLeft,
|
|
2255
|
+
iconRight,
|
|
2256
|
+
extraClear
|
|
2257
|
+
}
|
|
2258
|
+
),
|
|
2259
|
+
isOpen && !isDisable && /* @__PURE__ */ (0, import_jsx_runtime733.jsxs)(import_jsx_runtime733.Fragment, { children: [
|
|
2260
|
+
/* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
|
|
2261
|
+
Box,
|
|
2262
|
+
{
|
|
2263
|
+
style: {
|
|
2264
|
+
position: "fixed",
|
|
2265
|
+
top: 0,
|
|
2266
|
+
left: 0,
|
|
2267
|
+
right: 0,
|
|
2268
|
+
bottom: 0,
|
|
2269
|
+
zIndex: 999,
|
|
2270
|
+
cursor: "default"
|
|
2271
|
+
},
|
|
2272
|
+
onPress: onClose
|
|
2273
|
+
}
|
|
2274
|
+
),
|
|
2275
|
+
/* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
|
|
2276
|
+
Box,
|
|
2277
|
+
{
|
|
2278
|
+
ref: menuRef,
|
|
2279
|
+
backgroundColor: theme.colors.background.secondary,
|
|
2280
|
+
borderColor: theme.colors.border.secondary,
|
|
2281
|
+
borderWidth: 1,
|
|
2282
|
+
borderRadius: theme.radius.button,
|
|
2283
|
+
paddingVertical: 4,
|
|
2284
|
+
style: {
|
|
2285
|
+
position: "absolute",
|
|
2286
|
+
top: "100%",
|
|
2287
|
+
left: 0,
|
|
2288
|
+
right: 0,
|
|
2289
|
+
marginTop: 4,
|
|
2290
|
+
zIndex: 1001,
|
|
2291
|
+
// Above control (1000) and backdrop (999)
|
|
2292
|
+
boxShadow: theme.shadow.popover,
|
|
2293
|
+
maxHeight,
|
|
2294
|
+
overflowY: "auto"
|
|
2295
|
+
},
|
|
2296
|
+
children: menuItems.map((item, _index) => {
|
|
2297
|
+
const brandColors = theme.colors.control.brand.primary;
|
|
2298
|
+
const contentColors = theme.colors.content;
|
|
2299
|
+
return /* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
|
|
2300
|
+
Box,
|
|
2301
|
+
{
|
|
2302
|
+
paddingHorizontal: sizeStyles.paddingHorizontal,
|
|
2303
|
+
paddingVertical: 8,
|
|
2304
|
+
onPress: () => {
|
|
2305
|
+
if (!item.disabled) {
|
|
2306
|
+
handleItemToggle(item.id, !item.checked);
|
|
2307
|
+
}
|
|
2308
|
+
},
|
|
2309
|
+
flexDirection: "row",
|
|
2310
|
+
alignItems: "center",
|
|
2311
|
+
justifyContent: "space-between",
|
|
2312
|
+
backgroundColor: item.checked ? brandColors.bg : "transparent",
|
|
2313
|
+
hoverStyle: !item.disabled && !item.checked ? {
|
|
2314
|
+
backgroundColor: theme.colors.control.input.bgHover
|
|
2315
|
+
} : void 0,
|
|
2316
|
+
style: {
|
|
2317
|
+
cursor: item.disabled ? "not-allowed" : "pointer",
|
|
2318
|
+
opacity: item.disabled ? 0.5 : 1
|
|
2319
|
+
},
|
|
2320
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
|
|
2321
|
+
Text,
|
|
2323
2322
|
{
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
)
|
|
2351
|
-
},
|
|
2352
|
-
item.id
|
|
2353
|
-
);
|
|
2354
|
-
})
|
|
2355
|
-
}
|
|
2356
|
-
)
|
|
2357
|
-
] })
|
|
2358
|
-
]
|
|
2359
|
-
}
|
|
2360
|
-
),
|
|
2361
|
-
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
|
|
2362
|
-
Text,
|
|
2363
|
-
{
|
|
2364
|
-
color: theme.colors.content.alert.primary,
|
|
2365
|
-
fontSize: sizeStyles.fontSize - 2,
|
|
2366
|
-
style: { lineHeight: sizeStyles.lineHeight + "px" },
|
|
2367
|
-
children: errorMessage
|
|
2368
|
-
}
|
|
2369
|
-
)
|
|
2370
|
-
]
|
|
2371
|
-
}
|
|
2372
|
-
);
|
|
2323
|
+
color: item.checked ? contentColors.on.brand : theme.colors.content.secondary,
|
|
2324
|
+
fontSize: sizeStyles.fontSize,
|
|
2325
|
+
fontWeight: "400",
|
|
2326
|
+
children: item.children
|
|
2327
|
+
}
|
|
2328
|
+
)
|
|
2329
|
+
},
|
|
2330
|
+
item.id
|
|
2331
|
+
);
|
|
2332
|
+
})
|
|
2333
|
+
}
|
|
2334
|
+
)
|
|
2335
|
+
] })
|
|
2336
|
+
]
|
|
2337
|
+
}
|
|
2338
|
+
),
|
|
2339
|
+
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
|
|
2340
|
+
Text,
|
|
2341
|
+
{
|
|
2342
|
+
color: theme.colors.content.alert.primary,
|
|
2343
|
+
fontSize: sizeStyles.fontSize - 2,
|
|
2344
|
+
style: { lineHeight: sizeStyles.lineHeight + "px" },
|
|
2345
|
+
children: errorMessage
|
|
2346
|
+
}
|
|
2347
|
+
)
|
|
2348
|
+
] });
|
|
2373
2349
|
}
|
|
2374
2350
|
);
|
|
2375
2351
|
MultiSelect.displayName = "MultiSelect";
|