@tamagui/select 1.0.1-beta.99 → 1.0.1-rc.0

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.
Files changed (114) hide show
  1. package/dist/cjs/BubbleSelect.js +25 -33
  2. package/dist/cjs/BubbleSelect.js.map +1 -1
  3. package/dist/cjs/Select.js +391 -789
  4. package/dist/cjs/Select.js.map +3 -3
  5. package/dist/cjs/SelectContent.js +72 -0
  6. package/dist/cjs/SelectContent.js.map +7 -0
  7. package/dist/cjs/SelectContent.native.js +31 -0
  8. package/dist/cjs/SelectContent.native.js.map +7 -0
  9. package/dist/cjs/SelectImpl.js +288 -0
  10. package/dist/cjs/SelectImpl.js.map +7 -0
  11. package/dist/cjs/SelectScrollButton.js +157 -0
  12. package/dist/cjs/SelectScrollButton.js.map +7 -0
  13. package/dist/cjs/SelectScrollButton.native.js +32 -0
  14. package/dist/cjs/SelectScrollButton.native.js.map +7 -0
  15. package/dist/cjs/SelectViewport.js +125 -0
  16. package/dist/cjs/SelectViewport.js.map +7 -0
  17. package/dist/cjs/SelectViewport.native.js +41 -0
  18. package/dist/cjs/SelectViewport.native.js.map +7 -0
  19. package/dist/cjs/constants.js +47 -0
  20. package/dist/cjs/constants.js.map +7 -0
  21. package/dist/cjs/context.js +49 -0
  22. package/dist/cjs/context.js.map +7 -0
  23. package/dist/cjs/index.js +2 -0
  24. package/dist/cjs/index.js.map +2 -2
  25. package/dist/cjs/types.js +17 -0
  26. package/dist/cjs/types.js.map +7 -0
  27. package/dist/cjs/useSelectBreakpointActive.js +39 -0
  28. package/dist/cjs/useSelectBreakpointActive.js.map +7 -0
  29. package/dist/esm/BubbleSelect.js +20 -33
  30. package/dist/esm/BubbleSelect.js.map +1 -1
  31. package/dist/esm/Select.js +379 -803
  32. package/dist/esm/Select.js.map +3 -3
  33. package/dist/esm/SelectContent.js +48 -0
  34. package/dist/esm/SelectContent.js.map +7 -0
  35. package/dist/esm/SelectContent.native.js +7 -0
  36. package/dist/esm/SelectContent.native.js.map +7 -0
  37. package/dist/esm/SelectImpl.js +273 -0
  38. package/dist/esm/SelectImpl.js.map +7 -0
  39. package/dist/esm/SelectScrollButton.js +126 -0
  40. package/dist/esm/SelectScrollButton.js.map +7 -0
  41. package/dist/esm/SelectScrollButton.native.js +7 -0
  42. package/dist/esm/SelectScrollButton.native.js.map +7 -0
  43. package/dist/esm/SelectViewport.js +94 -0
  44. package/dist/esm/SelectViewport.js.map +7 -0
  45. package/dist/esm/SelectViewport.native.js +17 -0
  46. package/dist/esm/SelectViewport.native.js.map +7 -0
  47. package/dist/esm/constants.js +17 -0
  48. package/dist/esm/constants.js.map +7 -0
  49. package/dist/esm/context.js +21 -0
  50. package/dist/esm/context.js.map +7 -0
  51. package/dist/esm/index.js +1 -0
  52. package/dist/esm/index.js.map +2 -2
  53. package/dist/esm/types.js +1 -0
  54. package/dist/esm/types.js.map +7 -0
  55. package/dist/esm/useSelectBreakpointActive.js +14 -0
  56. package/dist/esm/useSelectBreakpointActive.js.map +7 -0
  57. package/dist/jsx/BubbleSelect.js +20 -18
  58. package/dist/jsx/BubbleSelect.js.map +1 -1
  59. package/dist/jsx/Select.js +259 -656
  60. package/dist/jsx/Select.js.map +3 -3
  61. package/dist/jsx/SelectContent.js +27 -0
  62. package/dist/jsx/SelectContent.js.map +7 -0
  63. package/dist/jsx/SelectContent.native.js +7 -0
  64. package/dist/jsx/SelectContent.native.js.map +7 -0
  65. package/dist/jsx/SelectImpl.js +246 -0
  66. package/dist/jsx/SelectImpl.js.map +7 -0
  67. package/dist/jsx/SelectScrollButton.js +99 -0
  68. package/dist/jsx/SelectScrollButton.js.map +7 -0
  69. package/dist/jsx/SelectScrollButton.native.js +7 -0
  70. package/dist/jsx/SelectScrollButton.native.js.map +7 -0
  71. package/dist/jsx/SelectViewport.js +72 -0
  72. package/dist/jsx/SelectViewport.js.map +7 -0
  73. package/dist/jsx/SelectViewport.native.js +13 -0
  74. package/dist/jsx/SelectViewport.native.js.map +7 -0
  75. package/dist/jsx/constants.js +17 -0
  76. package/dist/jsx/constants.js.map +7 -0
  77. package/dist/jsx/context.js +15 -0
  78. package/dist/jsx/context.js.map +7 -0
  79. package/dist/jsx/index.js +1 -0
  80. package/dist/jsx/index.js.map +2 -2
  81. package/dist/jsx/types.js +1 -0
  82. package/dist/jsx/types.js.map +7 -0
  83. package/dist/jsx/useSelectBreakpointActive.js +14 -0
  84. package/dist/jsx/useSelectBreakpointActive.js.map +7 -0
  85. package/package.json +26 -20
  86. package/src/Select.tsx +210 -906
  87. package/src/SelectContent.native.tsx +5 -0
  88. package/src/SelectContent.tsx +45 -0
  89. package/src/SelectImpl.tsx +344 -0
  90. package/src/SelectScrollButton.native.tsx +7 -0
  91. package/src/SelectScrollButton.tsx +168 -0
  92. package/src/SelectViewport.native.tsx +14 -0
  93. package/src/SelectViewport.tsx +104 -0
  94. package/src/constants.tsx +7 -0
  95. package/src/context.tsx +19 -0
  96. package/src/index.tsx +7 -0
  97. package/src/types.tsx +91 -0
  98. package/src/useSelectBreakpointActive.tsx +15 -0
  99. package/types/BubbleSelect.d.ts +2 -0
  100. package/types/Select.d.ts +449 -599
  101. package/types/SelectContent.d.ts +5 -0
  102. package/types/SelectContent.native.d.ts +4 -0
  103. package/types/SelectImpl.d.ts +9 -0
  104. package/types/SelectScrollButton.d.ts +6 -0
  105. package/types/SelectScrollButton.native.d.ts +4 -0
  106. package/types/SelectViewport.d.ts +127 -0
  107. package/types/SelectViewport.native.d.ts +7 -0
  108. package/types/constants.d.ts +8 -0
  109. package/types/context.d.ts +21 -0
  110. package/types/index.d.ts +2 -0
  111. package/types/types.d.ts +81 -0
  112. package/types/useSelectBreakpointActive.d.ts +4 -0
  113. package/types/Select.d.ts.map +0 -1
  114. package/types/index.d.ts.map +0 -1
@@ -1,233 +1,190 @@
1
- import {
2
- FloatingFocusManager,
3
- FloatingOverlay,
4
- FloatingPortal,
5
- autoUpdate,
6
- detectOverflow,
7
- flip,
8
- offset,
9
- size,
10
- useClick,
11
- useDismiss,
12
- useFloating,
13
- useInteractions,
14
- useListNavigation,
15
- useRole,
16
- useTypeahead
17
- } from "@floating-ui/react-dom-interactions";
18
- import { usePrevious } from "@radix-ui/react-use-previous";
1
+ import { Adapt, useAdaptParent } from "@tamagui/adapt";
19
2
  import { useComposedRefs } from "@tamagui/compose-refs";
20
- import {
21
- Theme,
22
- styled,
23
- useIsomorphicLayoutEffect,
24
- useThemeName,
25
- withStaticProperties
26
- } from "@tamagui/core";
3
+ import { isWeb } from "@tamagui/core";
4
+ import { styled, useGet, useIsomorphicLayoutEffect, withStaticProperties } from "@tamagui/core";
27
5
  import { useId } from "@tamagui/core";
28
- import { createContextScope } from "@tamagui/create-context";
29
6
  import { ListItem } from "@tamagui/list-item";
7
+ import { PortalHost } from "@tamagui/portal";
30
8
  import { Separator } from "@tamagui/separator";
31
- import { ThemeableStack, XStack, YStack } from "@tamagui/stacks";
32
- import { Paragraph } from "@tamagui/text";
9
+ import { ControlledSheet, SheetController } from "@tamagui/sheet";
10
+ import { XStack, YStack } from "@tamagui/stacks";
11
+ import { Paragraph, SizableText } from "@tamagui/text";
33
12
  import { useControllableState } from "@tamagui/use-controllable-state";
34
13
  import * as React from "react";
35
- import * as ReactDOM from "react-dom";
36
- const userAgent = typeof navigator !== "undefined" && navigator.userAgent || "";
37
- const isFirefox = userAgent.toLowerCase().includes("firefox");
38
- if (isFirefox) {
39
- document.body.classList.add("firefox");
40
- }
41
- function getVisualOffsetTop() {
42
- var _a;
43
- return !/^((?!chrome|android).)*safari/i.test(userAgent) ? (_a = visualViewport == null ? void 0 : visualViewport.offsetTop) != null ? _a : 0 : 0;
44
- }
45
- const SELECT_NAME = "Select";
46
- const WINDOW_PADDING = 8;
47
- const SCROLL_ARROW_VELOCITY = 8;
48
- const SCROLL_ARROW_THRESHOLD = 8;
49
- const MIN_HEIGHT = 80;
50
- const FALLBACK_THRESHOLD = 16;
51
- const [createSelectContext, createSelectScope] = createContextScope(SELECT_NAME);
52
- const [SelectProvider, useSelectContext] = createSelectContext(SELECT_NAME);
14
+ import { SELECT_NAME } from "./constants";
15
+ import { SelectProvider, createSelectContext, useSelectContext } from "./context";
16
+ import { SelectContent } from "./SelectContent";
17
+ import { SelectInlineImpl } from "./SelectImpl";
18
+ import { SelectScrollDownButton, SelectScrollUpButton } from "./SelectScrollButton";
19
+ import { SelectViewport } from "./SelectViewport";
20
+ import { useSelectBreakpointActive, useShowSelectSheet } from "./useSelectBreakpointActive";
53
21
  const TRIGGER_NAME = "SelectTrigger";
54
- const SelectTrigger = React.forwardRef((props, forwardedRef) => {
55
- const {
56
- __scopeSelect,
57
- disabled = false,
58
- "aria-labelledby": ariaLabelledby,
59
- ...triggerProps
60
- } = props;
61
- const context = useSelectContext(TRIGGER_NAME, __scopeSelect);
62
- return <ListItem backgrounded radiused hoverTheme pressTheme focusTheme focusable={false} borderWidth={1} componentName={TRIGGER_NAME} size={context.size} aria-expanded={context.open} aria-autocomplete="none" disabled={disabled} data-disabled={disabled ? "" : void 0} {...triggerProps} ref={forwardedRef} {...context.interactions.getReferenceProps()} />;
63
- });
22
+ const SelectTrigger = React.forwardRef(
23
+ (props, forwardedRef) => {
24
+ const {
25
+ __scopeSelect,
26
+ disabled = false,
27
+ "aria-labelledby": ariaLabelledby,
28
+ ...triggerProps
29
+ } = props;
30
+ const context = useSelectContext(TRIGGER_NAME, __scopeSelect);
31
+ const labelledBy = ariaLabelledby;
32
+ return <ListItem componentName={TRIGGER_NAME} backgrounded radiused hoverTheme pressTheme focusTheme focusable borderWidth={1} size={context.size} aria-expanded={context.open} aria-autocomplete="none" aria-labelledby={labelledBy} dir={context.dir} disabled={disabled} data-disabled={disabled ? "" : void 0} {...triggerProps} ref={forwardedRef} {...process.env.TAMAGUI_TARGET === "web" && context.interactions ? context.interactions.getReferenceProps() : {
33
+ onPress() {
34
+ context.setOpen(!context.open);
35
+ }
36
+ }} />;
37
+ }
38
+ );
64
39
  SelectTrigger.displayName = TRIGGER_NAME;
65
40
  const VALUE_NAME = "SelectValue";
66
41
  const SelectValueFrame = styled(Paragraph, {
67
42
  name: VALUE_NAME,
68
43
  selectable: false
69
44
  });
70
- const SelectValue = SelectValueFrame.extractable(React.forwardRef(({ __scopeSelect, children, placeholder }, forwardedRef) => {
71
- const context = useSelectContext(VALUE_NAME, __scopeSelect);
72
- const { onValueNodeHasChildrenChange } = context;
73
- const hasChildren = children !== void 0;
74
- const composedRefs = useComposedRefs(forwardedRef, context.onValueNodeChange);
75
- React.useLayoutEffect(() => {
76
- onValueNodeHasChildrenChange(hasChildren);
77
- }, [onValueNodeHasChildrenChange, hasChildren]);
78
- return <SelectValueFrame size={context.size} ref={composedRefs} pointerEvents="none">{context.value === void 0 && placeholder !== void 0 ? placeholder : children}</SelectValueFrame>;
79
- }));
45
+ const SelectValue = SelectValueFrame.extractable(
46
+ React.forwardRef(
47
+ ({ __scopeSelect, children: childrenProp, placeholder }, forwardedRef) => {
48
+ const context = useSelectContext(VALUE_NAME, __scopeSelect);
49
+ const { onValueNodeHasChildrenChange } = context;
50
+ const composedRefs = useComposedRefs(forwardedRef, context.onValueNodeChange);
51
+ const children = childrenProp ?? context.selectedItem;
52
+ const hasChildren = !!children;
53
+ const selectValueChildren = context.value === void 0 && placeholder !== void 0 ? placeholder : children;
54
+ useIsomorphicLayoutEffect(() => {
55
+ onValueNodeHasChildrenChange(hasChildren);
56
+ }, [onValueNodeHasChildrenChange, hasChildren]);
57
+ return <SelectValueFrame size={context.size} ref={composedRefs} pointerEvents="none">{selectValueChildren}</SelectValueFrame>;
58
+ }
59
+ )
60
+ );
80
61
  SelectValue.displayName = VALUE_NAME;
81
62
  const SelectIcon = styled(XStack, {
82
63
  name: "SelectIcon",
83
64
  "aria-hidden": true,
84
65
  children: <Paragraph>{"\u25BC"}</Paragraph>
85
66
  });
86
- const CONTENT_NAME = "SelectContent";
87
- const SelectContent = ({ children, __scopeSelect }) => {
88
- const context = useSelectContext(CONTENT_NAME, __scopeSelect);
89
- const themeName = useThemeName();
90
- const contents = <Theme name={themeName}>{children}</Theme>;
91
- return <FloatingPortal>{context.open ? <FloatingOverlay lockScroll>{contents}</FloatingOverlay> : <div style={{ display: "none" }}>{contents}</div>}</FloatingPortal>;
92
- };
93
- const VIEWPORT_NAME = "SelectViewport";
94
- const SelectViewportFrame = styled(ThemeableStack, {
95
- name: VIEWPORT_NAME,
96
- backgroundColor: "$background",
97
- elevate: true,
98
- bordered: true,
99
- overflow: "scroll",
100
- userSelect: "none",
101
- variants: {
102
- size: {
103
- "...size": (val, { tokens }) => {
104
- var _a;
105
- return {
106
- borderRadius: (_a = tokens.radius[val]) != null ? _a : val
107
- };
108
- }
109
- }
110
- },
111
- defaultVariants: {
112
- size: "$2"
113
- }
114
- });
115
- const SelectViewport = React.forwardRef((props, forwardedRef) => {
116
- const { __scopeSelect, children, ...viewportProps } = props;
117
- const context = useSelectContext(VIEWPORT_NAME, __scopeSelect);
118
- const { style, ...floatingProps } = context.interactions.getFloatingProps();
119
- delete style["scrollbarWidth"];
120
- delete style["listStyleType"];
121
- return <>
122
- <style dangerouslySetInnerHTML={{
123
- __html: `[data-tamagui-select-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-tamagui-select-viewport]::-webkit-scrollbar{display:none}`
124
- }} />
125
- <FloatingFocusManager context={context.floatingContext} preventTabbing><SelectViewportFrame size={context.size} data-tamagui-select-viewport="" role="presentation" {...viewportProps} ref={forwardedRef} {...floatingProps} {...style}>{children}</SelectViewportFrame></FloatingFocusManager>
126
- </>;
127
- });
128
- SelectViewport.displayName = VIEWPORT_NAME;
129
67
  const ITEM_NAME = "SelectItem";
130
68
  const [SelectItemContextProvider, useSelectItemContext] = createSelectContext(ITEM_NAME);
131
- const SelectItem = React.forwardRef((props, forwardedRef) => {
132
- const {
133
- __scopeSelect,
134
- value,
135
- disabled = false,
136
- textValue: textValueProp,
137
- index,
138
- ...itemProps
139
- } = props;
140
- const context = useSelectContext(ITEM_NAME, __scopeSelect);
141
- const isSelected = context.value === value;
142
- const [textValue, setTextValue] = React.useState(textValueProp != null ? textValueProp : "");
143
- const [isFocused, setIsFocused] = React.useState(false);
144
- const textId = useId();
145
- const {
146
- selectedIndex,
147
- setSelectedIndex,
148
- listRef,
149
- open,
150
- setOpen,
151
- onChange,
152
- activeIndex,
153
- setActiveIndex,
154
- setValueAtIndex,
155
- dataRef
156
- } = context;
157
- const composedRefs = useComposedRefs(forwardedRef, (node) => {
158
- if (node instanceof HTMLElement) {
159
- listRef.current[index] = node;
160
- }
161
- });
162
- React.useEffect(() => {
163
- setValueAtIndex(index, value);
164
- }, [index]);
165
- const timeoutRef = React.useRef();
166
- const [allowMouseUp, setAllowMouseUp] = React.useState(false);
167
- function handleSelect() {
168
- setSelectedIndex(index);
169
- onChange(value);
170
- setOpen(false);
171
- }
172
- React.useLayoutEffect(() => {
173
- clearTimeout(timeoutRef.current);
174
- if (open) {
175
- if (selectedIndex !== index) {
176
- setAllowMouseUp(true);
177
- } else {
178
- timeoutRef.current = setTimeout(() => {
179
- setAllowMouseUp(true);
180
- }, 300);
69
+ const SelectItem = React.forwardRef(
70
+ (props, forwardedRef) => {
71
+ const {
72
+ __scopeSelect,
73
+ value,
74
+ disabled = false,
75
+ textValue: textValueProp,
76
+ index,
77
+ ...itemProps
78
+ } = props;
79
+ const context = useSelectContext(ITEM_NAME, __scopeSelect);
80
+ const isSelected = context.value === value;
81
+ const textId = useId();
82
+ const {
83
+ selectedIndex,
84
+ setSelectedIndex,
85
+ listRef,
86
+ open,
87
+ setOpen,
88
+ onChange,
89
+ setActiveIndex,
90
+ allowMouseUpRef,
91
+ allowSelectRef,
92
+ setValueAtIndex,
93
+ selectTimeoutRef,
94
+ dataRef
95
+ } = context;
96
+ const composedRefs = useComposedRefs(forwardedRef, (node) => {
97
+ if (!isWeb)
98
+ return;
99
+ if (node instanceof HTMLElement) {
100
+ if (listRef) {
101
+ listRef.current[index] = node;
102
+ }
181
103
  }
182
- } else {
183
- setAllowMouseUp(false);
184
- }
185
- }, [open, index, setActiveIndex, selectedIndex]);
186
- function handleKeyDown(event) {
187
- if (event.key === "Enter" || event.key === " " && !dataRef.current.typing) {
188
- event.preventDefault();
189
- handleSelect();
104
+ });
105
+ React.useEffect(() => {
106
+ setValueAtIndex(index, value);
107
+ }, [index, setValueAtIndex, value]);
108
+ function handleSelect() {
109
+ setSelectedIndex(index);
110
+ onChange(value);
111
+ setOpen(false);
190
112
  }
113
+ const selectItemProps = context.interactions ? context.interactions.getItemProps({
114
+ onTouchStart() {
115
+ allowSelectRef.current = true;
116
+ allowMouseUpRef.current = false;
117
+ },
118
+ onKeyDown(event) {
119
+ if (event.key === "Enter" || event.key === " " && !dataRef?.current.typing) {
120
+ event.preventDefault();
121
+ handleSelect();
122
+ } else {
123
+ allowSelectRef.current = true;
124
+ }
125
+ },
126
+ onClick() {
127
+ if (allowSelectRef.current) {
128
+ setSelectedIndex(index);
129
+ setOpen(false);
130
+ }
131
+ },
132
+ onMouseUp() {
133
+ if (!allowMouseUpRef.current) {
134
+ return;
135
+ }
136
+ if (allowSelectRef.current) {
137
+ handleSelect();
138
+ }
139
+ clearTimeout(selectTimeoutRef.current);
140
+ selectTimeoutRef.current = setTimeout(() => {
141
+ allowSelectRef.current = true;
142
+ });
143
+ }
144
+ }) : {
145
+ onPress: handleSelect
146
+ };
147
+ return <SelectItemContextProvider scope={__scopeSelect} value={value} textId={textId || ""} isSelected={isSelected}><ListItem backgrounded pressTheme cursor="" focusTheme componentName={ITEM_NAME} ref={composedRefs} aria-labelledby={textId} aria-selected={isSelected} data-state={isSelected ? "active" : "inactive"} aria-disabled={disabled || void 0} data-disabled={disabled ? "" : void 0} tabIndex={disabled ? void 0 : -1} size={context.size} {...itemProps} {...selectItemProps} /></SelectItemContextProvider>;
191
148
  }
192
- const selectItemProps = context.interactions.getItemProps({
193
- onClick: allowMouseUp ? handleSelect : void 0,
194
- onMouseUp: allowMouseUp ? handleSelect : void 0,
195
- onKeyDown: handleKeyDown
196
- });
197
- return <SelectItemContextProvider scope={__scopeSelect} value={value} textId={textId || ""} isSelected={isSelected} onItemTextChange={React.useCallback((node) => {
198
- setTextValue((prevTextValue) => {
199
- var _a;
200
- return prevTextValue || ((_a = node == null ? void 0 : node.textContent) != null ? _a : "").trim();
201
- });
202
- }, [])}><ListItem backgrounded pressTheme focusTheme componentName={ITEM_NAME} ref={composedRefs} aria-labelledby={textId} aria-selected={isSelected && isFocused} data-state={isSelected ? "active" : "inactive"} aria-disabled={disabled || void 0} data-disabled={disabled ? "" : void 0} tabIndex={disabled ? void 0 : -1} size={context.size} {...itemProps} {...selectItemProps} /></SelectItemContextProvider>;
203
- });
149
+ );
204
150
  SelectItem.displayName = ITEM_NAME;
205
151
  const ITEM_TEXT_NAME = "SelectItemText";
206
- const SelectItemTextFrame = styled(Paragraph, {
152
+ const SelectItemTextFrame = styled(SizableText, {
207
153
  name: ITEM_TEXT_NAME,
208
154
  selectable: false
209
155
  });
210
- const SelectItemText = React.forwardRef((props, forwardedRef) => {
211
- const { __scopeSelect, className, style, ...itemTextProps } = props;
212
- const context = useSelectContext(ITEM_TEXT_NAME, __scopeSelect);
213
- const itemContext = useSelectItemContext(ITEM_TEXT_NAME, __scopeSelect);
214
- const ref = React.useRef(null);
215
- const composedRefs = useComposedRefs(forwardedRef, ref, itemContext.onItemTextChange);
216
- return <>
217
- <SelectItemTextFrame size={context.size} id={itemContext.textId} {...itemTextProps} ref={composedRefs} />
218
- {itemContext.isSelected && context.valueNode && !context.valueNodeHasChildren ? ReactDOM.createPortal(itemTextProps.children, context.valueNode) : null}
219
- </>;
220
- });
156
+ const SelectItemText = React.forwardRef(
157
+ (props, forwardedRef) => {
158
+ const { __scopeSelect, className, ...itemTextProps } = props;
159
+ const context = useSelectContext(ITEM_TEXT_NAME, __scopeSelect);
160
+ const itemContext = useSelectItemContext(ITEM_TEXT_NAME, __scopeSelect);
161
+ const ref = React.useRef(null);
162
+ const composedRefs = useComposedRefs(forwardedRef, ref);
163
+ const isSelected = Boolean(itemContext.isSelected && context.valueNode);
164
+ const contents = React.useMemo(
165
+ () => <SelectItemTextFrame className={className} size={context.size} id={itemContext.textId} {...itemTextProps} ref={composedRefs} />,
166
+ [props, context.size, className, itemContext.textId]
167
+ );
168
+ React.useEffect(() => {
169
+ if (isSelected) {
170
+ context.setSelectedItem(contents);
171
+ }
172
+ }, [isSelected, contents]);
173
+ return <>{contents}</>;
174
+ }
175
+ );
221
176
  SelectItemText.displayName = ITEM_TEXT_NAME;
222
177
  const ITEM_INDICATOR_NAME = "SelectItemIndicator";
223
178
  const SelectItemIndicatorFrame = styled(XStack, {
224
179
  name: ITEM_TEXT_NAME
225
180
  });
226
- const SelectItemIndicator = React.forwardRef((props, forwardedRef) => {
227
- const { __scopeSelect, ...itemIndicatorProps } = props;
228
- const itemContext = useSelectItemContext(ITEM_INDICATOR_NAME, __scopeSelect);
229
- return itemContext.isSelected ? <SelectItemIndicatorFrame aria-hidden {...itemIndicatorProps} ref={forwardedRef} /> : null;
230
- });
181
+ const SelectItemIndicator = React.forwardRef(
182
+ (props, forwardedRef) => {
183
+ const { __scopeSelect, ...itemIndicatorProps } = props;
184
+ const itemContext = useSelectItemContext(ITEM_INDICATOR_NAME, __scopeSelect);
185
+ return itemContext.isSelected ? <SelectItemIndicatorFrame aria-hidden {...itemIndicatorProps} ref={forwardedRef} /> : null;
186
+ }
187
+ );
231
188
  SelectItemIndicator.displayName = ITEM_INDICATOR_NAME;
232
189
  const GROUP_NAME = "SelectGroup";
233
190
  const [SelectGroupContextProvider, useSelectGroupContext] = createSelectContext(GROUP_NAME);
@@ -235,470 +192,118 @@ const SelectGroupFrame = styled(YStack, {
235
192
  name: GROUP_NAME,
236
193
  width: "100%"
237
194
  });
238
- const SelectGroup = React.forwardRef((props, forwardedRef) => {
239
- const { __scopeSelect, ...groupProps } = props;
240
- const groupId = useId();
241
- return <SelectGroupContextProvider scope={__scopeSelect} id={groupId || ""}><SelectGroupFrame role="group" aria-labelledby={groupId} {...groupProps} ref={forwardedRef} /></SelectGroupContextProvider>;
242
- });
195
+ const SelectGroup = React.forwardRef(
196
+ (props, forwardedRef) => {
197
+ const { __scopeSelect, ...groupProps } = props;
198
+ const groupId = useId();
199
+ return <SelectGroupContextProvider scope={__scopeSelect} id={groupId || ""}><SelectGroupFrame role="group" aria-labelledby={groupId} {...groupProps} ref={forwardedRef} /></SelectGroupContextProvider>;
200
+ }
201
+ );
243
202
  SelectGroup.displayName = GROUP_NAME;
244
203
  const LABEL_NAME = "SelectLabel";
245
- const SelectLabel = React.forwardRef((props, forwardedRef) => {
246
- const { __scopeSelect, ...labelProps } = props;
247
- const context = useSelectContext(LABEL_NAME, __scopeSelect);
248
- const groupContext = useSelectGroupContext(LABEL_NAME, __scopeSelect);
249
- return <ListItem componentName={LABEL_NAME} fontWeight="800" id={groupContext.id} size={context.size} {...labelProps} ref={forwardedRef} />;
250
- });
251
- SelectLabel.displayName = LABEL_NAME;
252
- const SCROLL_UP_BUTTON_NAME = "SelectScrollUpButton";
253
- const SelectScrollUpButton = React.forwardRef((props, forwardedRef) => {
254
- return <SelectScrollButtonImpl componentName={SCROLL_UP_BUTTON_NAME} {...props} dir="up" ref={forwardedRef} />;
255
- });
256
- SelectScrollUpButton.displayName = SCROLL_UP_BUTTON_NAME;
257
- const SCROLL_DOWN_BUTTON_NAME = "SelectScrollDownButton";
258
- const SelectScrollDownButton = React.forwardRef((props, forwardedRef) => {
259
- return <SelectScrollButtonImpl componentName={SCROLL_DOWN_BUTTON_NAME} {...props} dir="down" ref={forwardedRef} />;
260
- });
261
- SelectScrollDownButton.displayName = SCROLL_DOWN_BUTTON_NAME;
262
- const SelectScrollButtonImpl = React.forwardRef((props, forwardedRef) => {
263
- var _a, _b;
264
- const { __scopeSelect, dir, componentName, ...scrollIndicatorProps } = props;
265
- const { floatingRef, increaseHeight, forceUpdate, ...context } = useSelectContext(componentName, __scopeSelect);
266
- const intervalRef = React.useRef();
267
- const loopingRef = React.useRef(false);
268
- const isVisible = context[dir === "down" ? "canScrollDown" : "canScrollUp"];
269
- const { x, y, reference, floating, strategy, update, refs } = useFloating({
270
- strategy: "fixed",
271
- placement: dir === "up" ? "top" : "bottom",
272
- middleware: [offset(({ rects }) => -rects.floating.height)]
273
- });
274
- const composedRefs = useComposedRefs(forwardedRef, floating);
275
- React.useLayoutEffect(() => {
276
- reference(floatingRef.current);
277
- }, [reference, floatingRef.current]);
278
- React.useEffect(() => {
279
- if (!refs.reference.current || !refs.floating.current || !isVisible) {
280
- return;
281
- }
282
- const cleanup = autoUpdate(refs.reference.current, refs.floating.current, update, {
283
- animationFrame: true
284
- });
285
- return () => {
286
- clearInterval(intervalRef.current);
287
- loopingRef.current = false;
288
- cleanup();
289
- };
290
- }, [isVisible, update, refs.floating, refs.reference]);
291
- if (!isVisible) {
292
- return null;
204
+ const SelectLabel = React.forwardRef(
205
+ (props, forwardedRef) => {
206
+ const { __scopeSelect, ...labelProps } = props;
207
+ const context = useSelectContext(LABEL_NAME, __scopeSelect);
208
+ const groupContext = useSelectGroupContext(LABEL_NAME, __scopeSelect);
209
+ return <ListItem componentName={LABEL_NAME} fontWeight="800" id={groupContext.id} size={context.size} {...labelProps} ref={forwardedRef} />;
293
210
  }
294
- const handleScrollArrowChange = () => {
295
- const floating2 = floatingRef.current;
296
- const isUp = dir === "up";
297
- if (floating2) {
298
- const value = isUp ? -SCROLL_ARROW_VELOCITY : SCROLL_ARROW_VELOCITY;
299
- const multi = isUp && floating2.scrollTop <= SCROLL_ARROW_THRESHOLD * 2 || !isUp && floating2.scrollTop >= floating2.scrollHeight - floating2.clientHeight - SCROLL_ARROW_THRESHOLD * 2 ? 2 : 1;
300
- floating2.scrollTop += multi * (isUp ? -SCROLL_ARROW_VELOCITY : SCROLL_ARROW_VELOCITY);
301
- increaseHeight(floating2, multi === 2 ? value * 2 : value);
302
- forceUpdate();
303
- }
304
- };
305
- return <YStack ref={composedRefs} componentName={componentName} aria-hidden {...scrollIndicatorProps} zIndex={1e3} position={strategy} left={x || 0} top={y || 0} width={`calc(${((_b = (_a = floatingRef.current) == null ? void 0 : _a.offsetWidth) != null ? _b : 0) - 2}px)`} onPointerMove={() => {
306
- if (!loopingRef.current) {
307
- intervalRef.current = setInterval(handleScrollArrowChange, 1e3 / 60);
308
- loopingRef.current = true;
309
- }
310
- }} onPointerLeave={() => {
311
- loopingRef.current = false;
312
- clearInterval(intervalRef.current);
313
- }} />;
314
- });
211
+ );
212
+ SelectLabel.displayName = LABEL_NAME;
315
213
  const SelectSeparator = styled(Separator, {
316
214
  name: "SelectSeparator"
317
215
  });
318
- const Select = withStaticProperties((props) => {
319
- const {
320
- id,
321
- __scopeSelect,
322
- children,
323
- open: openProp,
324
- defaultOpen,
325
- onOpenChange,
326
- value: valueProp,
327
- defaultValue,
328
- onValueChange,
329
- size: sizeProp,
330
- dir,
331
- name,
332
- autoComplete
333
- } = props;
334
- const [open, setOpen] = useControllableState({
335
- prop: openProp,
336
- defaultProp: defaultOpen || false,
337
- onChange: onOpenChange
338
- });
339
- const [value, setValue] = useControllableState({
340
- prop: valueProp,
341
- defaultProp: defaultValue || "",
342
- onChange: onValueChange
343
- });
344
- const [activeIndex, setActiveIndex] = React.useState(null);
345
- const selectedIndexRef = React.useRef(null);
346
- const activeIndexRef = React.useRef(null);
347
- const prevActiveIndex = usePrevious(activeIndex);
348
- const [showArrows, setShowArrows] = React.useState(false);
349
- const [scrollTop, setScrollTop] = React.useState(0);
350
- const listItemsRef = React.useRef([]);
351
- const listContentRef = React.useRef([]);
352
- const [selectedIndex, setSelectedIndex] = React.useState(Math.max(0, listContentRef.current.indexOf(value)));
353
- const [controlledScrolling, setControlledScrolling] = React.useState(false);
354
- const [middlewareType, setMiddlewareType] = React.useState("align");
355
- useIsomorphicLayoutEffect(() => {
356
- selectedIndexRef.current = selectedIndex;
357
- activeIndexRef.current = activeIndex;
358
- });
359
- React.useEffect(() => {
360
- const frame = requestAnimationFrame(() => {
361
- setShowArrows(open);
362
- if (!open) {
363
- setScrollTop(0);
364
- setMiddlewareType("align");
365
- setActiveIndex(null);
366
- setControlledScrolling(false);
367
- }
368
- });
369
- return () => {
370
- cancelAnimationFrame(frame);
371
- };
372
- }, [open]);
373
- function getFloatingPadding(floating2) {
374
- var _a;
375
- if (!floating2) {
376
- return 0;
377
- }
378
- return Number((_a = getComputedStyle(floating2).paddingLeft) == null ? void 0 : _a.replace("px", ""));
379
- }
380
- const { x, y, reference, floating, strategy, context, refs, middlewareData, update } = useFloating({
381
- open,
382
- onOpenChange: setOpen,
383
- placement: "bottom",
384
- middleware: middlewareType === "align" ? [
385
- offset(({ rects }) => {
386
- var _a;
387
- const index = (_a = activeIndexRef.current) != null ? _a : selectedIndexRef.current;
388
- if (index == null) {
389
- return 0;
390
- }
391
- const item = listItemsRef.current[index];
392
- if (item == null) {
393
- return 0;
394
- }
395
- const offsetTop = item.offsetTop;
396
- const itemHeight = item.offsetHeight;
397
- const height = rects.reference.height;
398
- return -offsetTop - height - (itemHeight - height) / 2;
399
- }),
400
- {
401
- name: "size",
402
- async fn(args) {
403
- var _a;
404
- const {
405
- elements: { floating: floating2 },
406
- rects: { reference: reference2 },
407
- middlewareData: middlewareData2
408
- } = args;
409
- const overflow = await detectOverflow(args, {
410
- padding: WINDOW_PADDING
411
- });
412
- const top = Math.max(0, overflow.top);
413
- const bottom = Math.max(0, overflow.bottom);
414
- const nextY = args.y + top;
415
- if ((_a = middlewareData2.size) == null ? void 0 : _a.skip) {
416
- return {
417
- y: nextY,
418
- data: {
419
- y: middlewareData2.size.y
420
- }
421
- };
422
- }
423
- Object.assign(floating2.style, {
424
- maxHeight: `${floating2.scrollHeight - Math.abs(top + bottom)}px`,
425
- minWidth: `${reference2.width + getFloatingPadding(floating2) * 2}px`
426
- });
427
- return {
428
- y: nextY,
429
- data: {
430
- y: top,
431
- skip: true
432
- },
433
- reset: {
434
- rects: true
435
- }
436
- };
437
- }
438
- }
439
- ] : [
440
- offset(5),
441
- flip(),
442
- size({
443
- apply({ rects, availableHeight, elements }) {
444
- Object.assign(elements.floating.style, {
445
- width: `${rects.reference.width}px`,
446
- maxHeight: `${availableHeight}px`
447
- });
448
- },
449
- padding: WINDOW_PADDING
450
- })
451
- ]
452
- });
453
- const floatingRef = refs.floating;
454
- const forceUpdate = React.useReducer(() => ({}), {})[1];
455
- const showUpArrow = showArrows && scrollTop > SCROLL_ARROW_THRESHOLD;
456
- const showDownArrow = showArrows && floatingRef.current && scrollTop < floatingRef.current.scrollHeight - floatingRef.current.clientHeight - SCROLL_ARROW_THRESHOLD;
457
- const interactions = useInteractions([
458
- useClick(context, { pointerDown: true }),
459
- useRole(context, { role: "listbox" }),
460
- useDismiss(context),
461
- useListNavigation(context, {
462
- listRef: listItemsRef,
463
- activeIndex,
464
- selectedIndex,
465
- onNavigate: setActiveIndex
466
- }),
467
- useTypeahead(context, {
468
- listRef: listContentRef,
469
- onMatch: open ? setActiveIndex : setSelectedIndex,
470
- selectedIndex,
471
- activeIndex
472
- })
473
- ]);
474
- const increaseHeight = React.useCallback((floating2, amount = 0) => {
475
- var _a;
476
- if (middlewareType === "fallback") {
477
- return;
478
- }
479
- const currentMaxHeight = Number(floating2.style.maxHeight.replace("px", ""));
480
- const currentTop = Number(floating2.style.top.replace("px", ""));
481
- const rect = floating2.getBoundingClientRect();
482
- const rectTop = rect.top;
483
- const rectBottom = rect.bottom;
484
- const viewportHeight = (_a = visualViewport == null ? void 0 : visualViewport.height) != null ? _a : 0;
485
- const visualMaxHeight = viewportHeight - WINDOW_PADDING * 2;
486
- if (amount < 0 && selectedIndexRef.current != null && Math.round(rectBottom) < Math.round(viewportHeight + getVisualOffsetTop() - WINDOW_PADDING)) {
487
- floating2.style.maxHeight = `${Math.min(visualMaxHeight, currentMaxHeight - amount)}px`;
488
- }
489
- if (amount > 0 && Math.round(rectTop) > Math.round(WINDOW_PADDING - getVisualOffsetTop()) && floating2.scrollHeight > floating2.offsetHeight) {
490
- const nextTop = Math.max(WINDOW_PADDING + getVisualOffsetTop(), currentTop - amount);
491
- const nextMaxHeight = Math.min(visualMaxHeight, currentMaxHeight + amount);
492
- Object.assign(floating2.style, {
493
- maxHeight: `${nextMaxHeight}px`,
494
- top: `${nextTop}px`
495
- });
496
- if (nextTop - WINDOW_PADDING > getVisualOffsetTop()) {
497
- floating2.scrollTop -= nextMaxHeight - currentMaxHeight + getFloatingPadding(floating2);
498
- }
499
- return currentTop - nextTop;
500
- }
501
- }, [middlewareType]);
502
- const touchPageYRef = React.useRef(null);
503
- const handleWheel = React.useCallback((event) => {
504
- var _a, _b, _c;
505
- const pinching = event.ctrlKey;
506
- const currentTarget = event.currentTarget;
507
- function isWheelEvent(event2) {
508
- return typeof event2.deltaY === "number";
509
- }
510
- function isTouchEvent(event2) {
511
- return event2.touches != null;
512
- }
513
- if (Math.abs(((_a = currentTarget == null ? void 0 : currentTarget.offsetHeight) != null ? _a : 0) - (((_b = visualViewport == null ? void 0 : visualViewport.height) != null ? _b : 0) - WINDOW_PADDING * 2)) > 1 && !pinching) {
514
- event.preventDefault();
515
- } else if (isWheelEvent(event) && isFirefox) {
516
- currentTarget.scrollTop += event.deltaY;
517
- }
518
- if (!pinching) {
519
- let delta = 5;
520
- if (isTouchEvent(event)) {
521
- const currentPageY = touchPageYRef.current;
522
- const pageY = (_c = event.touches[0]) == null ? void 0 : _c.pageY;
523
- if (pageY != null) {
524
- touchPageYRef.current = pageY;
525
- if (currentPageY != null) {
526
- delta = currentPageY - pageY;
527
- }
528
- }
529
- }
530
- increaseHeight(currentTarget, isWheelEvent(event) ? event.deltaY : delta);
531
- setScrollTop(currentTarget.scrollTop);
532
- forceUpdate();
533
- }
534
- }, [increaseHeight, forceUpdate]);
535
- React.useEffect(() => {
536
- function onTouchEnd() {
537
- touchPageYRef.current = null;
538
- }
539
- const floating2 = floatingRef.current;
540
- if (open && floating2 && middlewareType === "align") {
541
- floating2.addEventListener("wheel", handleWheel);
542
- floating2.addEventListener("touchmove", handleWheel);
543
- floating2.addEventListener("touchend", onTouchEnd, { passive: true });
544
- return () => {
545
- floating2.removeEventListener("wheel", handleWheel);
546
- floating2.removeEventListener("touchmove", handleWheel);
547
- floating2.removeEventListener("touchend", onTouchEnd);
548
- };
549
- }
550
- }, [open, floatingRef, handleWheel, middlewareType]);
551
- React.useEffect(() => {
552
- window.addEventListener("resize", update);
553
- return () => {
554
- window.removeEventListener("resize", update);
555
- };
556
- }, [update]);
557
- React.useLayoutEffect(() => {
558
- var _a, _b, _c;
559
- const floating2 = floatingRef.current;
560
- if (open && controlledScrolling && floating2) {
561
- const item = activeIndex != null ? listItemsRef.current[activeIndex] : selectedIndex != null ? listItemsRef.current[selectedIndex] : null;
562
- if (item && prevActiveIndex != null) {
563
- const itemHeight = (_b = (_a = listItemsRef.current[prevActiveIndex]) == null ? void 0 : _a.offsetHeight) != null ? _b : 0;
564
- const floatingHeight = floating2.offsetHeight;
565
- const top = item.offsetTop;
566
- const bottom = top + itemHeight;
567
- if (top < floating2.scrollTop + 20) {
568
- const diff = floating2.scrollTop - top + 20;
569
- floating2.scrollTop -= diff;
570
- if (activeIndex != selectedIndex && activeIndex != null) {
571
- increaseHeight(floating2, -diff);
572
- }
573
- } else if (bottom > floatingHeight + floating2.scrollTop - 20) {
574
- const diff = bottom - floatingHeight - floating2.scrollTop + 20;
575
- floating2.scrollTop += diff;
576
- if (activeIndex != selectedIndex && activeIndex != null) {
577
- floating2.scrollTop -= (_c = increaseHeight(floating2, diff)) != null ? _c : 0;
578
- }
579
- }
580
- }
216
+ const SelectSheetController = (props) => {
217
+ const context = useSelectContext("SelectSheetController", props.__scopeSelect);
218
+ const showSheet = useShowSelectSheet(context);
219
+ const breakpointActive = useSelectBreakpointActive(context.sheetBreakpoint);
220
+ const getShowSheet = useGet(showSheet);
221
+ return <SheetController onOpenChange={(val) => {
222
+ if (getShowSheet()) {
223
+ props.onOpenChange(val);
581
224
  }
582
- }, [
583
- open,
584
- controlledScrolling,
585
- prevActiveIndex,
586
- activeIndex,
587
- selectedIndex,
588
- floatingRef,
589
- increaseHeight
590
- ]);
591
- React.useLayoutEffect(() => {
592
- var _a, _b;
593
- const floating2 = refs.floating.current;
594
- const reference2 = refs.reference.current;
595
- if (open && floating2 && reference2 && floating2.offsetHeight < floating2.scrollHeight) {
596
- const referenceRect = reference2.getBoundingClientRect();
597
- if (middlewareType === "fallback") {
598
- const item = listItemsRef.current[selectedIndex];
599
- if (item) {
600
- floating2.scrollTop = item.offsetTop - floating2.clientHeight + referenceRect.height;
601
- }
602
- return;
603
- }
604
- floating2.scrollTop = (_a = middlewareData.size) == null ? void 0 : _a.y;
605
- const closeToBottom = ((_b = visualViewport == null ? void 0 : visualViewport.height) != null ? _b : 0) + getVisualOffsetTop() - referenceRect.bottom < FALLBACK_THRESHOLD;
606
- const closeToTop = referenceRect.top < FALLBACK_THRESHOLD;
607
- if (floating2.offsetHeight < MIN_HEIGHT || closeToTop || closeToBottom) {
608
- setMiddlewareType("fallback");
609
- }
610
- }
611
- }, [
612
- open,
613
- increaseHeight,
614
- selectedIndex,
615
- middlewareType,
616
- refs.floating,
617
- refs.reference,
618
- middlewareData
619
- ]);
620
- React.useLayoutEffect(() => {
621
- if (open && selectedIndex != null) {
622
- requestAnimationFrame(() => {
623
- var _a;
624
- (_a = listItemsRef.current[selectedIndex]) == null ? void 0 : _a.focus({ preventScroll: true });
625
- });
626
- }
627
- }, [listItemsRef, selectedIndex, open]);
628
- React.useEffect(() => {
629
- const frame = requestAnimationFrame(() => {
630
- setShowArrows(open);
631
- if (!open) {
632
- setScrollTop(0);
633
- setMiddlewareType("align");
634
- setActiveIndex(null);
635
- setControlledScrolling(false);
636
- }
225
+ }} open={context.open} hidden={breakpointActive === false}>{props.children}</SheetController>;
226
+ };
227
+ const SHEET_CONTENTS_NAME = "SelectSheetContents";
228
+ const SelectSheetContents = ({ __scopeSelect }) => {
229
+ const context = useSelectContext(SHEET_CONTENTS_NAME, __scopeSelect);
230
+ return <PortalHost name={`${context.scopeKey}SheetContents`} />;
231
+ };
232
+ SelectSheetContents.displayName = SHEET_CONTENTS_NAME;
233
+ const SelectSheetImpl = (props) => {
234
+ return <>{props.children}</>;
235
+ };
236
+ const Select = withStaticProperties(
237
+ (props) => {
238
+ const {
239
+ __scopeSelect,
240
+ children,
241
+ open: openProp,
242
+ defaultOpen,
243
+ onOpenChange,
244
+ value: valueProp,
245
+ defaultValue,
246
+ onValueChange,
247
+ size: sizeProp = "$4",
248
+ dir
249
+ } = props;
250
+ const { when, AdaptProvider } = useAdaptParent({
251
+ Contents: SelectSheetContents
637
252
  });
638
- return () => cancelAnimationFrame(frame);
639
- }, [open]);
640
- const [valueNode, setValueNode] = React.useState(null);
641
- const [valueNodeHasChildren, setValueNodeHasChildren] = React.useState(false);
642
- return <SelectProvider size={sizeProp} scope={__scopeSelect} increaseHeight={increaseHeight} forceUpdate={forceUpdate} floatingRef={floatingRef} valueNode={valueNode} onValueNodeChange={setValueNode} valueNodeHasChildren={valueNodeHasChildren} onValueNodeHasChildrenChange={setValueNodeHasChildren} setValueAtIndex={(index, value2) => {
643
- listContentRef.current[index] = value2;
644
- }} interactions={{
645
- ...interactions,
646
- getReferenceProps() {
647
- return interactions.getReferenceProps({
648
- ref: reference,
649
- className: "SelectTrigger",
650
- onKeyDown(event) {
651
- if (event.key === "Enter" || event.key === " " && !context.dataRef.current.typing) {
652
- event.preventDefault();
653
- setOpen(true);
654
- }
655
- }
656
- });
657
- },
658
- getFloatingProps(props2) {
659
- return interactions.getFloatingProps({
660
- ref: floating,
661
- className: "Select",
662
- ...props2,
663
- style: {
664
- position: strategy,
665
- top: y != null ? y : "",
666
- left: x != null ? x : "",
667
- outline: 0,
668
- listStyleType: "none",
669
- scrollbarWidth: "none",
670
- userSelect: "none",
671
- ...props2 == null ? void 0 : props2.style
672
- },
673
- onPointerEnter() {
674
- setControlledScrolling(false);
675
- },
676
- onPointerMove() {
677
- setControlledScrolling(false);
678
- },
679
- onKeyDown() {
680
- setControlledScrolling(true);
681
- },
682
- onScroll(event) {
683
- setScrollTop(event.currentTarget.scrollTop);
684
- }
685
- });
686
- }
687
- }} floatingContext={context} activeIndex={activeIndex} canScrollDown={!!showDownArrow} canScrollUp={!!showUpArrow} controlledScrolling dataRef={context.dataRef} listRef={listItemsRef} onChange={setValue} selectedIndex={selectedIndex} setActiveIndex={setActiveIndex} setOpen={setOpen} setSelectedIndex={setSelectedIndex} value={value} open={open}>{children}</SelectProvider>;
688
- }, {
689
- Content: SelectContent,
690
- Group: SelectGroup,
691
- Icon: SelectIcon,
692
- Item: SelectItem,
693
- ItemIndicator: SelectItemIndicator,
694
- ItemText: SelectItemText,
695
- Label: SelectLabel,
696
- ScrollDownButton: SelectScrollDownButton,
697
- ScrollUpButton: SelectScrollUpButton,
698
- Trigger: SelectTrigger,
699
- Value: SelectValue,
700
- Viewport: SelectViewport
701
- });
253
+ const sheetBreakpoint = when || false;
254
+ const isSheet = useSelectBreakpointActive(sheetBreakpoint);
255
+ const SelectImpl = isSheet ? SelectSheetImpl : SelectInlineImpl;
256
+ const forceUpdate = React.useReducer(() => ({}), {})[1];
257
+ const [selectedItem, setSelectedItem] = React.useState(null);
258
+ const [open, setOpen] = useControllableState({
259
+ prop: openProp,
260
+ defaultProp: defaultOpen || false,
261
+ onChange: onOpenChange,
262
+ strategy: "most-recent-wins"
263
+ });
264
+ const [value, setValue] = useControllableState({
265
+ prop: valueProp,
266
+ defaultProp: defaultValue || "",
267
+ onChange: onValueChange,
268
+ strategy: "most-recent-wins"
269
+ });
270
+ const [activeIndex, setActiveIndex] = React.useState(null);
271
+ const selectedIndexRef = React.useRef(null);
272
+ const activeIndexRef = React.useRef(null);
273
+ const listContentRef = React.useRef([]);
274
+ const [selectedIndex, setSelectedIndex] = React.useState(
275
+ Math.max(0, listContentRef.current.indexOf(value))
276
+ );
277
+ const [valueNode, setValueNode] = React.useState(null);
278
+ const [valueNodeHasChildren, setValueNodeHasChildren] = React.useState(false);
279
+ useIsomorphicLayoutEffect(() => {
280
+ selectedIndexRef.current = selectedIndex;
281
+ activeIndexRef.current = activeIndex;
282
+ });
283
+ const id = useId();
284
+ const scopeKey = __scopeSelect ? Object.keys(__scopeSelect)[0] ?? id : id;
285
+ return <AdaptProvider><SelectProvider dir={dir} blockSelection={false} size={sizeProp} fallback={false} selectedItem={selectedItem} setSelectedItem={setSelectedItem} forceUpdate={forceUpdate} valueNode={valueNode} onValueNodeChange={setValueNode} onValueNodeHasChildrenChange={setValueNodeHasChildren} valueNodeHasChildren={valueNodeHasChildren} scopeKey={scopeKey} sheetBreakpoint={sheetBreakpoint} scope={__scopeSelect} setValueAtIndex={(index, value2) => {
286
+ listContentRef.current[index] = value2;
287
+ }} activeIndex={activeIndex} onChange={setValue} selectedIndex={selectedIndex} setActiveIndex={setActiveIndex} setOpen={setOpen} setSelectedIndex={setSelectedIndex} value={value} open={open}><SelectSheetController onOpenChange={setOpen} __scopeSelect={__scopeSelect}><SelectImpl activeIndexRef={activeIndexRef} listContentRef={listContentRef} selectedIndexRef={selectedIndexRef} {...props} open={open} value={value}>{children}</SelectImpl></SelectSheetController></SelectProvider></AdaptProvider>;
288
+ },
289
+ {
290
+ Adapt,
291
+ Content: SelectContent,
292
+ Group: SelectGroup,
293
+ Icon: SelectIcon,
294
+ Item: SelectItem,
295
+ ItemIndicator: SelectItemIndicator,
296
+ ItemText: SelectItemText,
297
+ Label: SelectLabel,
298
+ ScrollDownButton: SelectScrollDownButton,
299
+ ScrollUpButton: SelectScrollUpButton,
300
+ Trigger: SelectTrigger,
301
+ Value: SelectValue,
302
+ Viewport: SelectViewport,
303
+ SheetContents: SelectSheetContents,
304
+ Sheet: ControlledSheet
305
+ }
306
+ );
702
307
  Select.displayName = SELECT_NAME;
703
308
  export {
704
309
  Select,
@@ -707,9 +312,7 @@ export {
707
312
  SelectItem,
708
313
  SelectItemTextFrame,
709
314
  SelectSeparator,
710
- SelectTrigger,
711
- SelectViewport,
712
- SelectViewportFrame,
713
- createSelectScope
315
+ SelectSheetContents,
316
+ SelectTrigger
714
317
  };
715
318
  //# sourceMappingURL=Select.js.map