@xsolla/xui-multi-select 0.184.0 → 0.185.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 +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/native/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 useEffect3,
|
|
6
|
+
useState as useState3,
|
|
7
|
+
useCallback as useCallback2
|
|
8
|
+
} from "react";
|
|
3
9
|
|
|
4
10
|
// ../../foundation/primitives-native/src/Box.tsx
|
|
5
11
|
import {
|
|
@@ -283,10 +289,6 @@ var isWeb = false;
|
|
|
283
289
|
// src/MultiSelect.tsx
|
|
284
290
|
import { useModalId, useResolvedTheme as useResolvedTheme4 } from "@xsolla/xui-core";
|
|
285
291
|
|
|
286
|
-
// src/MultiSelectControl.tsx
|
|
287
|
-
import { forwardRef as forwardRef3, useRef as useRef2 } from "react";
|
|
288
|
-
import { useResolvedTheme as useResolvedTheme3 } from "@xsolla/xui-core";
|
|
289
|
-
|
|
290
292
|
// ../../foundation/icons-base/dist/web/index.mjs
|
|
291
293
|
import styled from "styled-components";
|
|
292
294
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
@@ -1065,6 +1067,13 @@ var ExclamationMarkCr = (props) => /* @__PURE__ */ jsx149(BaseIcon, { ...props,
|
|
|
1065
1067
|
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>`;
|
|
1066
1068
|
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>`;
|
|
1067
1069
|
var Remove = (props) => /* @__PURE__ */ jsx173(BaseIcon, { ...props, solidContent: solidContent172, lineContent: lineContent172 });
|
|
1070
|
+
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>`;
|
|
1071
|
+
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>`;
|
|
1072
|
+
var Search = (props) => /* @__PURE__ */ jsx707(BaseIcon, { ...props, solidContent: solidContent706, lineContent: lineContent706 });
|
|
1073
|
+
|
|
1074
|
+
// src/MultiSelectControl.tsx
|
|
1075
|
+
import { forwardRef as forwardRef3, useRef as useRef2 } from "react";
|
|
1076
|
+
import { useResolvedTheme as useResolvedTheme3 } from "@xsolla/xui-core";
|
|
1068
1077
|
|
|
1069
1078
|
// src/useMultiSelectControl.tsx
|
|
1070
1079
|
import {
|
|
@@ -2162,10 +2171,14 @@ var MultiSelect = forwardRef4(
|
|
|
2162
2171
|
iconLeft,
|
|
2163
2172
|
iconRight,
|
|
2164
2173
|
maxHeight = 300,
|
|
2174
|
+
optionOverflow = "truncate",
|
|
2165
2175
|
dropdownMenu = true,
|
|
2166
2176
|
onTriggerPress,
|
|
2167
2177
|
menuOpen = false,
|
|
2168
2178
|
menuMinWidth,
|
|
2179
|
+
searchable = false,
|
|
2180
|
+
searchPlaceholder = "Search",
|
|
2181
|
+
noOptionsMessage = "No results",
|
|
2169
2182
|
testID,
|
|
2170
2183
|
themeMode,
|
|
2171
2184
|
themeProductContext
|
|
@@ -2174,8 +2187,12 @@ var MultiSelect = forwardRef4(
|
|
|
2174
2187
|
const modalId = useModalId();
|
|
2175
2188
|
const controlRef = useRef4(null);
|
|
2176
2189
|
const menuRef = useRef4(null);
|
|
2190
|
+
const containerRef = useRef4(null);
|
|
2191
|
+
const searchInputRef = useRef4(null);
|
|
2177
2192
|
const [menuPosition, setMenuPosition] = useState3(null);
|
|
2193
|
+
const [searchValue, setSearchValue] = useState3("");
|
|
2178
2194
|
const sizeStyles = theme.sizing.input(size);
|
|
2195
|
+
const inputColors = theme.colors.control.input;
|
|
2179
2196
|
const state = externalState || (disabled ? "disable" : "default");
|
|
2180
2197
|
const isDisable = state === "disable" || disabled;
|
|
2181
2198
|
const isError = state === "error" || !!errorMessage;
|
|
@@ -2200,7 +2217,19 @@ var MultiSelect = forwardRef4(
|
|
|
2200
2217
|
onClose();
|
|
2201
2218
|
}
|
|
2202
2219
|
}, [isDisable, dropdownMenu, onClose]);
|
|
2203
|
-
|
|
2220
|
+
useEffect3(() => {
|
|
2221
|
+
if (isOpen && searchable && isWeb) {
|
|
2222
|
+
searchInputRef.current?.focus();
|
|
2223
|
+
}
|
|
2224
|
+
}, [isOpen, searchable]);
|
|
2225
|
+
useEffect3(() => {
|
|
2226
|
+
if (!isOpen) setSearchValue("");
|
|
2227
|
+
}, [isOpen]);
|
|
2228
|
+
const getOptionText = (opt) => typeof opt.label === "string" ? opt.label : String(opt.value);
|
|
2229
|
+
const filteredOptions = searchable && searchValue ? options.filter(
|
|
2230
|
+
(opt) => getOptionText(opt).toLowerCase().includes(searchValue.toLowerCase())
|
|
2231
|
+
) : options;
|
|
2232
|
+
const menuItems = filteredOptions.map((opt) => {
|
|
2204
2233
|
const id = String(opt.value);
|
|
2205
2234
|
const checked = values.map(String).includes(id);
|
|
2206
2235
|
return {
|
|
@@ -2218,6 +2247,22 @@ var MultiSelect = forwardRef4(
|
|
|
2218
2247
|
};
|
|
2219
2248
|
const controlMenuOpen = dropdownMenu ? isOpen : Boolean(menuOpen);
|
|
2220
2249
|
const controlOnClick = dropdownMenu ? onSelectClick : onTriggerPress;
|
|
2250
|
+
const isScrollOverflow = optionOverflow === "scroll";
|
|
2251
|
+
const isWrapOverflow = optionOverflow === "wrap";
|
|
2252
|
+
const optionListOverflowX = isScrollOverflow ? "auto" : "hidden";
|
|
2253
|
+
const optionRowMinWidth = isScrollOverflow ? void 0 : 0;
|
|
2254
|
+
const optionLabelNumberOfLines = optionOverflow === "truncate" ? 1 : void 0;
|
|
2255
|
+
const optionLabelStyle = isScrollOverflow ? { whiteSpace: "nowrap" } : isWrapOverflow ? {
|
|
2256
|
+
minWidth: 0,
|
|
2257
|
+
whiteSpace: "normal",
|
|
2258
|
+
overflowWrap: "break-word",
|
|
2259
|
+
wordBreak: "break-word"
|
|
2260
|
+
} : {
|
|
2261
|
+
minWidth: 0,
|
|
2262
|
+
whiteSpace: "nowrap",
|
|
2263
|
+
overflow: "hidden",
|
|
2264
|
+
textOverflow: "ellipsis"
|
|
2265
|
+
};
|
|
2221
2266
|
const updateMenuPosition = useCallback2(() => {
|
|
2222
2267
|
if (!isWeb || !controlRef.current) return;
|
|
2223
2268
|
const rect = controlRef.current.getBoundingClientRect();
|
|
@@ -2237,13 +2282,25 @@ var MultiSelect = forwardRef4(
|
|
|
2237
2282
|
window.removeEventListener("scroll", updateMenuPosition, true);
|
|
2238
2283
|
};
|
|
2239
2284
|
}, [controlMenuOpen, dropdownMenu, isDisable, updateMenuPosition]);
|
|
2285
|
+
useEffect3(() => {
|
|
2286
|
+
if (!isWeb || !dropdownMenu || !isOpen || isDisable) return;
|
|
2287
|
+
const handleOutsideMouseDown = (event) => {
|
|
2288
|
+
const path = typeof event.composedPath === "function" ? event.composedPath() : [];
|
|
2289
|
+
const targetNode = event.target;
|
|
2290
|
+
const isInside = (el) => !!el && (path.length ? path.includes(el) : !!targetNode && el.contains(targetNode));
|
|
2291
|
+
if (isInside(containerRef.current) || isInside(menuRef.current)) return;
|
|
2292
|
+
onClose();
|
|
2293
|
+
};
|
|
2294
|
+
document.addEventListener("mousedown", handleOutsideMouseDown);
|
|
2295
|
+
return () => document.removeEventListener("mousedown", handleOutsideMouseDown);
|
|
2296
|
+
}, [dropdownMenu, isOpen, isDisable, onClose]);
|
|
2240
2297
|
const externalFieldLayout = !dropdownMenu ? {
|
|
2241
2298
|
width: "100%",
|
|
2242
2299
|
minWidth: menuMinWidth ?? EXTERNAL_MENU_MIN_WIDTH_DEFAULT,
|
|
2243
2300
|
boxSizing: "border-box"
|
|
2244
2301
|
} : void 0;
|
|
2245
2302
|
const dropdown = dropdownMenu && isOpen && !isDisable && (!isWeb || menuPosition) && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
2246
|
-
/* @__PURE__ */ jsx727(
|
|
2303
|
+
!isWeb && /* @__PURE__ */ jsx727(
|
|
2247
2304
|
Box,
|
|
2248
2305
|
{
|
|
2249
2306
|
"data-modal-id": modalId,
|
|
@@ -2259,7 +2316,7 @@ var MultiSelect = forwardRef4(
|
|
|
2259
2316
|
onPress: onClose
|
|
2260
2317
|
}
|
|
2261
2318
|
),
|
|
2262
|
-
/* @__PURE__ */
|
|
2319
|
+
/* @__PURE__ */ jsxs4(
|
|
2263
2320
|
Box,
|
|
2264
2321
|
{
|
|
2265
2322
|
ref: menuRef,
|
|
@@ -2268,7 +2325,6 @@ var MultiSelect = forwardRef4(
|
|
|
2268
2325
|
borderColor: theme.colors.border.secondary,
|
|
2269
2326
|
borderWidth: 1,
|
|
2270
2327
|
borderRadius: sizeStyles.radius,
|
|
2271
|
-
paddingVertical: 4,
|
|
2272
2328
|
style: {
|
|
2273
2329
|
position: isWeb ? "fixed" : "absolute",
|
|
2274
2330
|
top: isWeb ? menuPosition?.top : "100%",
|
|
@@ -2278,54 +2334,134 @@ var MultiSelect = forwardRef4(
|
|
|
2278
2334
|
marginTop: isWeb ? void 0 : 4,
|
|
2279
2335
|
zIndex: 1001,
|
|
2280
2336
|
// Above control (1000) and backdrop (999)
|
|
2281
|
-
boxShadow: theme.shadow.popover
|
|
2282
|
-
maxHeight,
|
|
2283
|
-
overflowY: "auto"
|
|
2337
|
+
boxShadow: theme.shadow.popover
|
|
2284
2338
|
},
|
|
2285
|
-
children:
|
|
2286
|
-
|
|
2287
|
-
const contentColors = theme.colors.content;
|
|
2288
|
-
return /* @__PURE__ */ jsx727(
|
|
2339
|
+
children: [
|
|
2340
|
+
searchable && isWeb && /* @__PURE__ */ jsx727(
|
|
2289
2341
|
Box,
|
|
2290
2342
|
{
|
|
2291
|
-
testID,
|
|
2292
2343
|
paddingHorizontal: sizeStyles.paddingHorizontal,
|
|
2293
|
-
paddingVertical:
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2344
|
+
paddingVertical: sizeStyles.paddingVertical,
|
|
2345
|
+
borderBottomWidth: 1,
|
|
2346
|
+
borderColor: theme.colors.border.secondary,
|
|
2347
|
+
children: /* @__PURE__ */ jsxs4(
|
|
2348
|
+
Box,
|
|
2349
|
+
{
|
|
2350
|
+
flexDirection: "row",
|
|
2351
|
+
alignItems: "center",
|
|
2352
|
+
gap: sizeStyles.paddingHorizontal / 2,
|
|
2353
|
+
paddingHorizontal: 4,
|
|
2354
|
+
children: [
|
|
2355
|
+
/* @__PURE__ */ jsx727(
|
|
2356
|
+
Icon,
|
|
2357
|
+
{
|
|
2358
|
+
size: sizeStyles.iconSize - 2,
|
|
2359
|
+
color: inputColors.placeholder,
|
|
2360
|
+
children: /* @__PURE__ */ jsx727(Search, {})
|
|
2361
|
+
}
|
|
2362
|
+
),
|
|
2363
|
+
/* @__PURE__ */ jsx727(
|
|
2364
|
+
Box,
|
|
2365
|
+
{
|
|
2366
|
+
as: "input",
|
|
2367
|
+
ref: searchInputRef,
|
|
2368
|
+
testID: testID ? `${testID}-search-input` : void 0,
|
|
2369
|
+
flex: 1,
|
|
2370
|
+
type: "text",
|
|
2371
|
+
"aria-label": searchPlaceholder,
|
|
2372
|
+
value: searchValue,
|
|
2373
|
+
onChange: (e) => setSearchValue(e.target.value),
|
|
2374
|
+
placeholder: searchPlaceholder,
|
|
2375
|
+
style: {
|
|
2376
|
+
border: "none",
|
|
2377
|
+
outline: "none",
|
|
2378
|
+
background: "transparent",
|
|
2379
|
+
color: inputColors.text,
|
|
2380
|
+
fontSize: sizeStyles.fontSize,
|
|
2381
|
+
width: "100%"
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
)
|
|
2385
|
+
]
|
|
2297
2386
|
}
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
} : void 0,
|
|
2387
|
+
)
|
|
2388
|
+
}
|
|
2389
|
+
),
|
|
2390
|
+
/* @__PURE__ */ jsx727(
|
|
2391
|
+
Box,
|
|
2392
|
+
{
|
|
2393
|
+
paddingVertical: 4,
|
|
2306
2394
|
style: {
|
|
2307
|
-
|
|
2308
|
-
|
|
2395
|
+
maxHeight: searchable ? maxHeight - 60 : maxHeight,
|
|
2396
|
+
overflowY: "auto",
|
|
2397
|
+
overflowX: optionListOverflowX
|
|
2309
2398
|
},
|
|
2310
|
-
children: /* @__PURE__ */ jsx727(
|
|
2311
|
-
|
|
2399
|
+
children: menuItems.length === 0 ? /* @__PURE__ */ jsx727(
|
|
2400
|
+
Box,
|
|
2312
2401
|
{
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
children:
|
|
2402
|
+
paddingVertical: sizeStyles.paddingVertical * 2,
|
|
2403
|
+
paddingHorizontal: sizeStyles.paddingHorizontal,
|
|
2404
|
+
alignItems: "center",
|
|
2405
|
+
children: /* @__PURE__ */ jsx727(
|
|
2406
|
+
Text,
|
|
2407
|
+
{
|
|
2408
|
+
color: theme.colors.content.tertiary,
|
|
2409
|
+
fontSize: sizeStyles.fontSize,
|
|
2410
|
+
children: noOptionsMessage
|
|
2411
|
+
}
|
|
2412
|
+
)
|
|
2317
2413
|
}
|
|
2318
|
-
)
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2414
|
+
) : menuItems.map((item, _index) => {
|
|
2415
|
+
const brandColors = theme.colors.control.brand.primary;
|
|
2416
|
+
const contentColors = theme.colors.content;
|
|
2417
|
+
return /* @__PURE__ */ jsx727(
|
|
2418
|
+
Box,
|
|
2419
|
+
{
|
|
2420
|
+
testID,
|
|
2421
|
+
paddingHorizontal: sizeStyles.paddingHorizontal,
|
|
2422
|
+
paddingVertical: 8,
|
|
2423
|
+
onPress: () => {
|
|
2424
|
+
if (!item.disabled) {
|
|
2425
|
+
handleItemToggle(item.id, !item.checked);
|
|
2426
|
+
}
|
|
2427
|
+
},
|
|
2428
|
+
flexDirection: "row",
|
|
2429
|
+
alignItems: "center",
|
|
2430
|
+
justifyContent: "space-between",
|
|
2431
|
+
backgroundColor: item.checked ? brandColors.bg : "transparent",
|
|
2432
|
+
hoverStyle: !item.disabled && !item.checked ? {
|
|
2433
|
+
backgroundColor: theme.colors.control.input.bgHover
|
|
2434
|
+
} : void 0,
|
|
2435
|
+
style: {
|
|
2436
|
+
cursor: item.disabled ? "not-allowed" : "pointer",
|
|
2437
|
+
opacity: item.disabled ? 0.5 : 1,
|
|
2438
|
+
minWidth: optionRowMinWidth
|
|
2439
|
+
},
|
|
2440
|
+
children: /* @__PURE__ */ jsx727(
|
|
2441
|
+
Text,
|
|
2442
|
+
{
|
|
2443
|
+
color: item.checked ? contentColors.on.brand : theme.colors.content.secondary,
|
|
2444
|
+
fontSize: sizeStyles.fontSize,
|
|
2445
|
+
fontWeight: "400",
|
|
2446
|
+
numberOfLines: optionLabelNumberOfLines,
|
|
2447
|
+
style: optionLabelStyle,
|
|
2448
|
+
children: item.children
|
|
2449
|
+
}
|
|
2450
|
+
)
|
|
2451
|
+
},
|
|
2452
|
+
item.id
|
|
2453
|
+
);
|
|
2454
|
+
})
|
|
2455
|
+
}
|
|
2456
|
+
)
|
|
2457
|
+
]
|
|
2323
2458
|
}
|
|
2324
2459
|
)
|
|
2325
2460
|
] });
|
|
2326
2461
|
return /* @__PURE__ */ jsxs4(
|
|
2327
2462
|
Box,
|
|
2328
2463
|
{
|
|
2464
|
+
ref: containerRef,
|
|
2329
2465
|
testID,
|
|
2330
2466
|
flexDirection: "column",
|
|
2331
2467
|
gap: sizeStyles.fieldGap,
|