@xsolla/xui-multi-select 0.183.0 → 0.185.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 +56 -0
- package/native/index.d.mts +31 -1
- package/native/index.d.ts +31 -1
- package/native/index.js +171 -41
- package/native/index.js.map +1 -1
- package/native/index.mjs +178 -42
- package/native/index.mjs.map +1 -1
- package/package.json +5 -5
- package/web/index.d.mts +31 -1
- package/web/index.d.ts +31 -1
- package/web/index.js +171 -41
- package/web/index.js.map +1 -1
- package/web/index.mjs +178 -42
- package/web/index.mjs.map +1 -1
package/web/index.mjs
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
// src/MultiSelect.tsx
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
forwardRef as forwardRef4,
|
|
4
|
+
useRef as useRef4,
|
|
5
|
+
useEffect as useEffect4,
|
|
6
|
+
useState as useState4,
|
|
7
|
+
useCallback as useCallback2
|
|
8
|
+
} from "react";
|
|
3
9
|
|
|
4
10
|
// ../../foundation/primitives-web/src/Box.tsx
|
|
5
11
|
import React2 from "react";
|
|
@@ -323,10 +329,6 @@ var isWeb = true;
|
|
|
323
329
|
// src/MultiSelect.tsx
|
|
324
330
|
import { useModalId, useResolvedTheme as useResolvedTheme4 } from "@xsolla/xui-core";
|
|
325
331
|
|
|
326
|
-
// src/MultiSelectControl.tsx
|
|
327
|
-
import { forwardRef as forwardRef3, useRef as useRef2 } from "react";
|
|
328
|
-
import { useResolvedTheme as useResolvedTheme3 } from "@xsolla/xui-core";
|
|
329
|
-
|
|
330
332
|
// ../../foundation/icons-base/dist/web/index.mjs
|
|
331
333
|
import styled4 from "styled-components";
|
|
332
334
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
@@ -1105,6 +1107,13 @@ var ExclamationMarkCr = (props) => /* @__PURE__ */ jsx149(BaseIcon, { ...props,
|
|
|
1105
1107
|
var solidContent172 = `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><g id="icon_remove--solid"><path id="Union" d="M20.5 3C20.7761 3 21 3.22386 21 3.5V20.5C21 20.7761 20.7761 21 20.5 21H3.5C3.22386 21 3 20.7761 3 20.5V3.5C3 3.22386 3.22386 3 3.5 3H20.5ZM12 10.5859L7.20703 5.79297L5.79297 7.20703L10.5859 12L5.79297 16.793L7.20703 18.207L12 13.4141L16.793 18.207L18.207 16.793L13.4141 12L18.207 7.20703L16.793 5.79297L12 10.5859Z" style="fill: currentColor"/></g></svg>`;
|
|
1106
1108
|
var lineContent172 = `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><g id="icon_remove--line"><path id="Union" d="M20.0303 5.41455L13.4199 12.0249L20.0195 18.6245L18.6055 20.0386L12.0059 13.439L5.41406 20.0308L4 18.6167L10.5918 12.0249L4.00879 5.44189L5.42285 4.02783L12.0059 10.6108L18.6162 4.00049L20.0303 5.41455Z" style="fill: currentColor"/></g></svg>`;
|
|
1107
1109
|
var Remove = (props) => /* @__PURE__ */ jsx173(BaseIcon, { ...props, solidContent: solidContent172, lineContent: lineContent172 });
|
|
1110
|
+
var solidContent706 = `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><g id="icon_search--solid"><path id="Union" d="M10.0215 2.02148C14.4398 2.02148 18.0215 5.60321 18.0215 10.0215C18.0215 11.8699 17.3926 13.5702 16.3398 14.9248L21.9785 20.5645L20.5645 21.9785L14.9248 16.3389C13.5702 17.3918 11.8701 18.0215 10.0215 18.0215C5.60321 18.0215 2.02148 14.4398 2.02148 10.0215C2.02148 5.60321 5.60321 2.02148 10.0215 2.02148ZM10.0215 4.02148C6.70778 4.02148 4.02148 6.70778 4.02148 10.0215C4.02148 13.3352 6.70778 16.0215 10.0215 16.0215C13.3352 16.0215 16.0215 13.3352 16.0215 10.0215C16.0215 6.70778 13.3352 4.02148 10.0215 4.02148ZM7.19336 7.19336C8.75546 5.63126 11.2875 5.63126 12.8496 7.19336C14.4117 8.75546 14.4117 11.2875 12.8496 12.8496C11.2875 14.4117 8.75546 14.4117 7.19336 12.8496C5.63126 11.2875 5.63127 8.75546 7.19336 7.19336Z" style="fill: currentColor"/></g></svg>`;
|
|
1111
|
+
var lineContent706 = `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><g id="icon_search--line"><path id="Union" fill-rule="evenodd" clip-rule="evenodd" d="M10 2C14.4183 2 18 5.58172 18 10C18 11.8484 17.3711 13.5488 16.3184 14.9033L21.957 20.543L20.543 21.957L14.9033 16.3174C13.5487 17.3703 11.8486 18 10 18C5.58172 18 2 14.4183 2 10C2 5.58172 5.58172 2 10 2ZM10 4C6.68629 4 4 6.68629 4 10C4 13.3137 6.68629 16 10 16C13.3137 16 16 13.3137 16 10C16 6.68629 13.3137 4 10 4Z" style="fill: currentColor"/></g></svg>`;
|
|
1112
|
+
var Search = (props) => /* @__PURE__ */ jsx707(BaseIcon, { ...props, solidContent: solidContent706, lineContent: lineContent706 });
|
|
1113
|
+
|
|
1114
|
+
// src/MultiSelectControl.tsx
|
|
1115
|
+
import { forwardRef as forwardRef3, useRef as useRef2 } from "react";
|
|
1116
|
+
import { useResolvedTheme as useResolvedTheme3 } from "@xsolla/xui-core";
|
|
1108
1117
|
|
|
1109
1118
|
// src/useMultiSelectControl.tsx
|
|
1110
1119
|
import {
|
|
@@ -2208,10 +2217,14 @@ var MultiSelect = forwardRef4(
|
|
|
2208
2217
|
iconLeft,
|
|
2209
2218
|
iconRight,
|
|
2210
2219
|
maxHeight = 300,
|
|
2220
|
+
optionOverflow = "truncate",
|
|
2211
2221
|
dropdownMenu = true,
|
|
2212
2222
|
onTriggerPress,
|
|
2213
2223
|
menuOpen = false,
|
|
2214
2224
|
menuMinWidth,
|
|
2225
|
+
searchable = false,
|
|
2226
|
+
searchPlaceholder = "Search",
|
|
2227
|
+
noOptionsMessage = "No results",
|
|
2215
2228
|
testID,
|
|
2216
2229
|
themeMode,
|
|
2217
2230
|
themeProductContext
|
|
@@ -2220,8 +2233,12 @@ var MultiSelect = forwardRef4(
|
|
|
2220
2233
|
const modalId = useModalId();
|
|
2221
2234
|
const controlRef = useRef4(null);
|
|
2222
2235
|
const menuRef = useRef4(null);
|
|
2236
|
+
const containerRef = useRef4(null);
|
|
2237
|
+
const searchInputRef = useRef4(null);
|
|
2223
2238
|
const [menuPosition, setMenuPosition] = useState4(null);
|
|
2239
|
+
const [searchValue, setSearchValue] = useState4("");
|
|
2224
2240
|
const sizeStyles = theme.sizing.input(size);
|
|
2241
|
+
const inputColors = theme.colors.control.input;
|
|
2225
2242
|
const state = externalState || (disabled ? "disable" : "default");
|
|
2226
2243
|
const isDisable = state === "disable" || disabled;
|
|
2227
2244
|
const isError = state === "error" || !!errorMessage;
|
|
@@ -2246,7 +2263,19 @@ var MultiSelect = forwardRef4(
|
|
|
2246
2263
|
onClose();
|
|
2247
2264
|
}
|
|
2248
2265
|
}, [isDisable, dropdownMenu, onClose]);
|
|
2249
|
-
|
|
2266
|
+
useEffect4(() => {
|
|
2267
|
+
if (isOpen && searchable && isWeb) {
|
|
2268
|
+
searchInputRef.current?.focus();
|
|
2269
|
+
}
|
|
2270
|
+
}, [isOpen, searchable]);
|
|
2271
|
+
useEffect4(() => {
|
|
2272
|
+
if (!isOpen) setSearchValue("");
|
|
2273
|
+
}, [isOpen]);
|
|
2274
|
+
const getOptionText = (opt) => typeof opt.label === "string" ? opt.label : String(opt.value);
|
|
2275
|
+
const filteredOptions = searchable && searchValue ? options.filter(
|
|
2276
|
+
(opt) => getOptionText(opt).toLowerCase().includes(searchValue.toLowerCase())
|
|
2277
|
+
) : options;
|
|
2278
|
+
const menuItems = filteredOptions.map((opt) => {
|
|
2250
2279
|
const id = String(opt.value);
|
|
2251
2280
|
const checked = values.map(String).includes(id);
|
|
2252
2281
|
return {
|
|
@@ -2264,6 +2293,22 @@ var MultiSelect = forwardRef4(
|
|
|
2264
2293
|
};
|
|
2265
2294
|
const controlMenuOpen = dropdownMenu ? isOpen : Boolean(menuOpen);
|
|
2266
2295
|
const controlOnClick = dropdownMenu ? onSelectClick : onTriggerPress;
|
|
2296
|
+
const isScrollOverflow = optionOverflow === "scroll";
|
|
2297
|
+
const isWrapOverflow = optionOverflow === "wrap";
|
|
2298
|
+
const optionListOverflowX = isScrollOverflow ? "auto" : "hidden";
|
|
2299
|
+
const optionRowMinWidth = isScrollOverflow ? void 0 : 0;
|
|
2300
|
+
const optionLabelNumberOfLines = optionOverflow === "truncate" ? 1 : void 0;
|
|
2301
|
+
const optionLabelStyle = isScrollOverflow ? { whiteSpace: "nowrap" } : isWrapOverflow ? {
|
|
2302
|
+
minWidth: 0,
|
|
2303
|
+
whiteSpace: "normal",
|
|
2304
|
+
overflowWrap: "break-word",
|
|
2305
|
+
wordBreak: "break-word"
|
|
2306
|
+
} : {
|
|
2307
|
+
minWidth: 0,
|
|
2308
|
+
whiteSpace: "nowrap",
|
|
2309
|
+
overflow: "hidden",
|
|
2310
|
+
textOverflow: "ellipsis"
|
|
2311
|
+
};
|
|
2267
2312
|
const updateMenuPosition = useCallback2(() => {
|
|
2268
2313
|
if (!isWeb || !controlRef.current) return;
|
|
2269
2314
|
const rect = controlRef.current.getBoundingClientRect();
|
|
@@ -2283,13 +2328,25 @@ var MultiSelect = forwardRef4(
|
|
|
2283
2328
|
window.removeEventListener("scroll", updateMenuPosition, true);
|
|
2284
2329
|
};
|
|
2285
2330
|
}, [controlMenuOpen, dropdownMenu, isDisable, updateMenuPosition]);
|
|
2331
|
+
useEffect4(() => {
|
|
2332
|
+
if (!isWeb || !dropdownMenu || !isOpen || isDisable) return;
|
|
2333
|
+
const handleOutsideMouseDown = (event) => {
|
|
2334
|
+
const path = typeof event.composedPath === "function" ? event.composedPath() : [];
|
|
2335
|
+
const targetNode = event.target;
|
|
2336
|
+
const isInside = (el) => !!el && (path.length ? path.includes(el) : !!targetNode && el.contains(targetNode));
|
|
2337
|
+
if (isInside(containerRef.current) || isInside(menuRef.current)) return;
|
|
2338
|
+
onClose();
|
|
2339
|
+
};
|
|
2340
|
+
document.addEventListener("mousedown", handleOutsideMouseDown);
|
|
2341
|
+
return () => document.removeEventListener("mousedown", handleOutsideMouseDown);
|
|
2342
|
+
}, [dropdownMenu, isOpen, isDisable, onClose]);
|
|
2286
2343
|
const externalFieldLayout = !dropdownMenu ? {
|
|
2287
2344
|
width: "100%",
|
|
2288
2345
|
minWidth: menuMinWidth ?? EXTERNAL_MENU_MIN_WIDTH_DEFAULT,
|
|
2289
2346
|
boxSizing: "border-box"
|
|
2290
2347
|
} : void 0;
|
|
2291
2348
|
const dropdown = dropdownMenu && isOpen && !isDisable && (!isWeb || menuPosition) && /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
2292
|
-
/* @__PURE__ */ jsx726(
|
|
2349
|
+
!isWeb && /* @__PURE__ */ jsx726(
|
|
2293
2350
|
Box,
|
|
2294
2351
|
{
|
|
2295
2352
|
"data-modal-id": modalId,
|
|
@@ -2305,7 +2362,7 @@ var MultiSelect = forwardRef4(
|
|
|
2305
2362
|
onPress: onClose
|
|
2306
2363
|
}
|
|
2307
2364
|
),
|
|
2308
|
-
/* @__PURE__ */
|
|
2365
|
+
/* @__PURE__ */ jsxs4(
|
|
2309
2366
|
Box,
|
|
2310
2367
|
{
|
|
2311
2368
|
ref: menuRef,
|
|
@@ -2314,7 +2371,6 @@ var MultiSelect = forwardRef4(
|
|
|
2314
2371
|
borderColor: theme.colors.border.secondary,
|
|
2315
2372
|
borderWidth: 1,
|
|
2316
2373
|
borderRadius: sizeStyles.radius,
|
|
2317
|
-
paddingVertical: 4,
|
|
2318
2374
|
style: {
|
|
2319
2375
|
position: isWeb ? "fixed" : "absolute",
|
|
2320
2376
|
top: isWeb ? menuPosition?.top : "100%",
|
|
@@ -2324,54 +2380,134 @@ var MultiSelect = forwardRef4(
|
|
|
2324
2380
|
marginTop: isWeb ? void 0 : 4,
|
|
2325
2381
|
zIndex: 1001,
|
|
2326
2382
|
// Above control (1000) and backdrop (999)
|
|
2327
|
-
boxShadow: theme.shadow.popover
|
|
2328
|
-
maxHeight,
|
|
2329
|
-
overflowY: "auto"
|
|
2383
|
+
boxShadow: theme.shadow.popover
|
|
2330
2384
|
},
|
|
2331
|
-
children:
|
|
2332
|
-
|
|
2333
|
-
const contentColors = theme.colors.content;
|
|
2334
|
-
return /* @__PURE__ */ jsx726(
|
|
2385
|
+
children: [
|
|
2386
|
+
searchable && isWeb && /* @__PURE__ */ jsx726(
|
|
2335
2387
|
Box,
|
|
2336
2388
|
{
|
|
2337
|
-
testID,
|
|
2338
2389
|
paddingHorizontal: sizeStyles.paddingHorizontal,
|
|
2339
|
-
paddingVertical:
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2390
|
+
paddingVertical: sizeStyles.paddingVertical,
|
|
2391
|
+
borderBottomWidth: 1,
|
|
2392
|
+
borderColor: theme.colors.border.secondary,
|
|
2393
|
+
children: /* @__PURE__ */ jsxs4(
|
|
2394
|
+
Box,
|
|
2395
|
+
{
|
|
2396
|
+
flexDirection: "row",
|
|
2397
|
+
alignItems: "center",
|
|
2398
|
+
gap: sizeStyles.paddingHorizontal / 2,
|
|
2399
|
+
paddingHorizontal: 4,
|
|
2400
|
+
children: [
|
|
2401
|
+
/* @__PURE__ */ jsx726(
|
|
2402
|
+
Icon,
|
|
2403
|
+
{
|
|
2404
|
+
size: sizeStyles.iconSize - 2,
|
|
2405
|
+
color: inputColors.placeholder,
|
|
2406
|
+
children: /* @__PURE__ */ jsx726(Search, {})
|
|
2407
|
+
}
|
|
2408
|
+
),
|
|
2409
|
+
/* @__PURE__ */ jsx726(
|
|
2410
|
+
Box,
|
|
2411
|
+
{
|
|
2412
|
+
as: "input",
|
|
2413
|
+
ref: searchInputRef,
|
|
2414
|
+
testID: testID ? `${testID}-search-input` : void 0,
|
|
2415
|
+
flex: 1,
|
|
2416
|
+
type: "text",
|
|
2417
|
+
"aria-label": searchPlaceholder,
|
|
2418
|
+
value: searchValue,
|
|
2419
|
+
onChange: (e) => setSearchValue(e.target.value),
|
|
2420
|
+
placeholder: searchPlaceholder,
|
|
2421
|
+
style: {
|
|
2422
|
+
border: "none",
|
|
2423
|
+
outline: "none",
|
|
2424
|
+
background: "transparent",
|
|
2425
|
+
color: inputColors.text,
|
|
2426
|
+
fontSize: sizeStyles.fontSize,
|
|
2427
|
+
width: "100%"
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
)
|
|
2431
|
+
]
|
|
2343
2432
|
}
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
} : void 0,
|
|
2433
|
+
)
|
|
2434
|
+
}
|
|
2435
|
+
),
|
|
2436
|
+
/* @__PURE__ */ jsx726(
|
|
2437
|
+
Box,
|
|
2438
|
+
{
|
|
2439
|
+
paddingVertical: 4,
|
|
2352
2440
|
style: {
|
|
2353
|
-
|
|
2354
|
-
|
|
2441
|
+
maxHeight: searchable ? maxHeight - 60 : maxHeight,
|
|
2442
|
+
overflowY: "auto",
|
|
2443
|
+
overflowX: optionListOverflowX
|
|
2355
2444
|
},
|
|
2356
|
-
children: /* @__PURE__ */ jsx726(
|
|
2357
|
-
|
|
2445
|
+
children: menuItems.length === 0 ? /* @__PURE__ */ jsx726(
|
|
2446
|
+
Box,
|
|
2358
2447
|
{
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
children:
|
|
2448
|
+
paddingVertical: sizeStyles.paddingVertical * 2,
|
|
2449
|
+
paddingHorizontal: sizeStyles.paddingHorizontal,
|
|
2450
|
+
alignItems: "center",
|
|
2451
|
+
children: /* @__PURE__ */ jsx726(
|
|
2452
|
+
Text,
|
|
2453
|
+
{
|
|
2454
|
+
color: theme.colors.content.tertiary,
|
|
2455
|
+
fontSize: sizeStyles.fontSize,
|
|
2456
|
+
children: noOptionsMessage
|
|
2457
|
+
}
|
|
2458
|
+
)
|
|
2363
2459
|
}
|
|
2364
|
-
)
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2460
|
+
) : menuItems.map((item, _index) => {
|
|
2461
|
+
const brandColors = theme.colors.control.brand.primary;
|
|
2462
|
+
const contentColors = theme.colors.content;
|
|
2463
|
+
return /* @__PURE__ */ jsx726(
|
|
2464
|
+
Box,
|
|
2465
|
+
{
|
|
2466
|
+
testID,
|
|
2467
|
+
paddingHorizontal: sizeStyles.paddingHorizontal,
|
|
2468
|
+
paddingVertical: 8,
|
|
2469
|
+
onPress: () => {
|
|
2470
|
+
if (!item.disabled) {
|
|
2471
|
+
handleItemToggle(item.id, !item.checked);
|
|
2472
|
+
}
|
|
2473
|
+
},
|
|
2474
|
+
flexDirection: "row",
|
|
2475
|
+
alignItems: "center",
|
|
2476
|
+
justifyContent: "space-between",
|
|
2477
|
+
backgroundColor: item.checked ? brandColors.bg : "transparent",
|
|
2478
|
+
hoverStyle: !item.disabled && !item.checked ? {
|
|
2479
|
+
backgroundColor: theme.colors.control.input.bgHover
|
|
2480
|
+
} : void 0,
|
|
2481
|
+
style: {
|
|
2482
|
+
cursor: item.disabled ? "not-allowed" : "pointer",
|
|
2483
|
+
opacity: item.disabled ? 0.5 : 1,
|
|
2484
|
+
minWidth: optionRowMinWidth
|
|
2485
|
+
},
|
|
2486
|
+
children: /* @__PURE__ */ jsx726(
|
|
2487
|
+
Text,
|
|
2488
|
+
{
|
|
2489
|
+
color: item.checked ? contentColors.on.brand : theme.colors.content.secondary,
|
|
2490
|
+
fontSize: sizeStyles.fontSize,
|
|
2491
|
+
fontWeight: "400",
|
|
2492
|
+
numberOfLines: optionLabelNumberOfLines,
|
|
2493
|
+
style: optionLabelStyle,
|
|
2494
|
+
children: item.children
|
|
2495
|
+
}
|
|
2496
|
+
)
|
|
2497
|
+
},
|
|
2498
|
+
item.id
|
|
2499
|
+
);
|
|
2500
|
+
})
|
|
2501
|
+
}
|
|
2502
|
+
)
|
|
2503
|
+
]
|
|
2369
2504
|
}
|
|
2370
2505
|
)
|
|
2371
2506
|
] });
|
|
2372
2507
|
return /* @__PURE__ */ jsxs4(
|
|
2373
2508
|
Box,
|
|
2374
2509
|
{
|
|
2510
|
+
ref: containerRef,
|
|
2375
2511
|
testID,
|
|
2376
2512
|
flexDirection: "column",
|
|
2377
2513
|
gap: sizeStyles.fieldGap,
|