@tamagui/select 1.0.0-beta.15 → 1.0.1-beta.100

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.
@@ -21,7 +21,6 @@ var __spreadValues = (a, b) => {
21
21
  return a;
22
22
  };
23
23
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
25
24
  var __objRest = (source, exclude) => {
26
25
  var target = {};
27
26
  for (var prop in source)
@@ -51,18 +50,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
51
50
  var Select_exports = {};
52
51
  __export(Select_exports, {
53
52
  Select: () => Select,
54
- SelectContent: () => SelectContent,
55
- SelectGroup: () => SelectGroup,
53
+ SelectGroupFrame: () => SelectGroupFrame,
56
54
  SelectIcon: () => SelectIcon,
57
55
  SelectItem: () => SelectItem,
58
- SelectItemIndicator: () => SelectItemIndicator,
59
- SelectItemText: () => SelectItemText,
60
- SelectLabel: () => SelectLabel,
61
- SelectScrollDownButton: () => SelectScrollDownButton,
62
- SelectScrollUpButton: () => SelectScrollUpButton,
56
+ SelectItemTextFrame: () => SelectItemTextFrame,
63
57
  SelectSeparator: () => SelectSeparator,
64
58
  SelectTrigger: () => SelectTrigger,
65
- SelectValue: () => SelectValue,
59
+ SelectViewport: () => SelectViewport,
60
+ SelectViewportFrame: () => SelectViewportFrame,
66
61
  createSelectScope: () => createSelectScope
67
62
  });
68
63
  module.exports = __toCommonJS(Select_exports);
@@ -72,13 +67,21 @@ var import_compose_refs = require("@tamagui/compose-refs");
72
67
  var import_core = require("@tamagui/core");
73
68
  var import_core2 = require("@tamagui/core");
74
69
  var import_create_context = require("@tamagui/create-context");
70
+ var import_list_item = require("@tamagui/list-item");
75
71
  var import_separator = require("@tamagui/separator");
76
72
  var import_stacks = require("@tamagui/stacks");
73
+ var import_text = require("@tamagui/text");
77
74
  var import_use_controllable_state = require("@tamagui/use-controllable-state");
78
75
  var React = __toESM(require("react"));
79
76
  var ReactDOM = __toESM(require("react-dom"));
80
- const OPEN_KEYS = [" ", "Enter", "ArrowUp", "ArrowDown"];
81
- const SELECTION_KEYS = [" ", "Enter"];
77
+ const userAgent = typeof navigator !== "undefined" && navigator.userAgent || "";
78
+ const isFirefox = userAgent.toLowerCase().includes("firefox");
79
+ if (isFirefox) {
80
+ document.body.classList.add("firefox");
81
+ }
82
+ function getVisualOffsetTop() {
83
+ return !/^((?!chrome|android).)*safari/i.test(userAgent) ? (visualViewport == null ? void 0 : visualViewport.offsetTop) ?? 0 : 0;
84
+ }
82
85
  const SELECT_NAME = "Select";
83
86
  const WINDOW_PADDING = 8;
84
87
  const SCROLL_ARROW_VELOCITY = 8;
@@ -87,61 +90,6 @@ const MIN_HEIGHT = 80;
87
90
  const FALLBACK_THRESHOLD = 16;
88
91
  const [createSelectContext, createSelectScope] = (0, import_create_context.createContextScope)(SELECT_NAME);
89
92
  const [SelectProvider, useSelectContext] = createSelectContext(SELECT_NAME);
90
- const Select = /* @__PURE__ */ __name((props) => {
91
- const {
92
- __scopeSelect,
93
- children,
94
- open: openProp,
95
- defaultOpen,
96
- onOpenChange,
97
- value: valueProp,
98
- defaultValue,
99
- onValueChange,
100
- dir: dir2,
101
- name,
102
- autoComplete
103
- } = props;
104
- const [open, setOpen] = (0, import_use_controllable_state.useControllableState)({
105
- prop: openProp,
106
- defaultProp: defaultOpen || false,
107
- onChange: onOpenChange
108
- });
109
- const [value, setValue] = (0, import_use_controllable_state.useControllableState)({
110
- prop: valueProp,
111
- defaultProp: defaultValue || "",
112
- onChange: onValueChange
113
- });
114
- const selectedIndexRef = React.useRef(null);
115
- const activeIndexRef = React.useRef(null);
116
- const prevActiveIndex = (0, import_react_use_previous.usePrevious)(activeIndex);
117
- const [showArrows, setShowArrows] = React.useState(false);
118
- const [scrollTop, setScrollTop] = React.useState(0);
119
- const [activeIndex, setActiveIndex] = React.useState(null);
120
- const [selectedIndex, setSelectedIndex] = React.useState(Math.max(0, listContentRef.current.indexOf(value)));
121
- (0, import_core.useIsomorphicLayoutEffect)(() => {
122
- selectedIndexRef.current = selectedIndex;
123
- activeIndexRef.current = activeIndex;
124
- });
125
- useEffect(() => {
126
- const frame = requestAnimationFrame(() => {
127
- setShowArrows(open);
128
- if (!open) {
129
- setScrollTop(0);
130
- setMiddlewareType("align");
131
- setActiveIndex(null);
132
- setControlledScrolling(false);
133
- }
134
- });
135
- return () => cancelAnimationFrame(frame);
136
- }, [open]);
137
- const showUpArrow = showArrows && scrollTop > SCROLL_ARROW_THRESHOLD;
138
- const showDownArrow = showArrows && floatingRef.current && scrollTop < floatingRef.current.scrollHeight - floatingRef.current.clientHeight - SCROLL_ARROW_THRESHOLD;
139
- return /* @__PURE__ */ React.createElement(SelectProvider, {
140
- scope: __scopeSelect,
141
- open
142
- }, children);
143
- }, "Select");
144
- Select.displayName = SELECT_NAME;
145
93
  const TRIGGER_NAME = "SelectTrigger";
146
94
  const SelectTrigger = React.forwardRef((props, forwardedRef) => {
147
95
  const _a = props, {
@@ -154,298 +102,777 @@ const SelectTrigger = React.forwardRef((props, forwardedRef) => {
154
102
  "aria-labelledby"
155
103
  ]);
156
104
  const context = useSelectContext(TRIGGER_NAME, __scopeSelect);
157
- const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, context.onTriggerChange);
158
- const getItems = useCollection(__scopeSelect);
159
- const handleOpen = /* @__PURE__ */ __name(() => {
160
- if (!disabled) {
161
- context.onOpenChange(true);
162
- resetTypeahead();
163
- }
164
- }, "handleOpen");
165
- return /* @__PURE__ */ React.createElement(Primitive.button, __spreadProps(__spreadValues({
166
- type: "button",
167
- role: "combobox",
168
- "aria-controls": context.contentId,
105
+ return /* @__PURE__ */ React.createElement(import_list_item.ListItem, __spreadValues(__spreadProps(__spreadValues({
106
+ backgrounded: true,
107
+ radiused: true,
108
+ hoverTheme: true,
109
+ pressTheme: true,
110
+ focusTheme: true,
111
+ focusable: false,
112
+ borderWidth: 1,
113
+ componentName: TRIGGER_NAME,
114
+ size: context.size,
169
115
  "aria-expanded": context.open,
170
116
  "aria-autocomplete": "none",
171
- dir: context.dir,
172
117
  disabled,
173
118
  "data-disabled": disabled ? "" : void 0
174
119
  }, triggerProps), {
175
- ref: composedRefs,
176
- onPointerDown: (0, import_core.composeEventHandlers)(triggerProps.onPointerDown, (event) => {
177
- ;
178
- event.target.releasePointerCapture(event.pointerId);
179
- if (event.button === 0 && event.ctrlKey === false) {
180
- handleOpen();
181
- context.triggerPointerDownPosRef.current = {
182
- x: Math.round(event.pageX),
183
- y: Math.round(event.pageY)
184
- };
185
- event.preventDefault();
186
- }
187
- }),
188
- onKeyDown: (0, import_core.composeEventHandlers)(triggerProps.onKeyDown, (event) => {
189
- const isTypingAhead = searchRef.current !== "";
190
- const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
191
- if (!isModifierKey && event.key.length === 1)
192
- handleTypeaheadSearch(event.key);
193
- if (isTypingAhead && event.key === " ")
194
- return;
195
- if (OPEN_KEYS.includes(event.key)) {
196
- handleOpen();
197
- event.preventDefault();
198
- }
199
- })
200
- }));
120
+ ref: forwardedRef
121
+ }), context.interactions.getReferenceProps()));
201
122
  });
202
123
  SelectTrigger.displayName = TRIGGER_NAME;
203
124
  const VALUE_NAME = "SelectValue";
204
- const SelectValue = React.forwardRef((props, forwardedRef) => {
205
- const _a = props, { __scopeSelect, className, style } = _a, valueProps = __objRest(_a, ["__scopeSelect", "className", "style"]);
206
- return /* @__PURE__ */ React.createElement(import_stacks.XStack, __spreadProps(__spreadValues({}, valueProps), {
207
- pointerEvents: "none"
208
- }));
125
+ const SelectValueFrame = (0, import_core.styled)(import_text.Paragraph, {
126
+ name: VALUE_NAME,
127
+ selectable: false
209
128
  });
210
- const ICON_NAME = "SelectIcon";
211
- const SelectIcon = React.forwardRef((props, forwardedRef) => {
212
- const _a = props, { __scopeSelect, children } = _a, iconProps = __objRest(_a, ["__scopeSelect", "children"]);
213
- return /* @__PURE__ */ React.createElement(import_stacks.XStack, __spreadProps(__spreadValues({
214
- "aria-hidden": true
215
- }, iconProps), {
216
- ref: forwardedRef
217
- }), children || "\u25BC");
129
+ const SelectValue = SelectValueFrame.extractable(React.forwardRef(({ __scopeSelect, children, placeholder }, forwardedRef) => {
130
+ const context = useSelectContext(VALUE_NAME, __scopeSelect);
131
+ const { onValueNodeHasChildrenChange } = context;
132
+ const hasChildren = children !== void 0;
133
+ const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, context.onValueNodeChange);
134
+ React.useLayoutEffect(() => {
135
+ onValueNodeHasChildrenChange(hasChildren);
136
+ }, [onValueNodeHasChildrenChange, hasChildren]);
137
+ return /* @__PURE__ */ React.createElement(SelectValueFrame, {
138
+ size: context.size,
139
+ ref: composedRefs,
140
+ pointerEvents: "none"
141
+ }, context.value === void 0 && placeholder !== void 0 ? placeholder : children);
142
+ }));
143
+ SelectValue.displayName = VALUE_NAME;
144
+ const SelectIcon = (0, import_core.styled)(import_stacks.XStack, {
145
+ name: "SelectIcon",
146
+ "aria-hidden": true,
147
+ children: /* @__PURE__ */ React.createElement(import_text.Paragraph, null, "\u25BC")
218
148
  });
219
- SelectIcon.displayName = ICON_NAME;
220
149
  const CONTENT_NAME = "SelectContent";
221
- const SelectContent = React.forwardRef((props, forwardedRef) => {
222
- const context = useSelectContext(CONTENT_NAME, props.__scopeSelect);
223
- return props.children;
224
- });
225
- const GROUP_NAME = "SelectGroup";
226
- const [SelectGroupContextProvider, useSelectGroupContext] = createSelectContext(GROUP_NAME);
227
- const SelectGroup = React.forwardRef((props, forwardedRef) => {
228
- const _a = props, { __scopeSelect } = _a, groupProps = __objRest(_a, ["__scopeSelect"]);
229
- const groupId = (0, import_core2.useId)();
230
- return /* @__PURE__ */ React.createElement(SelectGroupContextProvider, {
231
- scope: __scopeSelect,
232
- id: groupId
233
- }, /* @__PURE__ */ React.createElement(Primitive.div, __spreadProps(__spreadValues({
234
- role: "group",
235
- "aria-labelledby": groupId
236
- }, groupProps), {
237
- ref: forwardedRef
238
- })));
150
+ const SelectContent = ({ children, __scopeSelect }) => {
151
+ const context = useSelectContext(CONTENT_NAME, __scopeSelect);
152
+ const themeName = (0, import_core.useThemeName)();
153
+ const contents = /* @__PURE__ */ React.createElement(import_core.Theme, {
154
+ name: themeName
155
+ }, children);
156
+ return /* @__PURE__ */ React.createElement(import_react_dom_interactions.FloatingPortal, null, context.open ? /* @__PURE__ */ React.createElement(import_react_dom_interactions.FloatingOverlay, {
157
+ lockScroll: true
158
+ }, contents) : /* @__PURE__ */ React.createElement("div", {
159
+ style: { display: "none" }
160
+ }, contents));
161
+ };
162
+ const VIEWPORT_NAME = "SelectViewport";
163
+ const SelectViewportFrame = (0, import_core.styled)(import_stacks.ThemeableStack, {
164
+ name: VIEWPORT_NAME,
165
+ backgroundColor: "$background",
166
+ elevate: true,
167
+ bordered: true,
168
+ overflow: "scroll",
169
+ userSelect: "none",
170
+ variants: {
171
+ size: {
172
+ "...size": (val, { tokens }) => {
173
+ return {
174
+ borderRadius: tokens.radius[val] ?? val
175
+ };
176
+ }
177
+ }
178
+ },
179
+ defaultVariants: {
180
+ size: "$2"
181
+ }
239
182
  });
240
- SelectGroup.displayName = GROUP_NAME;
241
- const LABEL_NAME = "SelectLabel";
242
- const SelectLabel = React.forwardRef((props, forwardedRef) => {
243
- const _a = props, { __scopeSelect } = _a, labelProps = __objRest(_a, ["__scopeSelect"]);
244
- const groupContext = useSelectGroupContext(LABEL_NAME, __scopeSelect);
245
- return /* @__PURE__ */ React.createElement(Primitive.div, __spreadProps(__spreadValues({
246
- id: groupContext.id
247
- }, labelProps), {
183
+ const SelectViewport = React.forwardRef((props, forwardedRef) => {
184
+ const _a = props, { __scopeSelect, children } = _a, viewportProps = __objRest(_a, ["__scopeSelect", "children"]);
185
+ const context = useSelectContext(VIEWPORT_NAME, __scopeSelect);
186
+ const _b = context.interactions.getFloatingProps(), { style } = _b, floatingProps = __objRest(_b, ["style"]);
187
+ delete style["scrollbarWidth"];
188
+ delete style["listStyleType"];
189
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("style", {
190
+ dangerouslySetInnerHTML: {
191
+ __html: `[data-tamagui-select-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-tamagui-select-viewport]::-webkit-scrollbar{display:none}`
192
+ }
193
+ }), /* @__PURE__ */ React.createElement(import_react_dom_interactions.FloatingFocusManager, {
194
+ context: context.floatingContext,
195
+ preventTabbing: true
196
+ }, /* @__PURE__ */ React.createElement(SelectViewportFrame, __spreadValues(__spreadValues(__spreadProps(__spreadValues({
197
+ size: context.size,
198
+ "data-tamagui-select-viewport": "",
199
+ role: "presentation"
200
+ }, viewportProps), {
248
201
  ref: forwardedRef
249
- }));
202
+ }), floatingProps), style), children)));
250
203
  });
251
- SelectLabel.displayName = LABEL_NAME;
204
+ SelectViewport.displayName = VIEWPORT_NAME;
252
205
  const ITEM_NAME = "SelectItem";
253
206
  const [SelectItemContextProvider, useSelectItemContext] = createSelectContext(ITEM_NAME);
254
207
  const SelectItem = React.forwardRef((props, forwardedRef) => {
255
- const _a = props, { __scopeSelect, value, disabled = false, textValue: textValueProp } = _a, itemProps = __objRest(_a, ["__scopeSelect", "value", "disabled", "textValue"]);
208
+ const _a = props, {
209
+ __scopeSelect,
210
+ value,
211
+ disabled = false,
212
+ textValue: textValueProp,
213
+ index
214
+ } = _a, itemProps = __objRest(_a, [
215
+ "__scopeSelect",
216
+ "value",
217
+ "disabled",
218
+ "textValue",
219
+ "index"
220
+ ]);
256
221
  const context = useSelectContext(ITEM_NAME, __scopeSelect);
257
- const contentContext = useSelectContentContext(ITEM_NAME, __scopeSelect);
258
222
  const isSelected = context.value === value;
259
223
  const [textValue, setTextValue] = React.useState(textValueProp ?? "");
260
224
  const [isFocused, setIsFocused] = React.useState(false);
261
- const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, isSelected ? contentContext.onSelectedItemChange : void 0);
262
225
  const textId = (0, import_core2.useId)();
263
- const handleSelect = /* @__PURE__ */ __name(() => {
264
- if (!disabled) {
265
- context.onValueChange(value);
266
- context.onOpenChange(false);
226
+ const {
227
+ selectedIndex,
228
+ setSelectedIndex,
229
+ listRef,
230
+ open,
231
+ setOpen,
232
+ onChange,
233
+ activeIndex,
234
+ setActiveIndex,
235
+ setValueAtIndex,
236
+ dataRef
237
+ } = context;
238
+ const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, (node) => {
239
+ if (node instanceof HTMLElement) {
240
+ listRef.current[index] = node;
241
+ }
242
+ });
243
+ React.useEffect(() => {
244
+ setValueAtIndex(index, value);
245
+ }, [index]);
246
+ const timeoutRef = React.useRef();
247
+ const [allowMouseUp, setAllowMouseUp] = React.useState(false);
248
+ function handleSelect() {
249
+ setSelectedIndex(index);
250
+ onChange(value);
251
+ setOpen(false);
252
+ }
253
+ React.useLayoutEffect(() => {
254
+ clearTimeout(timeoutRef.current);
255
+ if (open) {
256
+ if (selectedIndex !== index) {
257
+ setAllowMouseUp(true);
258
+ } else {
259
+ timeoutRef.current = setTimeout(() => {
260
+ setAllowMouseUp(true);
261
+ }, 300);
262
+ }
263
+ } else {
264
+ setAllowMouseUp(false);
265
+ }
266
+ }, [open, index, setActiveIndex, selectedIndex]);
267
+ function handleKeyDown(event) {
268
+ if (event.key === "Enter" || event.key === " " && !dataRef.current.typing) {
269
+ event.preventDefault();
270
+ handleSelect();
267
271
  }
268
- }, "handleSelect");
272
+ }
273
+ const selectItemProps = context.interactions.getItemProps({
274
+ onClick: allowMouseUp ? handleSelect : void 0,
275
+ onMouseUp: allowMouseUp ? handleSelect : void 0,
276
+ onKeyDown: handleKeyDown
277
+ });
269
278
  return /* @__PURE__ */ React.createElement(SelectItemContextProvider, {
270
279
  scope: __scopeSelect,
271
280
  value,
272
- textId,
281
+ textId: textId || "",
273
282
  isSelected,
274
283
  onItemTextChange: React.useCallback((node) => {
275
284
  setTextValue((prevTextValue) => prevTextValue || ((node == null ? void 0 : node.textContent) ?? "").trim());
276
285
  }, [])
277
- }, /* @__PURE__ */ React.createElement(Collection.ItemSlot, {
278
- scope: __scopeSelect,
279
- value,
280
- disabled,
281
- textValue
282
- }, /* @__PURE__ */ React.createElement(Primitive.div, __spreadProps(__spreadValues({
283
- role: "option",
286
+ }, /* @__PURE__ */ React.createElement(import_list_item.ListItem, __spreadValues(__spreadValues({
287
+ backgrounded: true,
288
+ pressTheme: true,
289
+ focusTheme: true,
290
+ componentName: ITEM_NAME,
291
+ ref: composedRefs,
284
292
  "aria-labelledby": textId,
285
293
  "aria-selected": isSelected && isFocused,
286
294
  "data-state": isSelected ? "active" : "inactive",
287
295
  "aria-disabled": disabled || void 0,
288
296
  "data-disabled": disabled ? "" : void 0,
289
- tabIndex: disabled ? void 0 : -1
290
- }, itemProps), {
291
- ref: composedRefs,
292
- onFocus: (0, import_core.composeEventHandlers)(itemProps.onFocus, () => setIsFocused(true)),
293
- onBlur: (0, import_core.composeEventHandlers)(itemProps.onBlur, () => setIsFocused(false)),
294
- onPointerUp: (0, import_core.composeEventHandlers)(itemProps.onPointerUp, handleSelect),
295
- onPointerMove: (0, import_core.composeEventHandlers)(itemProps.onPointerMove, (event) => {
296
- if (disabled) {
297
- contentContext.onItemLeave();
298
- } else {
299
- event.currentTarget.focus({ preventScroll: true });
300
- }
301
- }),
302
- onPointerLeave: (0, import_core.composeEventHandlers)(itemProps.onPointerLeave, (event) => {
303
- if (event.currentTarget === document.activeElement) {
304
- contentContext.onItemLeave();
305
- }
306
- }),
307
- onKeyDown: (0, import_core.composeEventHandlers)(itemProps.onKeyDown, (event) => {
308
- const isTypingAhead = contentContext.searchRef.current !== "";
309
- if (isTypingAhead && event.key === " ")
310
- return;
311
- if (SELECTION_KEYS.includes(event.key))
312
- handleSelect();
313
- if (event.key === " ")
314
- event.preventDefault();
315
- })
316
- }))));
297
+ tabIndex: disabled ? void 0 : -1,
298
+ size: context.size
299
+ }, itemProps), selectItemProps)));
317
300
  });
318
301
  SelectItem.displayName = ITEM_NAME;
319
302
  const ITEM_TEXT_NAME = "SelectItemText";
303
+ const SelectItemTextFrame = (0, import_core.styled)(import_text.Paragraph, {
304
+ name: ITEM_TEXT_NAME,
305
+ selectable: false
306
+ });
320
307
  const SelectItemText = React.forwardRef((props, forwardedRef) => {
321
- var _b;
322
308
  const _a = props, { __scopeSelect, className, style } = _a, itemTextProps = __objRest(_a, ["__scopeSelect", "className", "style"]);
323
309
  const context = useSelectContext(ITEM_TEXT_NAME, __scopeSelect);
324
- const contentContext = useSelectContentContext(ITEM_TEXT_NAME, __scopeSelect);
325
310
  const itemContext = useSelectItemContext(ITEM_TEXT_NAME, __scopeSelect);
326
311
  const ref = React.useRef(null);
327
- const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, ref, itemContext.onItemTextChange, itemContext.isSelected ? contentContext.onSelectedItemTextChange : void 0);
328
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Primitive.span, __spreadProps(__spreadValues({
312
+ const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, ref, itemContext.onItemTextChange);
313
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(SelectItemTextFrame, __spreadProps(__spreadValues({
314
+ size: context.size,
329
315
  id: itemContext.textId
330
316
  }, itemTextProps), {
331
317
  ref: composedRefs
332
- })), itemContext.isSelected && context.valueNode && !context.valueNodeHasChildren ? ReactDOM.createPortal(itemTextProps.children, context.valueNode) : null, context.bubbleSelect ? ReactDOM.createPortal(/* @__PURE__ */ React.createElement("option", {
333
- value: itemContext.value
334
- }, (_b = ref.current) == null ? void 0 : _b.textContent), context.bubbleSelect) : null);
318
+ })), itemContext.isSelected && context.valueNode && !context.valueNodeHasChildren ? ReactDOM.createPortal(itemTextProps.children, context.valueNode) : null);
335
319
  });
336
320
  SelectItemText.displayName = ITEM_TEXT_NAME;
337
321
  const ITEM_INDICATOR_NAME = "SelectItemIndicator";
322
+ const SelectItemIndicatorFrame = (0, import_core.styled)(import_stacks.XStack, {
323
+ name: ITEM_TEXT_NAME
324
+ });
338
325
  const SelectItemIndicator = React.forwardRef((props, forwardedRef) => {
339
326
  const _a = props, { __scopeSelect } = _a, itemIndicatorProps = __objRest(_a, ["__scopeSelect"]);
340
327
  const itemContext = useSelectItemContext(ITEM_INDICATOR_NAME, __scopeSelect);
341
- return itemContext.isSelected ? /* @__PURE__ */ React.createElement(Primitive.span, __spreadProps(__spreadValues({
328
+ return itemContext.isSelected ? /* @__PURE__ */ React.createElement(SelectItemIndicatorFrame, __spreadProps(__spreadValues({
342
329
  "aria-hidden": true
343
330
  }, itemIndicatorProps), {
344
331
  ref: forwardedRef
345
332
  })) : null;
346
333
  });
347
334
  SelectItemIndicator.displayName = ITEM_INDICATOR_NAME;
335
+ const GROUP_NAME = "SelectGroup";
336
+ const [SelectGroupContextProvider, useSelectGroupContext] = createSelectContext(GROUP_NAME);
337
+ const SelectGroupFrame = (0, import_core.styled)(import_stacks.YStack, {
338
+ name: GROUP_NAME,
339
+ width: "100%"
340
+ });
341
+ const SelectGroup = React.forwardRef((props, forwardedRef) => {
342
+ const _a = props, { __scopeSelect } = _a, groupProps = __objRest(_a, ["__scopeSelect"]);
343
+ const groupId = (0, import_core2.useId)();
344
+ return /* @__PURE__ */ React.createElement(SelectGroupContextProvider, {
345
+ scope: __scopeSelect,
346
+ id: groupId || ""
347
+ }, /* @__PURE__ */ React.createElement(SelectGroupFrame, __spreadProps(__spreadValues({
348
+ role: "group",
349
+ "aria-labelledby": groupId
350
+ }, groupProps), {
351
+ ref: forwardedRef
352
+ })));
353
+ });
354
+ SelectGroup.displayName = GROUP_NAME;
355
+ const LABEL_NAME = "SelectLabel";
356
+ const SelectLabel = React.forwardRef((props, forwardedRef) => {
357
+ const _a = props, { __scopeSelect } = _a, labelProps = __objRest(_a, ["__scopeSelect"]);
358
+ const context = useSelectContext(LABEL_NAME, __scopeSelect);
359
+ const groupContext = useSelectGroupContext(LABEL_NAME, __scopeSelect);
360
+ return /* @__PURE__ */ React.createElement(import_list_item.ListItem, __spreadProps(__spreadValues({
361
+ componentName: LABEL_NAME,
362
+ fontWeight: "800",
363
+ id: groupContext.id,
364
+ size: context.size
365
+ }, labelProps), {
366
+ ref: forwardedRef
367
+ }));
368
+ });
369
+ SelectLabel.displayName = LABEL_NAME;
348
370
  const SCROLL_UP_BUTTON_NAME = "SelectScrollUpButton";
349
371
  const SelectScrollUpButton = React.forwardRef((props, forwardedRef) => {
350
- const contentContext = useSelectContentContext(SCROLL_UP_BUTTON_NAME, props.__scopeSelect);
351
- const [canScrollUp, setCanScrollUp] = React.useState(false);
352
- const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, contentContext.onScrollButtonChange);
353
- return canScrollUp ? /* @__PURE__ */ React.createElement(SelectScrollButtonImpl, __spreadProps(__spreadValues({}, props), {
354
- ref: composedRefs,
355
- onAutoScroll: () => {
356
- const { viewport, selectedItem } = contentContext;
357
- if (viewport && selectedItem) {
358
- viewport.scrollTop = viewport.scrollTop - selectedItem.offsetHeight;
359
- }
360
- }
361
- })) : null;
372
+ return /* @__PURE__ */ React.createElement(SelectScrollButtonImpl, __spreadProps(__spreadValues({
373
+ componentName: SCROLL_UP_BUTTON_NAME
374
+ }, props), {
375
+ dir: "up",
376
+ ref: forwardedRef
377
+ }));
362
378
  });
363
379
  SelectScrollUpButton.displayName = SCROLL_UP_BUTTON_NAME;
364
380
  const SCROLL_DOWN_BUTTON_NAME = "SelectScrollDownButton";
365
381
  const SelectScrollDownButton = React.forwardRef((props, forwardedRef) => {
366
- const contentContext = useSelectContentContext(SCROLL_DOWN_BUTTON_NAME, props.__scopeSelect);
367
- const [canScrollDown, setCanScrollDown] = React.useState(false);
368
- const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, contentContext.onScrollButtonChange);
369
- return canScrollDown ? /* @__PURE__ */ React.createElement(SelectScrollButtonImpl, __spreadProps(__spreadValues({}, props), {
370
- ref: composedRefs,
371
- onAutoScroll: () => {
372
- const { viewport, selectedItem } = contentContext;
373
- if (viewport && selectedItem) {
374
- viewport.scrollTop = viewport.scrollTop + selectedItem.offsetHeight;
375
- }
376
- }
377
- })) : null;
382
+ return /* @__PURE__ */ React.createElement(SelectScrollButtonImpl, __spreadProps(__spreadValues({
383
+ componentName: SCROLL_DOWN_BUTTON_NAME
384
+ }, props), {
385
+ dir: "down",
386
+ ref: forwardedRef
387
+ }));
378
388
  });
379
389
  SelectScrollDownButton.displayName = SCROLL_DOWN_BUTTON_NAME;
380
390
  const SelectScrollButtonImpl = React.forwardRef((props, forwardedRef) => {
381
- const _a = props, { __scopeSelect, onAutoScroll } = _a, scrollIndicatorProps = __objRest(_a, ["__scopeSelect", "onAutoScroll"]);
382
- const contentContext = useSelectContentContext("SelectScrollButton", __scopeSelect);
383
- const autoScrollTimerRef = React.useRef(null);
391
+ var _c;
392
+ const _a = props, { __scopeSelect, dir, componentName } = _a, scrollIndicatorProps = __objRest(_a, ["__scopeSelect", "dir", "componentName"]);
393
+ const _b = useSelectContext(componentName, __scopeSelect), { floatingRef, increaseHeight, forceUpdate } = _b, context = __objRest(_b, ["floatingRef", "increaseHeight", "forceUpdate"]);
384
394
  const intervalRef = React.useRef();
385
395
  const loopingRef = React.useRef(false);
396
+ const isVisible = context[dir === "down" ? "canScrollDown" : "canScrollUp"];
386
397
  const { x, y, reference, floating, strategy, update, refs } = (0, import_react_dom_interactions.useFloating)({
387
398
  strategy: "fixed",
388
399
  placement: dir === "up" ? "top" : "bottom",
389
- middleware: [(0, import_react_dom_interactions.offset)(({ floating: floating2 }) => -floating2.height)]
400
+ middleware: [(0, import_react_dom_interactions.offset)(({ rects }) => -rects.floating.height)]
390
401
  });
391
- return /* @__PURE__ */ React.createElement(Primitive.div, __spreadProps(__spreadValues({
402
+ const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, floating);
403
+ React.useLayoutEffect(() => {
404
+ reference(floatingRef.current);
405
+ }, [reference, floatingRef.current]);
406
+ React.useEffect(() => {
407
+ if (!refs.reference.current || !refs.floating.current || !isVisible) {
408
+ return;
409
+ }
410
+ const cleanup = (0, import_react_dom_interactions.autoUpdate)(refs.reference.current, refs.floating.current, update, {
411
+ animationFrame: true
412
+ });
413
+ return () => {
414
+ clearInterval(intervalRef.current);
415
+ loopingRef.current = false;
416
+ cleanup();
417
+ };
418
+ }, [isVisible, update, refs.floating, refs.reference]);
419
+ if (!isVisible) {
420
+ return null;
421
+ }
422
+ const handleScrollArrowChange = () => {
423
+ const floating2 = floatingRef.current;
424
+ const isUp = dir === "up";
425
+ if (floating2) {
426
+ const value = isUp ? -SCROLL_ARROW_VELOCITY : SCROLL_ARROW_VELOCITY;
427
+ const multi = isUp && floating2.scrollTop <= SCROLL_ARROW_THRESHOLD * 2 || !isUp && floating2.scrollTop >= floating2.scrollHeight - floating2.clientHeight - SCROLL_ARROW_THRESHOLD * 2 ? 2 : 1;
428
+ floating2.scrollTop += multi * (isUp ? -SCROLL_ARROW_VELOCITY : SCROLL_ARROW_VELOCITY);
429
+ increaseHeight(floating2, multi === 2 ? value * 2 : value);
430
+ forceUpdate();
431
+ }
432
+ };
433
+ return /* @__PURE__ */ React.createElement(import_stacks.YStack, __spreadProps(__spreadValues({
434
+ ref: composedRefs,
435
+ componentName,
392
436
  "aria-hidden": true
393
437
  }, scrollIndicatorProps), {
394
- ref: forwardedRef,
395
- style: __spreadValues({ flexShrink: 0 }, scrollIndicatorProps.style),
396
- onPointerMove: (0, import_core.composeEventHandlers)(scrollIndicatorProps.onPointerMove, () => {
397
- contentContext.onItemLeave();
398
- if (autoScrollTimerRef.current === null) {
399
- autoScrollTimerRef.current = window.setInterval(onAutoScroll, 50);
438
+ zIndex: 1e3,
439
+ position: strategy,
440
+ left: x || 0,
441
+ top: y || 0,
442
+ width: `calc(${(((_c = floatingRef.current) == null ? void 0 : _c.offsetWidth) ?? 0) - 2}px)`,
443
+ onPointerMove: () => {
444
+ if (!loopingRef.current) {
445
+ intervalRef.current = setInterval(handleScrollArrowChange, 1e3 / 60);
446
+ loopingRef.current = true;
400
447
  }
401
- }),
402
- onPointerLeave: (0, import_core.composeEventHandlers)(scrollIndicatorProps.onPointerLeave, () => {
403
- clearAutoScrollTimer();
404
- })
448
+ },
449
+ onPointerLeave: () => {
450
+ loopingRef.current = false;
451
+ clearInterval(intervalRef.current);
452
+ }
405
453
  }));
406
454
  });
407
- const SEPARATOR_NAME = "SelectSeparator";
408
- const SelectSeparator = import_separator.Separator;
409
- SelectSeparator.displayName = SEPARATOR_NAME;
410
- const BubbleSelect = React.forwardRef((props, forwardedRef) => {
411
- const _a = props, { value } = _a, selectProps = __objRest(_a, ["value"]);
412
- const ref = React.useRef(null);
413
- const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, ref);
414
- const prevValue = (0, import_react_use_previous.usePrevious)(value);
455
+ const SelectSeparator = (0, import_core.styled)(import_separator.Separator, {
456
+ name: "SelectSeparator"
457
+ });
458
+ const Select = (0, import_core.withStaticProperties)((props) => {
459
+ const {
460
+ id,
461
+ __scopeSelect,
462
+ children,
463
+ open: openProp,
464
+ defaultOpen,
465
+ onOpenChange,
466
+ value: valueProp,
467
+ defaultValue,
468
+ onValueChange,
469
+ size: sizeProp,
470
+ dir,
471
+ name,
472
+ autoComplete
473
+ } = props;
474
+ const [open, setOpen] = (0, import_use_controllable_state.useControllableState)({
475
+ prop: openProp,
476
+ defaultProp: defaultOpen || false,
477
+ onChange: onOpenChange
478
+ });
479
+ const [value, setValue] = (0, import_use_controllable_state.useControllableState)({
480
+ prop: valueProp,
481
+ defaultProp: defaultValue || "",
482
+ onChange: onValueChange
483
+ });
484
+ const [activeIndex, setActiveIndex] = React.useState(null);
485
+ const selectedIndexRef = React.useRef(null);
486
+ const activeIndexRef = React.useRef(null);
487
+ const prevActiveIndex = (0, import_react_use_previous.usePrevious)(activeIndex);
488
+ const [showArrows, setShowArrows] = React.useState(false);
489
+ const [scrollTop, setScrollTop] = React.useState(0);
490
+ const listItemsRef = React.useRef([]);
491
+ const listContentRef = React.useRef([]);
492
+ const [selectedIndex, setSelectedIndex] = React.useState(Math.max(0, listContentRef.current.indexOf(value)));
493
+ const [controlledScrolling, setControlledScrolling] = React.useState(false);
494
+ const [middlewareType, setMiddlewareType] = React.useState("align");
495
+ (0, import_core.useIsomorphicLayoutEffect)(() => {
496
+ selectedIndexRef.current = selectedIndex;
497
+ activeIndexRef.current = activeIndex;
498
+ });
415
499
  React.useEffect(() => {
416
- const select = ref.current;
417
- const selectProto = window.HTMLSelectElement.prototype;
418
- const descriptor = Object.getOwnPropertyDescriptor(selectProto, "value");
419
- const setValue = descriptor.set;
420
- if (prevValue !== value && setValue) {
421
- const event = new Event("change", { bubbles: true });
422
- setValue.call(select, value);
423
- select.dispatchEvent(event);
500
+ const frame = requestAnimationFrame(() => {
501
+ setShowArrows(open);
502
+ if (!open) {
503
+ setScrollTop(0);
504
+ setMiddlewareType("align");
505
+ setActiveIndex(null);
506
+ setControlledScrolling(false);
507
+ }
508
+ });
509
+ return () => {
510
+ cancelAnimationFrame(frame);
511
+ };
512
+ }, [open]);
513
+ function getFloatingPadding(floating2) {
514
+ var _a;
515
+ if (!floating2) {
516
+ return 0;
424
517
  }
425
- }, [prevValue, value]);
426
- return null;
427
- return /* @__PURE__ */ React.createElement(VisuallyHidden, {
428
- asChild: true
429
- }, /* @__PURE__ */ React.createElement("select", __spreadProps(__spreadValues({}, selectProps), {
430
- ref: composedRefs,
431
- defaultValue: value
432
- })));
518
+ return Number((_a = getComputedStyle(floating2).paddingLeft) == null ? void 0 : _a.replace("px", ""));
519
+ }
520
+ const { x, y, reference, floating, strategy, context, refs, middlewareData, update } = (0, import_react_dom_interactions.useFloating)({
521
+ open,
522
+ onOpenChange: setOpen,
523
+ placement: "bottom",
524
+ middleware: middlewareType === "align" ? [
525
+ (0, import_react_dom_interactions.offset)(({ rects }) => {
526
+ const index = activeIndexRef.current ?? selectedIndexRef.current;
527
+ if (index == null) {
528
+ return 0;
529
+ }
530
+ const item = listItemsRef.current[index];
531
+ if (item == null) {
532
+ return 0;
533
+ }
534
+ const offsetTop = item.offsetTop;
535
+ const itemHeight = item.offsetHeight;
536
+ const height = rects.reference.height;
537
+ return -offsetTop - height - (itemHeight - height) / 2;
538
+ }),
539
+ {
540
+ name: "size",
541
+ async fn(args) {
542
+ var _a;
543
+ const {
544
+ elements: { floating: floating2 },
545
+ rects: { reference: reference2 },
546
+ middlewareData: middlewareData2
547
+ } = args;
548
+ const overflow = await (0, import_react_dom_interactions.detectOverflow)(args, {
549
+ padding: WINDOW_PADDING
550
+ });
551
+ const top = Math.max(0, overflow.top);
552
+ const bottom = Math.max(0, overflow.bottom);
553
+ const nextY = args.y + top;
554
+ if ((_a = middlewareData2.size) == null ? void 0 : _a.skip) {
555
+ return {
556
+ y: nextY,
557
+ data: {
558
+ y: middlewareData2.size.y
559
+ }
560
+ };
561
+ }
562
+ Object.assign(floating2.style, {
563
+ maxHeight: `${floating2.scrollHeight - Math.abs(top + bottom)}px`,
564
+ minWidth: `${reference2.width + getFloatingPadding(floating2) * 2}px`
565
+ });
566
+ return {
567
+ y: nextY,
568
+ data: {
569
+ y: top,
570
+ skip: true
571
+ },
572
+ reset: {
573
+ rects: true
574
+ }
575
+ };
576
+ }
577
+ }
578
+ ] : [
579
+ (0, import_react_dom_interactions.offset)(5),
580
+ (0, import_react_dom_interactions.flip)(),
581
+ (0, import_react_dom_interactions.size)({
582
+ apply({ rects, availableHeight, elements }) {
583
+ Object.assign(elements.floating.style, {
584
+ width: `${rects.reference.width}px`,
585
+ maxHeight: `${availableHeight}px`
586
+ });
587
+ },
588
+ padding: WINDOW_PADDING
589
+ })
590
+ ]
591
+ });
592
+ const floatingRef = refs.floating;
593
+ const forceUpdate = React.useReducer(() => ({}), {})[1];
594
+ const showUpArrow = showArrows && scrollTop > SCROLL_ARROW_THRESHOLD;
595
+ const showDownArrow = showArrows && floatingRef.current && scrollTop < floatingRef.current.scrollHeight - floatingRef.current.clientHeight - SCROLL_ARROW_THRESHOLD;
596
+ const interactions = (0, import_react_dom_interactions.useInteractions)([
597
+ (0, import_react_dom_interactions.useClick)(context, { pointerDown: true }),
598
+ (0, import_react_dom_interactions.useRole)(context, { role: "listbox" }),
599
+ (0, import_react_dom_interactions.useDismiss)(context),
600
+ (0, import_react_dom_interactions.useListNavigation)(context, {
601
+ listRef: listItemsRef,
602
+ activeIndex,
603
+ selectedIndex,
604
+ onNavigate: setActiveIndex
605
+ }),
606
+ (0, import_react_dom_interactions.useTypeahead)(context, {
607
+ listRef: listContentRef,
608
+ onMatch: open ? setActiveIndex : setSelectedIndex,
609
+ selectedIndex,
610
+ activeIndex
611
+ })
612
+ ]);
613
+ const increaseHeight = React.useCallback((floating2, amount = 0) => {
614
+ if (middlewareType === "fallback") {
615
+ return;
616
+ }
617
+ const currentMaxHeight = Number(floating2.style.maxHeight.replace("px", ""));
618
+ const currentTop = Number(floating2.style.top.replace("px", ""));
619
+ const rect = floating2.getBoundingClientRect();
620
+ const rectTop = rect.top;
621
+ const rectBottom = rect.bottom;
622
+ const viewportHeight = (visualViewport == null ? void 0 : visualViewport.height) ?? 0;
623
+ const visualMaxHeight = viewportHeight - WINDOW_PADDING * 2;
624
+ if (amount < 0 && selectedIndexRef.current != null && Math.round(rectBottom) < Math.round(viewportHeight + getVisualOffsetTop() - WINDOW_PADDING)) {
625
+ floating2.style.maxHeight = `${Math.min(visualMaxHeight, currentMaxHeight - amount)}px`;
626
+ }
627
+ if (amount > 0 && Math.round(rectTop) > Math.round(WINDOW_PADDING - getVisualOffsetTop()) && floating2.scrollHeight > floating2.offsetHeight) {
628
+ const nextTop = Math.max(WINDOW_PADDING + getVisualOffsetTop(), currentTop - amount);
629
+ const nextMaxHeight = Math.min(visualMaxHeight, currentMaxHeight + amount);
630
+ Object.assign(floating2.style, {
631
+ maxHeight: `${nextMaxHeight}px`,
632
+ top: `${nextTop}px`
633
+ });
634
+ if (nextTop - WINDOW_PADDING > getVisualOffsetTop()) {
635
+ floating2.scrollTop -= nextMaxHeight - currentMaxHeight + getFloatingPadding(floating2);
636
+ }
637
+ return currentTop - nextTop;
638
+ }
639
+ }, [middlewareType]);
640
+ const touchPageYRef = React.useRef(null);
641
+ const handleWheel = React.useCallback((event) => {
642
+ var _a;
643
+ const pinching = event.ctrlKey;
644
+ const currentTarget = event.currentTarget;
645
+ function isWheelEvent(event2) {
646
+ return typeof event2.deltaY === "number";
647
+ }
648
+ function isTouchEvent(event2) {
649
+ return event2.touches != null;
650
+ }
651
+ if (Math.abs(((currentTarget == null ? void 0 : currentTarget.offsetHeight) ?? 0) - (((visualViewport == null ? void 0 : visualViewport.height) ?? 0) - WINDOW_PADDING * 2)) > 1 && !pinching) {
652
+ event.preventDefault();
653
+ } else if (isWheelEvent(event) && isFirefox) {
654
+ currentTarget.scrollTop += event.deltaY;
655
+ }
656
+ if (!pinching) {
657
+ let delta = 5;
658
+ if (isTouchEvent(event)) {
659
+ const currentPageY = touchPageYRef.current;
660
+ const pageY = (_a = event.touches[0]) == null ? void 0 : _a.pageY;
661
+ if (pageY != null) {
662
+ touchPageYRef.current = pageY;
663
+ if (currentPageY != null) {
664
+ delta = currentPageY - pageY;
665
+ }
666
+ }
667
+ }
668
+ increaseHeight(currentTarget, isWheelEvent(event) ? event.deltaY : delta);
669
+ setScrollTop(currentTarget.scrollTop);
670
+ forceUpdate();
671
+ }
672
+ }, [increaseHeight, forceUpdate]);
673
+ React.useEffect(() => {
674
+ function onTouchEnd() {
675
+ touchPageYRef.current = null;
676
+ }
677
+ const floating2 = floatingRef.current;
678
+ if (open && floating2 && middlewareType === "align") {
679
+ floating2.addEventListener("wheel", handleWheel);
680
+ floating2.addEventListener("touchmove", handleWheel);
681
+ floating2.addEventListener("touchend", onTouchEnd, { passive: true });
682
+ return () => {
683
+ floating2.removeEventListener("wheel", handleWheel);
684
+ floating2.removeEventListener("touchmove", handleWheel);
685
+ floating2.removeEventListener("touchend", onTouchEnd);
686
+ };
687
+ }
688
+ }, [open, floatingRef, handleWheel, middlewareType]);
689
+ React.useEffect(() => {
690
+ window.addEventListener("resize", update);
691
+ return () => {
692
+ window.removeEventListener("resize", update);
693
+ };
694
+ }, [update]);
695
+ React.useLayoutEffect(() => {
696
+ var _a;
697
+ const floating2 = floatingRef.current;
698
+ if (open && controlledScrolling && floating2) {
699
+ const item = activeIndex != null ? listItemsRef.current[activeIndex] : selectedIndex != null ? listItemsRef.current[selectedIndex] : null;
700
+ if (item && prevActiveIndex != null) {
701
+ const itemHeight = ((_a = listItemsRef.current[prevActiveIndex]) == null ? void 0 : _a.offsetHeight) ?? 0;
702
+ const floatingHeight = floating2.offsetHeight;
703
+ const top = item.offsetTop;
704
+ const bottom = top + itemHeight;
705
+ if (top < floating2.scrollTop + 20) {
706
+ const diff = floating2.scrollTop - top + 20;
707
+ floating2.scrollTop -= diff;
708
+ if (activeIndex != selectedIndex && activeIndex != null) {
709
+ increaseHeight(floating2, -diff);
710
+ }
711
+ } else if (bottom > floatingHeight + floating2.scrollTop - 20) {
712
+ const diff = bottom - floatingHeight - floating2.scrollTop + 20;
713
+ floating2.scrollTop += diff;
714
+ if (activeIndex != selectedIndex && activeIndex != null) {
715
+ floating2.scrollTop -= increaseHeight(floating2, diff) ?? 0;
716
+ }
717
+ }
718
+ }
719
+ }
720
+ }, [
721
+ open,
722
+ controlledScrolling,
723
+ prevActiveIndex,
724
+ activeIndex,
725
+ selectedIndex,
726
+ floatingRef,
727
+ increaseHeight
728
+ ]);
729
+ React.useLayoutEffect(() => {
730
+ var _a;
731
+ const floating2 = refs.floating.current;
732
+ const reference2 = refs.reference.current;
733
+ if (open && floating2 && reference2 && floating2.offsetHeight < floating2.scrollHeight) {
734
+ const referenceRect = reference2.getBoundingClientRect();
735
+ if (middlewareType === "fallback") {
736
+ const item = listItemsRef.current[selectedIndex];
737
+ if (item) {
738
+ floating2.scrollTop = item.offsetTop - floating2.clientHeight + referenceRect.height;
739
+ }
740
+ return;
741
+ }
742
+ floating2.scrollTop = (_a = middlewareData.size) == null ? void 0 : _a.y;
743
+ const closeToBottom = ((visualViewport == null ? void 0 : visualViewport.height) ?? 0) + getVisualOffsetTop() - referenceRect.bottom < FALLBACK_THRESHOLD;
744
+ const closeToTop = referenceRect.top < FALLBACK_THRESHOLD;
745
+ if (floating2.offsetHeight < MIN_HEIGHT || closeToTop || closeToBottom) {
746
+ setMiddlewareType("fallback");
747
+ }
748
+ }
749
+ }, [
750
+ open,
751
+ increaseHeight,
752
+ selectedIndex,
753
+ middlewareType,
754
+ refs.floating,
755
+ refs.reference,
756
+ middlewareData
757
+ ]);
758
+ React.useLayoutEffect(() => {
759
+ if (open && selectedIndex != null) {
760
+ requestAnimationFrame(() => {
761
+ var _a;
762
+ (_a = listItemsRef.current[selectedIndex]) == null ? void 0 : _a.focus({ preventScroll: true });
763
+ });
764
+ }
765
+ }, [listItemsRef, selectedIndex, open]);
766
+ React.useEffect(() => {
767
+ const frame = requestAnimationFrame(() => {
768
+ setShowArrows(open);
769
+ if (!open) {
770
+ setScrollTop(0);
771
+ setMiddlewareType("align");
772
+ setActiveIndex(null);
773
+ setControlledScrolling(false);
774
+ }
775
+ });
776
+ return () => cancelAnimationFrame(frame);
777
+ }, [open]);
778
+ const [valueNode, setValueNode] = React.useState(null);
779
+ const [valueNodeHasChildren, setValueNodeHasChildren] = React.useState(false);
780
+ return /* @__PURE__ */ React.createElement(SelectProvider, {
781
+ size: sizeProp,
782
+ scope: __scopeSelect,
783
+ increaseHeight,
784
+ forceUpdate,
785
+ floatingRef,
786
+ valueNode,
787
+ onValueNodeChange: setValueNode,
788
+ valueNodeHasChildren,
789
+ onValueNodeHasChildrenChange: setValueNodeHasChildren,
790
+ setValueAtIndex: (index, value2) => {
791
+ listContentRef.current[index] = value2;
792
+ },
793
+ interactions: __spreadProps(__spreadValues({}, interactions), {
794
+ getReferenceProps() {
795
+ return interactions.getReferenceProps({
796
+ ref: reference,
797
+ className: "SelectTrigger",
798
+ onKeyDown(event) {
799
+ if (event.key === "Enter" || event.key === " " && !context.dataRef.current.typing) {
800
+ event.preventDefault();
801
+ setOpen(true);
802
+ }
803
+ }
804
+ });
805
+ },
806
+ getFloatingProps(props2) {
807
+ return interactions.getFloatingProps(__spreadProps(__spreadValues({
808
+ ref: floating,
809
+ className: "Select"
810
+ }, props2), {
811
+ style: __spreadValues({
812
+ position: strategy,
813
+ top: y ?? "",
814
+ left: x ?? "",
815
+ outline: 0,
816
+ listStyleType: "none",
817
+ scrollbarWidth: "none",
818
+ userSelect: "none"
819
+ }, props2 == null ? void 0 : props2.style),
820
+ onPointerEnter() {
821
+ setControlledScrolling(false);
822
+ },
823
+ onPointerMove() {
824
+ setControlledScrolling(false);
825
+ },
826
+ onKeyDown() {
827
+ setControlledScrolling(true);
828
+ },
829
+ onScroll(event) {
830
+ setScrollTop(event.currentTarget.scrollTop);
831
+ }
832
+ }));
833
+ }
834
+ }),
835
+ floatingContext: context,
836
+ activeIndex,
837
+ canScrollDown: !!showDownArrow,
838
+ canScrollUp: !!showUpArrow,
839
+ controlledScrolling: true,
840
+ dataRef: context.dataRef,
841
+ listRef: listItemsRef,
842
+ onChange: setValue,
843
+ selectedIndex,
844
+ setActiveIndex,
845
+ setOpen,
846
+ setSelectedIndex,
847
+ value,
848
+ open
849
+ }, children);
850
+ }, {
851
+ Content: SelectContent,
852
+ Group: SelectGroup,
853
+ Icon: SelectIcon,
854
+ Item: SelectItem,
855
+ ItemIndicator: SelectItemIndicator,
856
+ ItemText: SelectItemText,
857
+ Label: SelectLabel,
858
+ ScrollDownButton: SelectScrollDownButton,
859
+ ScrollUpButton: SelectScrollUpButton,
860
+ Trigger: SelectTrigger,
861
+ Value: SelectValue,
862
+ Viewport: SelectViewport
433
863
  });
864
+ Select.displayName = SELECT_NAME;
434
865
  // Annotate the CommonJS export names for ESM import in node:
435
866
  0 && (module.exports = {
436
867
  Select,
437
- SelectContent,
438
- SelectGroup,
868
+ SelectGroupFrame,
439
869
  SelectIcon,
440
870
  SelectItem,
441
- SelectItemIndicator,
442
- SelectItemText,
443
- SelectLabel,
444
- SelectScrollDownButton,
445
- SelectScrollUpButton,
871
+ SelectItemTextFrame,
446
872
  SelectSeparator,
447
873
  SelectTrigger,
448
- SelectValue,
874
+ SelectViewport,
875
+ SelectViewportFrame,
449
876
  createSelectScope
450
877
  });
451
878
  //# sourceMappingURL=Select.js.map