@ecohouse/ui 0.1.53 → 0.1.55

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/dist/index.cjs CHANGED
@@ -27561,7 +27561,7 @@ var require_react_dom_development = __commonJS({
27561
27561
  return root2;
27562
27562
  }
27563
27563
  var ReactVersion = "18.3.1";
27564
- function createPortal3(children, containerInfo, implementation) {
27564
+ function createPortal4(children, containerInfo, implementation) {
27565
27565
  var key = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : null;
27566
27566
  {
27567
27567
  checkKeyStringCoercion(key);
@@ -28417,7 +28417,7 @@ var require_react_dom_development = __commonJS({
28417
28417
  if (!isValidContainer(container)) {
28418
28418
  throw new Error("Target container is not a DOM element.");
28419
28419
  }
28420
- return createPortal3(children, container, null, key);
28420
+ return createPortal4(children, container, null, key);
28421
28421
  }
28422
28422
  function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
28423
28423
  return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback);
@@ -28541,9 +28541,10 @@ var colors = {
28541
28541
  whiteAlpha40: "#FFFFFF66",
28542
28542
  whiteAlpha20: "#FFFFFF33",
28543
28543
  whiteAlpha1: "#FFFFFF03",
28544
+ whiteAlpha5: "#FFFFFF0D",
28544
28545
  whiteAlpha6: "#FFFFFF0F",
28546
+ whiteAlpha7: "#FFFFFF12",
28545
28547
  whiteAlpha10: "#FFFFFF1A",
28546
- whiteAlpha5: "#FFFFFF0D",
28547
28548
  dark: "#090909",
28548
28549
  red: "#A63E3E",
28549
28550
  lightGrey: "#B7B7B7",
@@ -31301,10 +31302,19 @@ function BrandLogo({
31301
31302
  );
31302
31303
  }
31303
31304
  var IMAGE_SIZE = 48;
31305
+ var CONTAINER_HEIGHT = 56;
31304
31306
  var CONTAINER_RADIUS = 71;
31305
31307
  var CHEVRON_SIZE = 20;
31306
31308
  var FALLBACK_ICON_SIZE = 20;
31307
31309
  var MENU_RADIUS = 16;
31310
+ var triggerWebBlurStyle = reactNative.Platform.OS === "web" ? {
31311
+ backdropFilter: "blur(40px)",
31312
+ WebkitBackdropFilter: "blur(40px)"
31313
+ } : {};
31314
+ var menuWebBlurStyle = reactNative.Platform.OS === "web" ? {
31315
+ backdropFilter: "blur(40px)",
31316
+ WebkitBackdropFilter: "blur(40px)"
31317
+ } : {};
31308
31318
  var Avatar = react.forwardRef(function Avatar2({
31309
31319
  name,
31310
31320
  email,
@@ -31312,6 +31322,7 @@ var Avatar = react.forwardRef(function Avatar2({
31312
31322
  onPress,
31313
31323
  disabled = false,
31314
31324
  showChevron = true,
31325
+ variant = "light",
31315
31326
  menuItems,
31316
31327
  open: openProp,
31317
31328
  defaultOpen = false,
@@ -31333,6 +31344,7 @@ var Avatar = react.forwardRef(function Avatar2({
31333
31344
  const isOpenControlled = typeof openProp === "boolean";
31334
31345
  const [uncontrolledOpen, setUncontrolledOpen] = react.useState(defaultOpen);
31335
31346
  const isOpen = hasMenu && (isOpenControlled ? openProp : uncontrolledOpen);
31347
+ const isLightVariant = variant === "light";
31336
31348
  useApplyWebClassName(containerRef, className);
31337
31349
  const setOpen = react.useCallback(
31338
31350
  (next) => {
@@ -31402,7 +31414,13 @@ var Avatar = react.forwardRef(function Avatar2({
31402
31414
  accessibilityRole: isInteractive ? "button" : void 0,
31403
31415
  accessibilityLabel: resolvedAccessibilityLabel,
31404
31416
  accessibilityState: isInteractive ? { disabled, expanded: hasMenu ? isOpen : void 0 } : void 0,
31405
- style: [styles6.root, disabled && styles6.disabled, style],
31417
+ style: [
31418
+ styles6.root,
31419
+ isLightVariant ? styles6.rootLight : styles6.rootDark,
31420
+ isLightVariant && triggerWebBlurStyle,
31421
+ disabled && styles6.disabled,
31422
+ style
31423
+ ],
31406
31424
  children: [
31407
31425
  /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles6.imageWrap, children: hasImage ? /* @__PURE__ */ jsxRuntime.jsx(
31408
31426
  reactNative.Image,
@@ -31411,30 +31429,71 @@ var Avatar = react.forwardRef(function Avatar2({
31411
31429
  style: styles6.image,
31412
31430
  onError: () => setImageFailed(true)
31413
31431
  }
31414
- ) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles6.imageFallback, children: /* @__PURE__ */ jsxRuntime.jsx(UserIcon, { size: FALLBACK_ICON_SIZE, color: colors.primary }) }) }),
31432
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
31433
+ reactNative.View,
31434
+ {
31435
+ style: [
31436
+ styles6.imageFallback,
31437
+ isLightVariant ? styles6.imageFallbackLight : styles6.imageFallbackDark
31438
+ ],
31439
+ children: /* @__PURE__ */ jsxRuntime.jsx(
31440
+ UserIcon,
31441
+ {
31442
+ size: FALLBACK_ICON_SIZE,
31443
+ color: isLightVariant ? colors.white : colors.primary
31444
+ }
31445
+ )
31446
+ }
31447
+ ) }),
31415
31448
  /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles6.textColumn, children: [
31416
31449
  /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles6.name, numberOfLines: 1, children: name }),
31417
- email ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles6.email, numberOfLines: 1, children: email }) : null
31450
+ email ? /* @__PURE__ */ jsxRuntime.jsx(
31451
+ reactNative.Text,
31452
+ {
31453
+ style: [styles6.email, isLightVariant ? styles6.emailLight : styles6.emailDark],
31454
+ numberOfLines: 1,
31455
+ children: email
31456
+ }
31457
+ ) : null
31418
31458
  ] }),
31419
- showChevron ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles6.chevronSlot, isOpen && styles6.chevronOpen], children: /* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon, { size: CHEVRON_SIZE, color: isOpen ? colors.primary : colors.grey100 }) }) : null
31459
+ showChevron ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles6.chevronSlot, isOpen && styles6.chevronOpen], children: /* @__PURE__ */ jsxRuntime.jsx(
31460
+ ChevronDownIcon,
31461
+ {
31462
+ size: CHEVRON_SIZE,
31463
+ color: isLightVariant ? colors.white : isOpen ? colors.primary : colors.grey100
31464
+ }
31465
+ ) }) : null
31420
31466
  ]
31421
31467
  }
31422
31468
  ),
31423
- hasMenu && isOpen ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles6.menu, menuWidth != null && { right: void 0, width: menuWidth }], children: resolvedMenuItems.map((item) => {
31424
- const itemKey = item.key ?? item.label;
31425
- return /* @__PURE__ */ jsxRuntime.jsx(
31426
- MenuItem,
31427
- {
31428
- icon: item.icon,
31429
- label: item.label,
31430
- disabled: item.disabled,
31431
- backgroundColor: item.backgroundColor,
31432
- hoverColor: item.hoverColor,
31433
- onPress: () => handleItemPress(item)
31434
- },
31435
- itemKey
31436
- );
31437
- }) }) : null
31469
+ hasMenu && isOpen ? /* @__PURE__ */ jsxRuntime.jsx(
31470
+ reactNative.View,
31471
+ {
31472
+ style: [
31473
+ styles6.menu,
31474
+ isLightVariant ? styles6.menuLight : styles6.menuDark,
31475
+ isLightVariant && menuWebBlurStyle,
31476
+ menuWidth != null && { right: void 0, width: menuWidth }
31477
+ ],
31478
+ children: resolvedMenuItems.map((item) => {
31479
+ const itemKey = item.key ?? item.label;
31480
+ return /* @__PURE__ */ jsxRuntime.jsx(
31481
+ MenuItem,
31482
+ {
31483
+ icon: item.icon,
31484
+ label: item.label,
31485
+ disabled: item.disabled,
31486
+ backgroundColor: item.backgroundColor,
31487
+ hoverColor: item.hoverColor ?? (isLightVariant ? colors.whiteAlpha7 : void 0),
31488
+ labelStyle: item.labelStyle,
31489
+ onPress: () => handleItemPress(item),
31490
+ style: isLightVariant ? item.backgroundColor ? styles6.emphasizedMenuItem : styles6.menuItem : void 0
31491
+ },
31492
+ itemKey
31493
+ );
31494
+ })
31495
+ }
31496
+ ) : null
31438
31497
  ] });
31439
31498
  });
31440
31499
  var styles6 = reactNative.StyleSheet.create({
@@ -31446,6 +31505,7 @@ var styles6 = reactNative.StyleSheet.create({
31446
31505
  zIndex: 20
31447
31506
  },
31448
31507
  root: {
31508
+ height: CONTAINER_HEIGHT,
31449
31509
  flexDirection: "row",
31450
31510
  alignItems: "center",
31451
31511
  alignSelf: "flex-start",
@@ -31454,7 +31514,12 @@ var styles6 = reactNative.StyleSheet.create({
31454
31514
  paddingBottom: 4,
31455
31515
  paddingLeft: 4,
31456
31516
  paddingRight: 12,
31457
- borderRadius: CONTAINER_RADIUS,
31517
+ borderRadius: CONTAINER_RADIUS
31518
+ },
31519
+ rootLight: {
31520
+ backgroundColor: colors.whiteAlpha5
31521
+ },
31522
+ rootDark: {
31458
31523
  backgroundColor: colors.grey700
31459
31524
  },
31460
31525
  disabled: {
@@ -31475,7 +31540,15 @@ var styles6 = reactNative.StyleSheet.create({
31475
31540
  width: IMAGE_SIZE,
31476
31541
  height: IMAGE_SIZE,
31477
31542
  alignItems: "center",
31478
- justifyContent: "center",
31543
+ justifyContent: "center"
31544
+ },
31545
+ imageFallbackLight: {
31546
+ borderRadius: IMAGE_SIZE / 2,
31547
+ backgroundColor: "transparent",
31548
+ borderWidth: 1,
31549
+ borderColor: colors.whiteAlpha10
31550
+ },
31551
+ imageFallbackDark: {
31479
31552
  backgroundColor: colors.grey600
31480
31553
  },
31481
31554
  textColumn: {
@@ -31488,7 +31561,12 @@ var styles6 = reactNative.StyleSheet.create({
31488
31561
  color: colors.white
31489
31562
  },
31490
31563
  email: {
31491
- ...avatarTypography.email,
31564
+ ...avatarTypography.email
31565
+ },
31566
+ emailLight: {
31567
+ color: colors.whiteAlpha60
31568
+ },
31569
+ emailDark: {
31492
31570
  color: colors.grey0
31493
31571
  },
31494
31572
  chevronSlot: {
@@ -31510,7 +31588,15 @@ var styles6 = reactNative.StyleSheet.create({
31510
31588
  zIndex: 10,
31511
31589
  borderRadius: MENU_RADIUS,
31512
31590
  padding: 8,
31513
- gap: 8,
31591
+ gap: 8
31592
+ },
31593
+ menuLight: {
31594
+ borderWidth: 1,
31595
+ borderColor: colors.whiteAlpha10,
31596
+ backgroundColor: colors.whiteAlpha5,
31597
+ overflow: "hidden"
31598
+ },
31599
+ menuDark: {
31514
31600
  backgroundColor: colors.grey700,
31515
31601
  ...reactNative.Platform.select({
31516
31602
  web: {
@@ -31520,6 +31606,16 @@ var styles6 = reactNative.StyleSheet.create({
31520
31606
  elevation: 8
31521
31607
  }
31522
31608
  })
31609
+ },
31610
+ menuItem: {
31611
+ height: 32,
31612
+ minHeight: 32,
31613
+ paddingVertical: 6
31614
+ },
31615
+ emphasizedMenuItem: {
31616
+ height: 46,
31617
+ minHeight: 46,
31618
+ paddingVertical: 11
31523
31619
  }
31524
31620
  });
31525
31621
  var IMAGE_SIZE2 = 32;
@@ -33529,6 +33625,7 @@ var defaultLanguageOptions = [
33529
33625
  ];
33530
33626
  var CONTROL_WIDTH = 96;
33531
33627
  var CONTROL_HEIGHT = 35;
33628
+ var MENU_WIDTH = 90;
33532
33629
  var ICON_SIZE9 = 16;
33533
33630
  var ICON_BUTTON_SIZE2 = 32;
33534
33631
  var ICON_MENU_WIDTH = 67;
@@ -33536,6 +33633,10 @@ var ICON_MENU_HEIGHT = 129;
33536
33633
  var ICON_MENU_TOP = 39;
33537
33634
  var ITEM_HEIGHT = 35;
33538
33635
  var ACTIVE_ITEM_BACKGROUND = "#E38E5E12";
33636
+ var menuWebBlurStyle2 = reactNative.Platform.OS === "web" ? {
33637
+ backdropFilter: "blur(40px)",
33638
+ WebkitBackdropFilter: "blur(40px)"
33639
+ } : {};
33539
33640
  var LanguageSwitcher = react.forwardRef(
33540
33641
  function LanguageSwitcher2({
33541
33642
  options = defaultLanguageOptions,
@@ -33640,7 +33741,7 @@ var LanguageSwitcher = react.forwardRef(
33640
33741
  onHoverOut: () => setTriggerHovered(false),
33641
33742
  style: ({ pressed }) => [
33642
33743
  isIconVariant ? styles22.triggerIcon : styles22.trigger,
33643
- !isIconVariant && (triggerHovered || pressed || isOpen) && styles22.triggerActive
33744
+ !isIconVariant && (triggerHovered || pressed) && styles22.triggerActive
33644
33745
  ],
33645
33746
  children: [
33646
33747
  /* @__PURE__ */ jsxRuntime.jsx(GlobeIcon, { size: ICON_SIZE9, color: colors.white, strokeWidth: isIconVariant ? 1.5 : 2 }),
@@ -33654,7 +33755,11 @@ var LanguageSwitcher = react.forwardRef(
33654
33755
  isOpen && options.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
33655
33756
  reactNative.View,
33656
33757
  {
33657
- style: [styles22.menu, isIconVariant ? styles22.menuIcon : styles22.menuDefault],
33758
+ style: [
33759
+ styles22.menu,
33760
+ !isIconVariant && menuWebBlurStyle2,
33761
+ isIconVariant ? styles22.menuIcon : styles22.menuDefault
33762
+ ],
33658
33763
  accessibilityRole: "menu",
33659
33764
  children: options.map((option) => {
33660
33765
  const selected = option.value === selectedValue;
@@ -33669,15 +33774,15 @@ var LanguageSwitcher = react.forwardRef(
33669
33774
  onHoverOut: () => setHoveredValue(null),
33670
33775
  style: ({ pressed }) => [
33671
33776
  styles22.item,
33672
- isIconVariant ? styles22.itemIcon : null,
33777
+ isIconVariant ? styles22.itemIcon : styles22.itemDefault,
33673
33778
  selected ? isIconVariant ? styles22.itemSelectedIcon : styles22.itemSelected : (hoveredValue === option.value || pressed) && styles22.itemHovered
33674
33779
  ],
33675
- children: /* @__PURE__ */ jsxRuntime.jsx(
33780
+ children: ({ pressed }) => /* @__PURE__ */ jsxRuntime.jsx(
33676
33781
  reactNative.Text,
33677
33782
  {
33678
33783
  style: [
33679
33784
  styles22.itemLabel,
33680
- selected && (isIconVariant ? styles22.itemLabelSelectedIcon : styles22.itemLabelSelected)
33785
+ (selected || hoveredValue === option.value || pressed) && styles22.itemLabelActive
33681
33786
  ],
33682
33787
  children: option.label
33683
33788
  }
@@ -33762,10 +33867,14 @@ var styles22 = reactNative.StyleSheet.create({
33762
33867
  },
33763
33868
  menuDefault: {
33764
33869
  top: CONTROL_HEIGHT + 8,
33765
- left: 0,
33766
- width: CONTROL_WIDTH,
33767
- gap: 8,
33768
- backgroundColor: colors.whiteAlpha6
33870
+ left: (CONTROL_WIDTH - MENU_WIDTH) / 2,
33871
+ width: MENU_WIDTH,
33872
+ height: 129,
33873
+ gap: 4,
33874
+ backgroundColor: colors.whiteAlpha5,
33875
+ borderWidth: 1,
33876
+ borderColor: colors.whiteAlpha10,
33877
+ borderRadius: 16
33769
33878
  },
33770
33879
  menuIcon: {
33771
33880
  top: ICON_MENU_TOP,
@@ -33793,11 +33902,15 @@ var styles22 = reactNative.StyleSheet.create({
33793
33902
  width: 51,
33794
33903
  alignSelf: "stretch"
33795
33904
  },
33905
+ itemDefault: {
33906
+ width: 74,
33907
+ alignSelf: "center"
33908
+ },
33796
33909
  itemHovered: {
33797
- backgroundColor: colors.whiteAlpha6
33910
+ backgroundColor: colors.whiteAlpha7
33798
33911
  },
33799
33912
  itemSelected: {
33800
- backgroundColor: colors.whiteAlpha6
33913
+ backgroundColor: colors.whiteAlpha7
33801
33914
  },
33802
33915
  itemSelectedIcon: {
33803
33916
  backgroundColor: ACTIVE_ITEM_BACKGROUND
@@ -33805,13 +33918,10 @@ var styles22 = reactNative.StyleSheet.create({
33805
33918
  itemLabel: {
33806
33919
  ...languageSwitcherTypography,
33807
33920
  ...reactNative.Platform.select({ web: { fontFamily: `${fonts.sans}, sans-serif` } }),
33808
- color: colors.white
33809
- },
33810
- itemLabelSelected: {
33811
- color: colors.primary
33921
+ color: colors.whiteAlpha60
33812
33922
  },
33813
- itemLabelSelectedIcon: {
33814
- color: colors.primary
33923
+ itemLabelActive: {
33924
+ color: colors.white
33815
33925
  }
33816
33926
  });
33817
33927
  var ICON_SIZE10 = 25.63181;
@@ -36214,6 +36324,9 @@ var styles32 = reactNative.StyleSheet.create({
36214
36324
  color: colors.red
36215
36325
  }
36216
36326
  });
36327
+
36328
+ // src/components/Select/Select.tsx
36329
+ var import_react_dom3 = __toESM(require_react_dom());
36217
36330
  var DEFAULT_WIDTH4 = 308;
36218
36331
  var TRIGGER_HEIGHT2 = 44;
36219
36332
  var TRIGGER_RADIUS2 = 60;
@@ -36223,6 +36336,9 @@ var ITEM_RADIUS2 = 12;
36223
36336
  var ICON_SIZE13 = 20;
36224
36337
  var CHIP_GAP = 6;
36225
36338
  var FALLBACK_ELLIPSIS_WIDTH = 20;
36339
+ var WEB_MENU_Z_INDEX = 600;
36340
+ var WEB_VIEWPORT_PADDING = 8;
36341
+ var WEB_MENU_GAP = 8;
36226
36342
  function itemBackground(state) {
36227
36343
  switch (state) {
36228
36344
  case "hover":
@@ -36369,6 +36485,7 @@ var Select = react.forwardRef(
36369
36485
  const valueProp = props.value;
36370
36486
  const rootRef = react.useRef(null);
36371
36487
  const triggerRef = react.useRef(null);
36488
+ const menuRef = react.useRef(null);
36372
36489
  const searchInputRef = react.useRef(null);
36373
36490
  const setRootRef = react.useMemo(() => mergeRefs(rootRef, forwardedRef), [forwardedRef]);
36374
36491
  const isOpenControlled = typeof openProp === "boolean";
@@ -36384,6 +36501,7 @@ var Select = react.forwardRef(
36384
36501
  const [hoveredValue, setHoveredValue] = react.useState(null);
36385
36502
  const [menuAlignEnd, setMenuAlignEnd] = react.useState(false);
36386
36503
  const [menuPlaceAbove, setMenuPlaceAbove] = react.useState(false);
36504
+ const [webMenuPosition, setWebMenuPosition] = react.useState(null);
36387
36505
  const selectedValues = react.useMemo(() => {
36388
36506
  const current = isValueControlled ? valueProp : multiple ? uncontrolledMultiple : uncontrolledSingle;
36389
36507
  return toArray(current);
@@ -36437,6 +36555,7 @@ var Select = react.forwardRef(
36437
36555
  setHoveredValue(null);
36438
36556
  setMenuAlignEnd(false);
36439
36557
  setMenuPlaceAbove(false);
36558
+ setWebMenuPosition(null);
36440
36559
  onSearchChange?.("");
36441
36560
  }
36442
36561
  },
@@ -36448,15 +36567,18 @@ var Select = react.forwardRef(
36448
36567
  const trigger = triggerRef.current;
36449
36568
  const rect = trigger?.getBoundingClientRect?.();
36450
36569
  if (!rect) return;
36451
- const viewportPadding = 8;
36452
- const gap = 8;
36453
36570
  const menuWidth = Math.max(rect.width, resolvedMenuWidth ?? 0);
36454
- const overflowsRight = rect.left + menuWidth > window.innerWidth - viewportPadding;
36571
+ const overflowsRight = rect.left + menuWidth > window.innerWidth - WEB_VIEWPORT_PADDING;
36455
36572
  setMenuAlignEnd(overflowsRight);
36456
- const spaceBelow = window.innerHeight - viewportPadding - rect.bottom;
36457
- const spaceAbove = rect.top - viewportPadding;
36458
- const needsAbove = estimatedMenuHeight + gap > spaceBelow && spaceAbove > spaceBelow;
36573
+ const spaceBelow = window.innerHeight - WEB_VIEWPORT_PADDING - rect.bottom;
36574
+ const spaceAbove = rect.top - WEB_VIEWPORT_PADDING;
36575
+ const needsAbove = estimatedMenuHeight + WEB_MENU_GAP > spaceBelow && spaceAbove > spaceBelow;
36459
36576
  setMenuPlaceAbove(needsAbove);
36577
+ const available = Math.max(0, (needsAbove ? spaceAbove : spaceBelow) - WEB_MENU_GAP);
36578
+ const maxHeight = Math.min(estimatedMenuHeight, Math.max(available, TRIGGER_HEIGHT2));
36579
+ const left = overflowsRight ? Math.max(WEB_VIEWPORT_PADDING, rect.right - menuWidth) : Math.min(rect.left, window.innerWidth - WEB_VIEWPORT_PADDING - menuWidth);
36580
+ const top = needsAbove ? Math.max(WEB_VIEWPORT_PADDING, rect.top - WEB_MENU_GAP - maxHeight) : rect.bottom + WEB_MENU_GAP;
36581
+ setWebMenuPosition({ top, left, width: menuWidth, maxHeight });
36460
36582
  };
36461
36583
  updateMenuPlacement();
36462
36584
  window.addEventListener("resize", updateMenuPlacement);
@@ -36473,11 +36595,12 @@ var Select = react.forwardRef(
36473
36595
  react.useEffect(() => {
36474
36596
  if (reactNative.Platform.OS !== "web" || !isOpen) return;
36475
36597
  const handlePointerDown = (event) => {
36476
- const root = rootRef.current;
36477
36598
  const target = event.target;
36478
- if (root?.contains && target instanceof Node && !root.contains(target)) {
36479
- setOpen(false);
36480
- }
36599
+ if (!(target instanceof Node)) return;
36600
+ const root = rootRef.current;
36601
+ const menu = menuRef.current;
36602
+ if (root?.contains?.(target) || menu?.contains?.(target)) return;
36603
+ setOpen(false);
36481
36604
  };
36482
36605
  document.addEventListener("mousedown", handlePointerDown);
36483
36606
  document.addEventListener("touchstart", handlePointerDown);
@@ -36591,7 +36714,7 @@ var Select = react.forwardRef(
36591
36714
  ]);
36592
36715
  const leftIconNode = renderStatefulIcon(leftIcon, UserIcon, {
36593
36716
  size: ICON_SIZE13,
36594
- color: error ? colors.red : colors.primary
36717
+ color: error ? colors.red : isOpen ? colors.primary : colors.grey100
36595
36718
  });
36596
36719
  const hasLeftIcon = showLeftIcon || leftIcon != null;
36597
36720
  const triggerBorderColor = error ? colors.redMuted : isOpen ? colors.primaryMuted : colors.grey700;
@@ -36600,6 +36723,95 @@ var Select = react.forwardRef(
36600
36723
  const hintColor = error ? colors.red : colors.grey100;
36601
36724
  const singleLabel = selectedOptions[0]?.label ?? placeholder;
36602
36725
  const resolvedAccessibilityLabel = accessibilityLabel ?? (typeof label === "string" ? label : void 0);
36726
+ const optionListMaxHeight = reactNative.Platform.OS === "web" && webMenuPosition != null ? Math.max(43, webMenuPosition.maxHeight - (24 + (showSearch ? 48 : 0))) : resolvedOptionListMaxHeight;
36727
+ const menuNode = isOpen ? /* @__PURE__ */ jsxRuntime.jsxs(
36728
+ reactNative.View,
36729
+ {
36730
+ ref: menuRef,
36731
+ style: [
36732
+ styles33.menu,
36733
+ reactNative.Platform.OS === "web" && webMenuPosition != null ? {
36734
+ position: "fixed",
36735
+ top: webMenuPosition.top,
36736
+ left: webMenuPosition.left,
36737
+ width: webMenuPosition.width,
36738
+ minWidth: webMenuPosition.width,
36739
+ maxHeight: webMenuPosition.maxHeight,
36740
+ zIndex: WEB_MENU_Z_INDEX,
36741
+ marginTop: 0,
36742
+ marginBottom: 0
36743
+ } : reactNative.Platform.OS === "web" ? { position: "fixed", opacity: 0, pointerEvents: "none" } : [
36744
+ menuAlignEnd ? styles33.menuAlignEnd : styles33.menuAlignStart,
36745
+ menuPlaceAbove ? styles33.menuAbove : styles33.menuBelow
36746
+ ],
36747
+ menuStyle
36748
+ ],
36749
+ children: [
36750
+ showSearch ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles33.searchField, children: [
36751
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles33.iconSlot, children: /* @__PURE__ */ jsxRuntime.jsx(SearchIcon, { size: ICON_SIZE13, color: colors.grey100 }) }),
36752
+ /* @__PURE__ */ jsxRuntime.jsx(
36753
+ reactNative.TextInput,
36754
+ {
36755
+ ref: searchInputRef,
36756
+ value: searchQuery,
36757
+ onChangeText: handleSearchChange,
36758
+ editable: !disabled,
36759
+ placeholder: searchPlaceholder,
36760
+ placeholderTextColor: colors.grey100,
36761
+ style: [
36762
+ styles33.searchInput,
36763
+ reactNative.Platform.OS === "web" ? styles33.searchInputWeb : null,
36764
+ reactNative.Platform.OS === "android" ? styles33.searchInputAndroid : null
36765
+ ],
36766
+ accessibilityLabel: searchPlaceholder
36767
+ }
36768
+ )
36769
+ ] }) : null,
36770
+ /* @__PURE__ */ jsxRuntime.jsxs(
36771
+ reactNative.ScrollView,
36772
+ {
36773
+ style: [styles33.optionList, { maxHeight: optionListMaxHeight }],
36774
+ contentContainerStyle: styles33.optionListContent,
36775
+ keyboardShouldPersistTaps: "handled",
36776
+ showsVerticalScrollIndicator: false,
36777
+ children: [
36778
+ loading ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles33.statusRow, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles33.statusText, children: "Loading..." }) }) : filteredOptions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles33.statusRow, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles33.statusText, children: emptyText }) }) : null,
36779
+ !loading && filteredOptions.map((option) => {
36780
+ const isSelected = selectedValues.includes(option.value);
36781
+ const isHovered = hoveredValue === option.value;
36782
+ const visualState = isSelected ? "selected" : isHovered ? "hover" : "default";
36783
+ return /* @__PURE__ */ jsxRuntime.jsxs(
36784
+ reactNative.Pressable,
36785
+ {
36786
+ onPress: () => handleSelect(option.value),
36787
+ disabled,
36788
+ onHoverIn: () => setHoveredValue(option.value),
36789
+ onHoverOut: () => setHoveredValue((current) => current === option.value ? null : current),
36790
+ onPressIn: () => setHoveredValue(option.value),
36791
+ onPressOut: () => setHoveredValue((current) => current === option.value ? null : current),
36792
+ accessibilityRole: multiple ? "checkbox" : "button",
36793
+ accessibilityState: { selected: isSelected, checked: isSelected, disabled },
36794
+ style: [
36795
+ styles33.item,
36796
+ {
36797
+ backgroundColor: itemBackground(visualState)
36798
+ }
36799
+ ],
36800
+ children: [
36801
+ multiple ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles33.itemCheckbox, { pointerEvents: "none" }], children: /* @__PURE__ */ jsxRuntime.jsx(Checkbox, { value: isSelected, variant: "light" }) }) : null,
36802
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles33.itemLabel, numberOfLines: 1, children: option.label })
36803
+ ]
36804
+ },
36805
+ option.value
36806
+ );
36807
+ })
36808
+ ]
36809
+ }
36810
+ )
36811
+ ]
36812
+ }
36813
+ ) : null;
36814
+ const webMenuPortal = reactNative.Platform.OS === "web" && isOpen && typeof document !== "undefined" ? (0, import_react_dom3.createPortal)(menuNode, document.body) : null;
36603
36815
  return /* @__PURE__ */ jsxRuntime.jsxs(
36604
36816
  reactNative.View,
36605
36817
  {
@@ -36640,80 +36852,7 @@ var Select = react.forwardRef(
36640
36852
  ]
36641
36853
  }
36642
36854
  ),
36643
- isOpen ? /* @__PURE__ */ jsxRuntime.jsxs(
36644
- reactNative.View,
36645
- {
36646
- style: [
36647
- styles33.menu,
36648
- menuAlignEnd ? styles33.menuAlignEnd : styles33.menuAlignStart,
36649
- menuPlaceAbove ? styles33.menuAbove : styles33.menuBelow,
36650
- menuStyle
36651
- ],
36652
- children: [
36653
- showSearch ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles33.searchField, children: [
36654
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles33.iconSlot, children: /* @__PURE__ */ jsxRuntime.jsx(SearchIcon, { size: ICON_SIZE13, color: colors.grey100 }) }),
36655
- /* @__PURE__ */ jsxRuntime.jsx(
36656
- reactNative.TextInput,
36657
- {
36658
- ref: searchInputRef,
36659
- value: searchQuery,
36660
- onChangeText: handleSearchChange,
36661
- editable: !disabled,
36662
- placeholder: searchPlaceholder,
36663
- placeholderTextColor: colors.grey100,
36664
- style: [
36665
- styles33.searchInput,
36666
- reactNative.Platform.OS === "web" ? styles33.searchInputWeb : null,
36667
- reactNative.Platform.OS === "android" ? styles33.searchInputAndroid : null
36668
- ],
36669
- accessibilityLabel: searchPlaceholder
36670
- }
36671
- )
36672
- ] }) : null,
36673
- /* @__PURE__ */ jsxRuntime.jsxs(
36674
- reactNative.ScrollView,
36675
- {
36676
- style: [styles33.optionList, { maxHeight: resolvedOptionListMaxHeight }],
36677
- contentContainerStyle: styles33.optionListContent,
36678
- keyboardShouldPersistTaps: "handled",
36679
- showsVerticalScrollIndicator: false,
36680
- children: [
36681
- loading ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles33.statusRow, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles33.statusText, children: "Loading..." }) }) : filteredOptions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles33.statusRow, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles33.statusText, children: emptyText }) }) : null,
36682
- !loading && filteredOptions.map((option) => {
36683
- const isSelected = selectedValues.includes(option.value);
36684
- const isHovered = hoveredValue === option.value;
36685
- const visualState = isSelected ? "selected" : isHovered ? "hover" : "default";
36686
- return /* @__PURE__ */ jsxRuntime.jsxs(
36687
- reactNative.Pressable,
36688
- {
36689
- onPress: () => handleSelect(option.value),
36690
- disabled,
36691
- onHoverIn: () => setHoveredValue(option.value),
36692
- onHoverOut: () => setHoveredValue((current) => current === option.value ? null : current),
36693
- onPressIn: () => setHoveredValue(option.value),
36694
- onPressOut: () => setHoveredValue((current) => current === option.value ? null : current),
36695
- accessibilityRole: multiple ? "checkbox" : "button",
36696
- accessibilityState: { selected: isSelected, checked: isSelected, disabled },
36697
- style: [
36698
- styles33.item,
36699
- {
36700
- backgroundColor: itemBackground(visualState)
36701
- }
36702
- ],
36703
- children: [
36704
- multiple ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles33.itemCheckbox, { pointerEvents: "none" }], children: /* @__PURE__ */ jsxRuntime.jsx(Checkbox, { value: isSelected, variant: "light" }) }) : null,
36705
- /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles33.itemLabel, numberOfLines: 1, children: option.label })
36706
- ]
36707
- },
36708
- option.value
36709
- );
36710
- })
36711
- ]
36712
- }
36713
- )
36714
- ]
36715
- }
36716
- ) : null
36855
+ reactNative.Platform.OS === "web" ? webMenuPortal : menuNode
36717
36856
  ] }),
36718
36857
  showHint && hint ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles33.hint, { color: hintColor }], children: hint }) : null
36719
36858
  ]