@ecohouse/ui 0.1.52 → 0.1.54

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.d.cts CHANGED
@@ -958,6 +958,15 @@ type DatePickerBaseProps = Omit<ViewProps, "style" | "children"> & {
958
958
  closeOnSelect?: boolean;
959
959
  minDate?: Date;
960
960
  maxDate?: Date;
961
+ /** Calendar days that cannot be selected, such as dates already booked. */
962
+ unavailableDates?: readonly Date[];
963
+ /**
964
+ * When true, unavailable days cannot be selected and a range cannot include them.
965
+ * Defaults to false so booked days can stay visual-only.
966
+ */
967
+ blockUnavailableDates?: boolean;
968
+ /** Accessibility label for an unavailable day. */
969
+ unavailableDateLabel?: string;
961
970
  /** First visible month when the calendar opens; defaults to the selected value's month, else today. */
962
971
  defaultVisibleMonth?: Date;
963
972
  /** Monday-first full month names. Defaults to Armenian. */
package/dist/index.d.ts CHANGED
@@ -958,6 +958,15 @@ type DatePickerBaseProps = Omit<ViewProps, "style" | "children"> & {
958
958
  closeOnSelect?: boolean;
959
959
  minDate?: Date;
960
960
  maxDate?: Date;
961
+ /** Calendar days that cannot be selected, such as dates already booked. */
962
+ unavailableDates?: readonly Date[];
963
+ /**
964
+ * When true, unavailable days cannot be selected and a range cannot include them.
965
+ * Defaults to false so booked days can stay visual-only.
966
+ */
967
+ blockUnavailableDates?: boolean;
968
+ /** Accessibility label for an unavailable day. */
969
+ unavailableDateLabel?: string;
961
970
  /** First visible month when the calendar opens; defaults to the selected value's month, else today. */
962
971
  defaultVisibleMonth?: Date;
963
972
  /** Monday-first full month names. Defaults to Armenian. */
package/dist/index.js CHANGED
@@ -27555,7 +27555,7 @@ var require_react_dom_development = __commonJS({
27555
27555
  return root2;
27556
27556
  }
27557
27557
  var ReactVersion = "18.3.1";
27558
- function createPortal3(children, containerInfo, implementation) {
27558
+ function createPortal4(children, containerInfo, implementation) {
27559
27559
  var key = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : null;
27560
27560
  {
27561
27561
  checkKeyStringCoercion(key);
@@ -28411,7 +28411,7 @@ var require_react_dom_development = __commonJS({
28411
28411
  if (!isValidContainer(container)) {
28412
28412
  throw new Error("Target container is not a DOM element.");
28413
28413
  }
28414
- return createPortal3(children, container, null, key);
28414
+ return createPortal4(children, container, null, key);
28415
28415
  }
28416
28416
  function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
28417
28417
  return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback);
@@ -34240,6 +34240,16 @@ var DEFAULT_MONTH_NAMES = [
34240
34240
  "\u0534\u0565\u056F\u057F\u0565\u0574\u0562\u0565\u0580"
34241
34241
  ];
34242
34242
  var DEFAULT_WEEKDAY_LABELS = ["\u0535\u0550", "\u0535\u0554", "\u0549\u0550", "\u0540\u0546", "\u0548\u0552\u0550", "\u0547\u0532", "\u053F\u0550"];
34243
+ function rangeIncludesUnavailable(start, end, isUnavailable) {
34244
+ const cursor = startOfDay(start);
34245
+ const last = startOfDay(end);
34246
+ const step = isBefore(last, cursor) ? -1 : 1;
34247
+ while (true) {
34248
+ if (isUnavailable(cursor)) return true;
34249
+ if (isSameDay(cursor, last)) return false;
34250
+ cursor.setDate(cursor.getDate() + step);
34251
+ }
34252
+ }
34243
34253
  var EMPTY_RANGE = { start: null, end: null };
34244
34254
  var DEFAULT_WIDTH = 320;
34245
34255
  var DEFAULT_MENU_HEIGHT = 388;
@@ -34293,6 +34303,9 @@ var DatePicker = forwardRef(
34293
34303
  closeOnSelect = true,
34294
34304
  minDate,
34295
34305
  maxDate,
34306
+ unavailableDates,
34307
+ unavailableDateLabel = "Booked",
34308
+ blockUnavailableDates = false,
34296
34309
  defaultVisibleMonth,
34297
34310
  monthNames = DEFAULT_MONTH_NAMES,
34298
34311
  weekdayLabels = DEFAULT_WEEKDAY_LABELS,
@@ -34311,6 +34324,17 @@ var DatePicker = forwardRef(
34311
34324
  onValueChange: _onValueChange,
34312
34325
  ...rest
34313
34326
  } = props;
34327
+ const unavailableDayKeys = useMemo(() => {
34328
+ const keys = /* @__PURE__ */ new Set();
34329
+ for (const date of unavailableDates ?? []) {
34330
+ keys.add(startOfDay(date).getTime());
34331
+ }
34332
+ return keys;
34333
+ }, [unavailableDates]);
34334
+ const isUnavailable = useCallback(
34335
+ (day) => unavailableDayKeys.has(startOfDay(day).getTime()),
34336
+ [unavailableDayKeys]
34337
+ );
34314
34338
  const isRange = props.range === true;
34315
34339
  const usesRangeTrigger = isRange && variant !== "default";
34316
34340
  const formatValue = formatValueProp ?? (usesRangeTrigger ? (date) => formatDateDayShortMonth(date, monthNames) : formatDate);
@@ -34413,6 +34437,7 @@ var DatePicker = forwardRef(
34413
34437
  const handleDayPress = useCallback(
34414
34438
  (day) => {
34415
34439
  if (disabled || isDateDisabled(day, minDate, maxDate)) return;
34440
+ if (blockUnavailableDates && isUnavailable(day)) return;
34416
34441
  const picked = startOfDay(day);
34417
34442
  if (!isRange) {
34418
34443
  if (!isValueControlled) setUncontrolledSingle(picked);
@@ -34423,14 +34448,19 @@ var DatePicker = forwardRef(
34423
34448
  const { start, end } = rangeValue;
34424
34449
  const startingNewRange = !start || start && end;
34425
34450
  const nextRange = startingNewRange ? { start: picked, end: null } : isBefore(picked, start) ? { start: picked, end: null } : { start, end: picked };
34451
+ if (blockUnavailableDates && nextRange.start && nextRange.end && rangeIncludesUnavailable(nextRange.start, nextRange.end, isUnavailable)) {
34452
+ return;
34453
+ }
34426
34454
  if (!isValueControlled) setUncontrolledRange(nextRange);
34427
34455
  props.onValueChange?.(nextRange);
34428
34456
  if (closeOnSelect && nextRange.start && nextRange.end) setOpen(false);
34429
34457
  },
34430
34458
  [
34459
+ blockUnavailableDates,
34431
34460
  closeOnSelect,
34432
34461
  disabled,
34433
34462
  isRange,
34463
+ isUnavailable,
34434
34464
  isValueControlled,
34435
34465
  maxDate,
34436
34466
  minDate,
@@ -34509,7 +34539,8 @@ var DatePicker = forwardRef(
34509
34539
  styles26.menu,
34510
34540
  usesRangeTrigger && styles26.rangeMenu,
34511
34541
  hideTrigger ? styles26.menuInline : menuAlignEnd ? styles26.menuAlignEnd : styles26.menuAlignStart,
34512
- calendarStyle
34542
+ calendarStyle,
34543
+ styles26.menuFitContent
34513
34544
  ],
34514
34545
  children: [
34515
34546
  /* @__PURE__ */ jsxs(View, { style: styles26.calendarHeader, children: [
@@ -34541,7 +34572,7 @@ var DatePicker = forwardRef(
34541
34572
  }
34542
34573
  )
34543
34574
  ] }),
34544
- /* @__PURE__ */ jsxs(View, { children: [
34575
+ /* @__PURE__ */ jsxs(View, { style: styles26.calendarGrid, children: [
34545
34576
  /* @__PURE__ */ jsx(View, { style: styles26.weekdayRow, children: weekdayLabels.map((weekdayLabel, index) => /* @__PURE__ */ jsx(View, { style: styles26.weekdayCell, children: /* @__PURE__ */ jsx(Text, { style: styles26.weekdayText, children: weekdayLabel }) }, `${weekdayLabel}-${index}`)) }),
34546
34577
  weeks.map((week, weekIndex) => {
34547
34578
  let rangeHighlightStyle = null;
@@ -34596,24 +34627,26 @@ var DatePicker = forwardRef(
34596
34627
  const isRangeStart = isRange && isSameDay(day, rangeValue.start);
34597
34628
  const isRangeEnd = isRange && isSameDay(day, rangeValue.end);
34598
34629
  const isSelectedEndpoint = isSelectedSingle || isRangeStart || isRangeEnd;
34630
+ const dayUnavailable = isUnavailable(day);
34631
+ const dayBlocked = blockUnavailableDates && dayUnavailable;
34599
34632
  const dayDisabled = disabled || isDateDisabled(day, minDate, maxDate);
34600
34633
  const dayKey = startOfDay(day).getTime();
34601
- const isHovered = !dayDisabled && !isSelectedEndpoint && hoveredDayKey === dayKey;
34634
+ const isHovered = !dayDisabled && !dayBlocked && !isSelectedEndpoint && hoveredDayKey === dayKey;
34602
34635
  const dayTextColor = isSelectedEndpoint ? colors.white : dayDisabled ? colors.grey400 : isToday ? colors.primary : !inCurrentMonth ? colors.grey300 : colors.white;
34603
34636
  return /* @__PURE__ */ jsxs(
34604
34637
  Pressable,
34605
34638
  {
34606
34639
  onPress: () => handleDayPress(day),
34607
- disabled: dayDisabled,
34640
+ disabled: dayDisabled || dayBlocked,
34608
34641
  onHoverIn: () => setHoveredDayKey(dayKey),
34609
34642
  onHoverOut: () => setHoveredDayKey((current) => current === dayKey ? null : current),
34610
34643
  onPressIn: () => setHoveredDayKey(dayKey),
34611
34644
  onPressOut: () => setHoveredDayKey((current) => current === dayKey ? null : current),
34612
34645
  style: styles26.dayCellWrap,
34613
34646
  accessibilityRole: "button",
34614
- accessibilityLabel: formatValue(day),
34647
+ accessibilityLabel: dayUnavailable ? `${formatValue(day)}, ${unavailableDateLabel}` : formatValue(day),
34615
34648
  accessibilityState: {
34616
- disabled: dayDisabled,
34649
+ disabled: dayDisabled || dayBlocked,
34617
34650
  selected: isSelectedEndpoint
34618
34651
  },
34619
34652
  children: [
@@ -34623,9 +34656,20 @@ var DatePicker = forwardRef(
34623
34656
  style: [
34624
34657
  styles26.dayCircle,
34625
34658
  isSelectedEndpoint && styles26.dayCircleSelected,
34659
+ dayUnavailable && styles26.dayCircleBooked,
34626
34660
  isHovered && styles26.dayCircleHovered
34627
34661
  ],
34628
- children: /* @__PURE__ */ jsx(Text, { style: [styles26.dayText, { color: dayTextColor }], children: day.getDate() })
34662
+ children: /* @__PURE__ */ jsx(
34663
+ Text,
34664
+ {
34665
+ style: [
34666
+ styles26.dayText,
34667
+ { color: dayTextColor },
34668
+ dayUnavailable && styles26.dayTextBooked
34669
+ ],
34670
+ children: day.getDate()
34671
+ }
34672
+ )
34629
34673
  }
34630
34674
  ),
34631
34675
  isToday && !isSelectedEndpoint ? /* @__PURE__ */ jsx(View, { style: styles26.todayDot }) : null
@@ -34763,7 +34807,7 @@ var styles26 = StyleSheet.create({
34763
34807
  menu: {
34764
34808
  position: "absolute",
34765
34809
  top: "100%",
34766
- width: DEFAULT_WIDTH,
34810
+ alignSelf: "flex-start",
34767
34811
  height: DEFAULT_MENU_HEIGHT,
34768
34812
  marginTop: 8,
34769
34813
  zIndex: 10,
@@ -34797,10 +34841,26 @@ var styles26 = StyleSheet.create({
34797
34841
  right: "auto",
34798
34842
  marginTop: 0
34799
34843
  },
34800
- rangeMenu: {
34801
- width: RANGE_TRIGGER_WIDTH
34844
+ rangeMenu: {},
34845
+ menuFitContent: {
34846
+ width: MENU_CONTENT_WIDTH + MENU_PADDING * 2,
34847
+ maxWidth: MENU_CONTENT_WIDTH + MENU_PADDING * 2,
34848
+ alignSelf: "flex-start",
34849
+ alignItems: "flex-start",
34850
+ ...Platform.select({
34851
+ web: {
34852
+ width: "fit-content",
34853
+ maxWidth: "fit-content"
34854
+ },
34855
+ default: {}
34856
+ })
34857
+ },
34858
+ calendarGrid: {
34859
+ width: MENU_CONTENT_WIDTH,
34860
+ alignSelf: "flex-start"
34802
34861
  },
34803
34862
  calendarHeader: {
34863
+ width: MENU_CONTENT_WIDTH,
34804
34864
  height: HEADER_HEIGHT3,
34805
34865
  paddingTop: 8,
34806
34866
  paddingBottom: 8,
@@ -34834,9 +34894,8 @@ var styles26 = StyleSheet.create({
34834
34894
  weekdayCell: {
34835
34895
  width: DAY_CELL_WIDTH,
34836
34896
  height: WEEKDAY_ROW_HEIGHT,
34837
- flexGrow: 1,
34838
- flexShrink: 1,
34839
- flexBasis: 0,
34897
+ flexGrow: 0,
34898
+ flexShrink: 0,
34840
34899
  alignItems: "center",
34841
34900
  justifyContent: "center"
34842
34901
  },
@@ -34864,9 +34923,8 @@ var styles26 = StyleSheet.create({
34864
34923
  dayCellWrap: {
34865
34924
  width: DAY_CELL_WIDTH,
34866
34925
  height: DAY_CELL_HEIGHT,
34867
- flexGrow: 1,
34868
- flexShrink: 1,
34869
- flexBasis: 0,
34926
+ flexGrow: 0,
34927
+ flexShrink: 0,
34870
34928
  alignItems: "center",
34871
34929
  justifyContent: "center",
34872
34930
  opacity: 1
@@ -34883,6 +34941,12 @@ var styles26 = StyleSheet.create({
34883
34941
  dayCircleSelected: {
34884
34942
  backgroundColor: colors.primary
34885
34943
  },
34944
+ dayCircleBooked: {
34945
+ backgroundColor: colors.grey700
34946
+ },
34947
+ dayTextBooked: {
34948
+ textDecorationLine: "line-through"
34949
+ },
34886
34950
  dayCircleHovered: {
34887
34951
  backgroundColor: colors.grey600
34888
34952
  },
@@ -36144,6 +36208,9 @@ var styles32 = StyleSheet.create({
36144
36208
  color: colors.red
36145
36209
  }
36146
36210
  });
36211
+
36212
+ // src/components/Select/Select.tsx
36213
+ var import_react_dom3 = __toESM(require_react_dom());
36147
36214
  var DEFAULT_WIDTH4 = 308;
36148
36215
  var TRIGGER_HEIGHT2 = 44;
36149
36216
  var TRIGGER_RADIUS2 = 60;
@@ -36153,6 +36220,9 @@ var ITEM_RADIUS2 = 12;
36153
36220
  var ICON_SIZE13 = 20;
36154
36221
  var CHIP_GAP = 6;
36155
36222
  var FALLBACK_ELLIPSIS_WIDTH = 20;
36223
+ var WEB_MENU_Z_INDEX = 600;
36224
+ var WEB_VIEWPORT_PADDING = 8;
36225
+ var WEB_MENU_GAP = 8;
36156
36226
  function itemBackground(state) {
36157
36227
  switch (state) {
36158
36228
  case "hover":
@@ -36299,6 +36369,7 @@ var Select = forwardRef(
36299
36369
  const valueProp = props.value;
36300
36370
  const rootRef = useRef(null);
36301
36371
  const triggerRef = useRef(null);
36372
+ const menuRef = useRef(null);
36302
36373
  const searchInputRef = useRef(null);
36303
36374
  const setRootRef = useMemo(() => mergeRefs(rootRef, forwardedRef), [forwardedRef]);
36304
36375
  const isOpenControlled = typeof openProp === "boolean";
@@ -36314,6 +36385,7 @@ var Select = forwardRef(
36314
36385
  const [hoveredValue, setHoveredValue] = useState(null);
36315
36386
  const [menuAlignEnd, setMenuAlignEnd] = useState(false);
36316
36387
  const [menuPlaceAbove, setMenuPlaceAbove] = useState(false);
36388
+ const [webMenuPosition, setWebMenuPosition] = useState(null);
36317
36389
  const selectedValues = useMemo(() => {
36318
36390
  const current = isValueControlled ? valueProp : multiple ? uncontrolledMultiple : uncontrolledSingle;
36319
36391
  return toArray(current);
@@ -36367,6 +36439,7 @@ var Select = forwardRef(
36367
36439
  setHoveredValue(null);
36368
36440
  setMenuAlignEnd(false);
36369
36441
  setMenuPlaceAbove(false);
36442
+ setWebMenuPosition(null);
36370
36443
  onSearchChange?.("");
36371
36444
  }
36372
36445
  },
@@ -36378,15 +36451,18 @@ var Select = forwardRef(
36378
36451
  const trigger = triggerRef.current;
36379
36452
  const rect = trigger?.getBoundingClientRect?.();
36380
36453
  if (!rect) return;
36381
- const viewportPadding = 8;
36382
- const gap = 8;
36383
36454
  const menuWidth = Math.max(rect.width, resolvedMenuWidth ?? 0);
36384
- const overflowsRight = rect.left + menuWidth > window.innerWidth - viewportPadding;
36455
+ const overflowsRight = rect.left + menuWidth > window.innerWidth - WEB_VIEWPORT_PADDING;
36385
36456
  setMenuAlignEnd(overflowsRight);
36386
- const spaceBelow = window.innerHeight - viewportPadding - rect.bottom;
36387
- const spaceAbove = rect.top - viewportPadding;
36388
- const needsAbove = estimatedMenuHeight + gap > spaceBelow && spaceAbove > spaceBelow;
36457
+ const spaceBelow = window.innerHeight - WEB_VIEWPORT_PADDING - rect.bottom;
36458
+ const spaceAbove = rect.top - WEB_VIEWPORT_PADDING;
36459
+ const needsAbove = estimatedMenuHeight + WEB_MENU_GAP > spaceBelow && spaceAbove > spaceBelow;
36389
36460
  setMenuPlaceAbove(needsAbove);
36461
+ const available = Math.max(0, (needsAbove ? spaceAbove : spaceBelow) - WEB_MENU_GAP);
36462
+ const maxHeight = Math.min(estimatedMenuHeight, Math.max(available, TRIGGER_HEIGHT2));
36463
+ const left = overflowsRight ? Math.max(WEB_VIEWPORT_PADDING, rect.right - menuWidth) : Math.min(rect.left, window.innerWidth - WEB_VIEWPORT_PADDING - menuWidth);
36464
+ const top = needsAbove ? Math.max(WEB_VIEWPORT_PADDING, rect.top - WEB_MENU_GAP - maxHeight) : rect.bottom + WEB_MENU_GAP;
36465
+ setWebMenuPosition({ top, left, width: menuWidth, maxHeight });
36390
36466
  };
36391
36467
  updateMenuPlacement();
36392
36468
  window.addEventListener("resize", updateMenuPlacement);
@@ -36403,11 +36479,12 @@ var Select = forwardRef(
36403
36479
  useEffect(() => {
36404
36480
  if (Platform.OS !== "web" || !isOpen) return;
36405
36481
  const handlePointerDown = (event) => {
36406
- const root = rootRef.current;
36407
36482
  const target = event.target;
36408
- if (root?.contains && target instanceof Node && !root.contains(target)) {
36409
- setOpen(false);
36410
- }
36483
+ if (!(target instanceof Node)) return;
36484
+ const root = rootRef.current;
36485
+ const menu = menuRef.current;
36486
+ if (root?.contains?.(target) || menu?.contains?.(target)) return;
36487
+ setOpen(false);
36411
36488
  };
36412
36489
  document.addEventListener("mousedown", handlePointerDown);
36413
36490
  document.addEventListener("touchstart", handlePointerDown);
@@ -36521,7 +36598,7 @@ var Select = forwardRef(
36521
36598
  ]);
36522
36599
  const leftIconNode = renderStatefulIcon(leftIcon, UserIcon, {
36523
36600
  size: ICON_SIZE13,
36524
- color: error ? colors.red : colors.primary
36601
+ color: error ? colors.red : isOpen ? colors.primary : colors.grey100
36525
36602
  });
36526
36603
  const hasLeftIcon = showLeftIcon || leftIcon != null;
36527
36604
  const triggerBorderColor = error ? colors.redMuted : isOpen ? colors.primaryMuted : colors.grey700;
@@ -36530,6 +36607,95 @@ var Select = forwardRef(
36530
36607
  const hintColor = error ? colors.red : colors.grey100;
36531
36608
  const singleLabel = selectedOptions[0]?.label ?? placeholder;
36532
36609
  const resolvedAccessibilityLabel = accessibilityLabel ?? (typeof label === "string" ? label : void 0);
36610
+ const optionListMaxHeight = Platform.OS === "web" && webMenuPosition != null ? Math.max(43, webMenuPosition.maxHeight - (24 + (showSearch ? 48 : 0))) : resolvedOptionListMaxHeight;
36611
+ const menuNode = isOpen ? /* @__PURE__ */ jsxs(
36612
+ View,
36613
+ {
36614
+ ref: menuRef,
36615
+ style: [
36616
+ styles33.menu,
36617
+ Platform.OS === "web" && webMenuPosition != null ? {
36618
+ position: "fixed",
36619
+ top: webMenuPosition.top,
36620
+ left: webMenuPosition.left,
36621
+ width: webMenuPosition.width,
36622
+ minWidth: webMenuPosition.width,
36623
+ maxHeight: webMenuPosition.maxHeight,
36624
+ zIndex: WEB_MENU_Z_INDEX,
36625
+ marginTop: 0,
36626
+ marginBottom: 0
36627
+ } : Platform.OS === "web" ? { position: "fixed", opacity: 0, pointerEvents: "none" } : [
36628
+ menuAlignEnd ? styles33.menuAlignEnd : styles33.menuAlignStart,
36629
+ menuPlaceAbove ? styles33.menuAbove : styles33.menuBelow
36630
+ ],
36631
+ menuStyle
36632
+ ],
36633
+ children: [
36634
+ showSearch ? /* @__PURE__ */ jsxs(View, { style: styles33.searchField, children: [
36635
+ /* @__PURE__ */ jsx(View, { style: styles33.iconSlot, children: /* @__PURE__ */ jsx(SearchIcon, { size: ICON_SIZE13, color: colors.grey100 }) }),
36636
+ /* @__PURE__ */ jsx(
36637
+ TextInput,
36638
+ {
36639
+ ref: searchInputRef,
36640
+ value: searchQuery,
36641
+ onChangeText: handleSearchChange,
36642
+ editable: !disabled,
36643
+ placeholder: searchPlaceholder,
36644
+ placeholderTextColor: colors.grey100,
36645
+ style: [
36646
+ styles33.searchInput,
36647
+ Platform.OS === "web" ? styles33.searchInputWeb : null,
36648
+ Platform.OS === "android" ? styles33.searchInputAndroid : null
36649
+ ],
36650
+ accessibilityLabel: searchPlaceholder
36651
+ }
36652
+ )
36653
+ ] }) : null,
36654
+ /* @__PURE__ */ jsxs(
36655
+ ScrollView,
36656
+ {
36657
+ style: [styles33.optionList, { maxHeight: optionListMaxHeight }],
36658
+ contentContainerStyle: styles33.optionListContent,
36659
+ keyboardShouldPersistTaps: "handled",
36660
+ showsVerticalScrollIndicator: false,
36661
+ children: [
36662
+ loading ? /* @__PURE__ */ jsx(View, { style: styles33.statusRow, children: /* @__PURE__ */ jsx(Text, { style: styles33.statusText, children: "Loading..." }) }) : filteredOptions.length === 0 ? /* @__PURE__ */ jsx(View, { style: styles33.statusRow, children: /* @__PURE__ */ jsx(Text, { style: styles33.statusText, children: emptyText }) }) : null,
36663
+ !loading && filteredOptions.map((option) => {
36664
+ const isSelected = selectedValues.includes(option.value);
36665
+ const isHovered = hoveredValue === option.value;
36666
+ const visualState = isSelected ? "selected" : isHovered ? "hover" : "default";
36667
+ return /* @__PURE__ */ jsxs(
36668
+ Pressable,
36669
+ {
36670
+ onPress: () => handleSelect(option.value),
36671
+ disabled,
36672
+ onHoverIn: () => setHoveredValue(option.value),
36673
+ onHoverOut: () => setHoveredValue((current) => current === option.value ? null : current),
36674
+ onPressIn: () => setHoveredValue(option.value),
36675
+ onPressOut: () => setHoveredValue((current) => current === option.value ? null : current),
36676
+ accessibilityRole: multiple ? "checkbox" : "button",
36677
+ accessibilityState: { selected: isSelected, checked: isSelected, disabled },
36678
+ style: [
36679
+ styles33.item,
36680
+ {
36681
+ backgroundColor: itemBackground(visualState)
36682
+ }
36683
+ ],
36684
+ children: [
36685
+ multiple ? /* @__PURE__ */ jsx(View, { style: [styles33.itemCheckbox, { pointerEvents: "none" }], children: /* @__PURE__ */ jsx(Checkbox, { value: isSelected, variant: "light" }) }) : null,
36686
+ /* @__PURE__ */ jsx(Text, { style: styles33.itemLabel, numberOfLines: 1, children: option.label })
36687
+ ]
36688
+ },
36689
+ option.value
36690
+ );
36691
+ })
36692
+ ]
36693
+ }
36694
+ )
36695
+ ]
36696
+ }
36697
+ ) : null;
36698
+ const webMenuPortal = Platform.OS === "web" && isOpen && typeof document !== "undefined" ? (0, import_react_dom3.createPortal)(menuNode, document.body) : null;
36533
36699
  return /* @__PURE__ */ jsxs(
36534
36700
  View,
36535
36701
  {
@@ -36570,80 +36736,7 @@ var Select = forwardRef(
36570
36736
  ]
36571
36737
  }
36572
36738
  ),
36573
- isOpen ? /* @__PURE__ */ jsxs(
36574
- View,
36575
- {
36576
- style: [
36577
- styles33.menu,
36578
- menuAlignEnd ? styles33.menuAlignEnd : styles33.menuAlignStart,
36579
- menuPlaceAbove ? styles33.menuAbove : styles33.menuBelow,
36580
- menuStyle
36581
- ],
36582
- children: [
36583
- showSearch ? /* @__PURE__ */ jsxs(View, { style: styles33.searchField, children: [
36584
- /* @__PURE__ */ jsx(View, { style: styles33.iconSlot, children: /* @__PURE__ */ jsx(SearchIcon, { size: ICON_SIZE13, color: colors.grey100 }) }),
36585
- /* @__PURE__ */ jsx(
36586
- TextInput,
36587
- {
36588
- ref: searchInputRef,
36589
- value: searchQuery,
36590
- onChangeText: handleSearchChange,
36591
- editable: !disabled,
36592
- placeholder: searchPlaceholder,
36593
- placeholderTextColor: colors.grey100,
36594
- style: [
36595
- styles33.searchInput,
36596
- Platform.OS === "web" ? styles33.searchInputWeb : null,
36597
- Platform.OS === "android" ? styles33.searchInputAndroid : null
36598
- ],
36599
- accessibilityLabel: searchPlaceholder
36600
- }
36601
- )
36602
- ] }) : null,
36603
- /* @__PURE__ */ jsxs(
36604
- ScrollView,
36605
- {
36606
- style: [styles33.optionList, { maxHeight: resolvedOptionListMaxHeight }],
36607
- contentContainerStyle: styles33.optionListContent,
36608
- keyboardShouldPersistTaps: "handled",
36609
- showsVerticalScrollIndicator: false,
36610
- children: [
36611
- loading ? /* @__PURE__ */ jsx(View, { style: styles33.statusRow, children: /* @__PURE__ */ jsx(Text, { style: styles33.statusText, children: "Loading..." }) }) : filteredOptions.length === 0 ? /* @__PURE__ */ jsx(View, { style: styles33.statusRow, children: /* @__PURE__ */ jsx(Text, { style: styles33.statusText, children: emptyText }) }) : null,
36612
- !loading && filteredOptions.map((option) => {
36613
- const isSelected = selectedValues.includes(option.value);
36614
- const isHovered = hoveredValue === option.value;
36615
- const visualState = isSelected ? "selected" : isHovered ? "hover" : "default";
36616
- return /* @__PURE__ */ jsxs(
36617
- Pressable,
36618
- {
36619
- onPress: () => handleSelect(option.value),
36620
- disabled,
36621
- onHoverIn: () => setHoveredValue(option.value),
36622
- onHoverOut: () => setHoveredValue((current) => current === option.value ? null : current),
36623
- onPressIn: () => setHoveredValue(option.value),
36624
- onPressOut: () => setHoveredValue((current) => current === option.value ? null : current),
36625
- accessibilityRole: multiple ? "checkbox" : "button",
36626
- accessibilityState: { selected: isSelected, checked: isSelected, disabled },
36627
- style: [
36628
- styles33.item,
36629
- {
36630
- backgroundColor: itemBackground(visualState)
36631
- }
36632
- ],
36633
- children: [
36634
- multiple ? /* @__PURE__ */ jsx(View, { style: [styles33.itemCheckbox, { pointerEvents: "none" }], children: /* @__PURE__ */ jsx(Checkbox, { value: isSelected, variant: "light" }) }) : null,
36635
- /* @__PURE__ */ jsx(Text, { style: styles33.itemLabel, numberOfLines: 1, children: option.label })
36636
- ]
36637
- },
36638
- option.value
36639
- );
36640
- })
36641
- ]
36642
- }
36643
- )
36644
- ]
36645
- }
36646
- ) : null
36739
+ Platform.OS === "web" ? webMenuPortal : menuNode
36647
36740
  ] }),
36648
36741
  showHint && hint ? /* @__PURE__ */ jsx(Text, { style: [styles33.hint, { color: hintColor }], children: hint }) : null
36649
36742
  ]