@tamagui/select 1.0.0-beta.17 → 1.0.1-beta.102

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