@xsolla/xui-multi-select 0.168.1 → 0.170.0-pr330.1780970046

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/native/index.js CHANGED
@@ -306,6 +306,9 @@ var Icon = ({
306
306
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style, testID: dataTestId || testID, children: childrenWithProps });
307
307
  };
308
308
 
309
+ // ../../foundation/primitives-native/src/index.tsx
310
+ var isWeb = false;
311
+
309
312
  // src/MultiSelect.tsx
310
313
  var import_xui_core4 = require("@xsolla/xui-core");
311
314
 
@@ -2174,8 +2177,12 @@ var useMultiSelect = ({
2174
2177
  };
2175
2178
  };
2176
2179
 
2177
- // src/MultiSelect.tsx
2180
+ // src/Portal.native.tsx
2178
2181
  var import_jsx_runtime733 = require("react/jsx-runtime");
2182
+ var Portal = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime733.jsx)(import_jsx_runtime733.Fragment, { children });
2183
+
2184
+ // src/MultiSelect.tsx
2185
+ var import_jsx_runtime734 = require("react/jsx-runtime");
2179
2186
  var EXTERNAL_MENU_MIN_WIDTH_DEFAULT = 540;
2180
2187
  var MultiSelect = (0, import_react10.forwardRef)(
2181
2188
  ({
@@ -2204,8 +2211,10 @@ var MultiSelect = (0, import_react10.forwardRef)(
2204
2211
  themeProductContext
2205
2212
  }, ref) => {
2206
2213
  const { theme } = (0, import_xui_core4.useResolvedTheme)({ themeMode, themeProductContext });
2214
+ const modalId = (0, import_xui_core4.useModalId)();
2207
2215
  const controlRef = (0, import_react10.useRef)(null);
2208
2216
  const menuRef = (0, import_react10.useRef)(null);
2217
+ const [menuPosition, setMenuPosition] = (0, import_react10.useState)(null);
2209
2218
  const sizeStyles = theme.sizing.input(size);
2210
2219
  const state = externalState || (disabled ? "disable" : "default");
2211
2220
  const isDisable = state === "disable" || disabled;
@@ -2249,12 +2258,112 @@ var MultiSelect = (0, import_react10.forwardRef)(
2249
2258
  };
2250
2259
  const controlMenuOpen = dropdownMenu ? isOpen : Boolean(menuOpen);
2251
2260
  const controlOnClick = dropdownMenu ? onSelectClick : onTriggerPress;
2261
+ const updateMenuPosition = (0, import_react10.useCallback)(() => {
2262
+ if (!isWeb || !controlRef.current) return;
2263
+ const rect = controlRef.current.getBoundingClientRect();
2264
+ setMenuPosition({
2265
+ left: rect.left,
2266
+ top: rect.bottom + 4,
2267
+ width: rect.width
2268
+ });
2269
+ }, []);
2270
+ (0, import_react10.useEffect)(() => {
2271
+ if (!isWeb || !controlMenuOpen || isDisable || !dropdownMenu) return;
2272
+ updateMenuPosition();
2273
+ window.addEventListener("resize", updateMenuPosition);
2274
+ window.addEventListener("scroll", updateMenuPosition, true);
2275
+ return () => {
2276
+ window.removeEventListener("resize", updateMenuPosition);
2277
+ window.removeEventListener("scroll", updateMenuPosition, true);
2278
+ };
2279
+ }, [controlMenuOpen, dropdownMenu, isDisable, updateMenuPosition]);
2252
2280
  const externalFieldLayout = !dropdownMenu ? {
2253
2281
  width: "100%",
2254
2282
  minWidth: menuMinWidth ?? EXTERNAL_MENU_MIN_WIDTH_DEFAULT,
2255
2283
  boxSizing: "border-box"
2256
2284
  } : void 0;
2257
- return /* @__PURE__ */ (0, import_jsx_runtime733.jsxs)(
2285
+ const dropdown = dropdownMenu && isOpen && !isDisable && (!isWeb || menuPosition) && /* @__PURE__ */ (0, import_jsx_runtime734.jsxs)(import_jsx_runtime734.Fragment, { children: [
2286
+ /* @__PURE__ */ (0, import_jsx_runtime734.jsx)(
2287
+ Box,
2288
+ {
2289
+ "data-modal-id": modalId,
2290
+ style: {
2291
+ position: "fixed",
2292
+ top: 0,
2293
+ left: 0,
2294
+ right: 0,
2295
+ bottom: 0,
2296
+ zIndex: 999,
2297
+ cursor: "default"
2298
+ },
2299
+ onPress: onClose
2300
+ }
2301
+ ),
2302
+ /* @__PURE__ */ (0, import_jsx_runtime734.jsx)(
2303
+ Box,
2304
+ {
2305
+ ref: menuRef,
2306
+ "data-modal-id": modalId,
2307
+ backgroundColor: theme.colors.background.secondary,
2308
+ borderColor: theme.colors.border.secondary,
2309
+ borderWidth: 1,
2310
+ borderRadius: sizeStyles.radius,
2311
+ paddingVertical: 4,
2312
+ style: {
2313
+ position: isWeb ? "fixed" : "absolute",
2314
+ top: isWeb ? menuPosition?.top : "100%",
2315
+ left: isWeb ? menuPosition?.left : 0,
2316
+ right: isWeb ? void 0 : 0,
2317
+ width: isWeb ? menuPosition?.width : void 0,
2318
+ marginTop: isWeb ? void 0 : 4,
2319
+ zIndex: 1001,
2320
+ // Above control (1000) and backdrop (999)
2321
+ boxShadow: theme.shadow.popover,
2322
+ maxHeight,
2323
+ overflowY: "auto"
2324
+ },
2325
+ children: menuItems.map((item, _index) => {
2326
+ const brandColors = theme.colors.control.brand.primary;
2327
+ const contentColors = theme.colors.content;
2328
+ return /* @__PURE__ */ (0, import_jsx_runtime734.jsx)(
2329
+ Box,
2330
+ {
2331
+ testID,
2332
+ paddingHorizontal: sizeStyles.paddingHorizontal,
2333
+ paddingVertical: 8,
2334
+ onPress: () => {
2335
+ if (!item.disabled) {
2336
+ handleItemToggle(item.id, !item.checked);
2337
+ }
2338
+ },
2339
+ flexDirection: "row",
2340
+ alignItems: "center",
2341
+ justifyContent: "space-between",
2342
+ backgroundColor: item.checked ? brandColors.bg : "transparent",
2343
+ hoverStyle: !item.disabled && !item.checked ? {
2344
+ backgroundColor: theme.colors.control.input.bgHover
2345
+ } : void 0,
2346
+ style: {
2347
+ cursor: item.disabled ? "not-allowed" : "pointer",
2348
+ opacity: item.disabled ? 0.5 : 1
2349
+ },
2350
+ children: /* @__PURE__ */ (0, import_jsx_runtime734.jsx)(
2351
+ Text,
2352
+ {
2353
+ color: item.checked ? contentColors.on.brand : theme.colors.content.secondary,
2354
+ fontSize: sizeStyles.fontSize,
2355
+ fontWeight: "400",
2356
+ children: item.children
2357
+ }
2358
+ )
2359
+ },
2360
+ item.id
2361
+ );
2362
+ })
2363
+ }
2364
+ )
2365
+ ] });
2366
+ return /* @__PURE__ */ (0, import_jsx_runtime734.jsxs)(
2258
2367
  Box,
2259
2368
  {
2260
2369
  testID,
@@ -2262,7 +2371,7 @@ var MultiSelect = (0, import_react10.forwardRef)(
2262
2371
  gap: sizeStyles.fieldGap,
2263
2372
  style: externalFieldLayout,
2264
2373
  children: [
2265
- label && /* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
2374
+ label && /* @__PURE__ */ (0, import_jsx_runtime734.jsx)(
2266
2375
  Text,
2267
2376
  {
2268
2377
  color: theme.colors.content.secondary,
@@ -2271,7 +2380,7 @@ var MultiSelect = (0, import_react10.forwardRef)(
2271
2380
  children: label
2272
2381
  }
2273
2382
  ),
2274
- /* @__PURE__ */ (0, import_jsx_runtime733.jsxs)(
2383
+ /* @__PURE__ */ (0, import_jsx_runtime734.jsxs)(
2275
2384
  Box,
2276
2385
  {
2277
2386
  ref,
@@ -2280,7 +2389,7 @@ var MultiSelect = (0, import_react10.forwardRef)(
2280
2389
  ...externalFieldLayout ? { width: "100%" } : {}
2281
2390
  },
2282
2391
  children: [
2283
- /* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
2392
+ /* @__PURE__ */ (0, import_jsx_runtime734.jsx)(
2284
2393
  MultiSelectControl,
2285
2394
  {
2286
2395
  ref: controlRef,
@@ -2305,88 +2414,11 @@ var MultiSelect = (0, import_react10.forwardRef)(
2305
2414
  extraClear
2306
2415
  }
2307
2416
  ),
2308
- dropdownMenu && isOpen && !isDisable && /* @__PURE__ */ (0, import_jsx_runtime733.jsxs)(import_jsx_runtime733.Fragment, { children: [
2309
- /* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
2310
- Box,
2311
- {
2312
- style: {
2313
- position: "fixed",
2314
- top: 0,
2315
- left: 0,
2316
- right: 0,
2317
- bottom: 0,
2318
- zIndex: 999,
2319
- cursor: "default"
2320
- },
2321
- onPress: onClose
2322
- }
2323
- ),
2324
- /* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
2325
- Box,
2326
- {
2327
- ref: menuRef,
2328
- backgroundColor: theme.colors.background.secondary,
2329
- borderColor: theme.colors.border.secondary,
2330
- borderWidth: 1,
2331
- borderRadius: theme.shape.input[size].borderRadius,
2332
- paddingVertical: 4,
2333
- style: {
2334
- position: "absolute",
2335
- top: "100%",
2336
- left: 0,
2337
- right: 0,
2338
- marginTop: 4,
2339
- zIndex: 1001,
2340
- // Above control (1000) and backdrop (999)
2341
- boxShadow: theme.shadow.popover,
2342
- maxHeight,
2343
- overflowY: "auto"
2344
- },
2345
- children: menuItems.map((item, _index) => {
2346
- const brandColors = theme.colors.control.brand.primary;
2347
- const contentColors = theme.colors.content;
2348
- return /* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
2349
- Box,
2350
- {
2351
- testID,
2352
- paddingHorizontal: sizeStyles.paddingHorizontal,
2353
- paddingVertical: 8,
2354
- onPress: () => {
2355
- if (!item.disabled) {
2356
- handleItemToggle(item.id, !item.checked);
2357
- }
2358
- },
2359
- flexDirection: "row",
2360
- alignItems: "center",
2361
- justifyContent: "space-between",
2362
- backgroundColor: item.checked ? brandColors.bg : "transparent",
2363
- hoverStyle: !item.disabled && !item.checked ? {
2364
- backgroundColor: theme.colors.control.input.bgHover
2365
- } : void 0,
2366
- style: {
2367
- cursor: item.disabled ? "not-allowed" : "pointer",
2368
- opacity: item.disabled ? 0.5 : 1
2369
- },
2370
- children: /* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
2371
- Text,
2372
- {
2373
- color: item.checked ? contentColors.on.brand : theme.colors.content.secondary,
2374
- fontSize: sizeStyles.fontSize,
2375
- fontWeight: "400",
2376
- children: item.children
2377
- }
2378
- )
2379
- },
2380
- item.id
2381
- );
2382
- })
2383
- }
2384
- )
2385
- ] })
2417
+ isWeb ? /* @__PURE__ */ (0, import_jsx_runtime734.jsx)(Portal, { children: dropdown }) : dropdown
2386
2418
  ]
2387
2419
  }
2388
2420
  ),
2389
- errorMessage && /* @__PURE__ */ (0, import_jsx_runtime733.jsx)(
2421
+ errorMessage && /* @__PURE__ */ (0, import_jsx_runtime734.jsx)(
2390
2422
  Text,
2391
2423
  {
2392
2424
  color: theme.colors.content.alert.primary,