@tamagui/select 3.0.0-beta.922.1 → 3.0.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 (106) hide show
  1. package/dist/cjs/Select.cjs +23 -25
  2. package/dist/cjs/Select.native.cjs +27 -26
  3. package/dist/cjs/Select.native.js +27 -26
  4. package/dist/cjs/Select.native.js.map +1 -1
  5. package/dist/cjs/SelectImpl.cjs +56 -50
  6. package/dist/cjs/SelectItem.cjs +49 -60
  7. package/dist/cjs/SelectItem.native.cjs +51 -79
  8. package/dist/cjs/SelectItem.native.js +51 -79
  9. package/dist/cjs/SelectItem.native.js.map +1 -1
  10. package/dist/cjs/SelectScrollButton.cjs +2 -2
  11. package/dist/cjs/SelectTrigger.cjs +22 -5
  12. package/dist/cjs/SelectTrigger.native.cjs +15 -5
  13. package/dist/cjs/SelectTrigger.native.js +15 -5
  14. package/dist/cjs/SelectTrigger.native.js.map +1 -1
  15. package/dist/cjs/SelectViewport.cjs +22 -30
  16. package/dist/cjs/SelectViewport.native.cjs +2 -2
  17. package/dist/cjs/SelectViewport.native.js +2 -2
  18. package/dist/cjs/SelectViewport.native.js.map +1 -1
  19. package/dist/cjs/selectionController.cjs +15 -5
  20. package/dist/cjs/selectionController.native.cjs +20 -15
  21. package/dist/cjs/selectionController.native.js +20 -15
  22. package/dist/cjs/selectionController.native.js.map +1 -1
  23. package/dist/esm/Select.mjs +27 -28
  24. package/dist/esm/Select.mjs.map +1 -1
  25. package/dist/esm/Select.native.js +31 -29
  26. package/dist/esm/Select.native.js.map +1 -1
  27. package/dist/esm/SelectImpl.mjs +56 -50
  28. package/dist/esm/SelectImpl.mjs.map +1 -1
  29. package/dist/esm/SelectItem.mjs +50 -61
  30. package/dist/esm/SelectItem.mjs.map +1 -1
  31. package/dist/esm/SelectItem.native.js +52 -80
  32. package/dist/esm/SelectItem.native.js.map +1 -1
  33. package/dist/esm/SelectScrollButton.mjs +2 -2
  34. package/dist/esm/SelectScrollButton.mjs.map +1 -1
  35. package/dist/esm/SelectTrigger.mjs +16 -5
  36. package/dist/esm/SelectTrigger.mjs.map +1 -1
  37. package/dist/esm/SelectTrigger.native.js +15 -4
  38. package/dist/esm/SelectTrigger.native.js.map +1 -1
  39. package/dist/esm/SelectViewport.mjs +22 -30
  40. package/dist/esm/SelectViewport.mjs.map +1 -1
  41. package/dist/esm/SelectViewport.native.js +3 -3
  42. package/dist/esm/SelectViewport.native.js.map +1 -1
  43. package/dist/esm/selectionController.mjs +15 -5
  44. package/dist/esm/selectionController.mjs.map +1 -1
  45. package/dist/esm/selectionController.native.js +20 -15
  46. package/dist/esm/selectionController.native.js.map +1 -1
  47. package/dist/jsx/Select.mjs +27 -28
  48. package/dist/jsx/Select.mjs.map +1 -1
  49. package/dist/jsx/Select.native.cjs +27 -26
  50. package/dist/jsx/Select.native.js +27 -26
  51. package/dist/jsx/Select.native.js.map +1 -1
  52. package/dist/jsx/SelectImpl.mjs +56 -50
  53. package/dist/jsx/SelectImpl.mjs.map +1 -1
  54. package/dist/jsx/SelectItem.mjs +50 -61
  55. package/dist/jsx/SelectItem.mjs.map +1 -1
  56. package/dist/jsx/SelectItem.native.cjs +51 -79
  57. package/dist/jsx/SelectItem.native.js +51 -79
  58. package/dist/jsx/SelectItem.native.js.map +1 -1
  59. package/dist/jsx/SelectScrollButton.mjs +2 -2
  60. package/dist/jsx/SelectScrollButton.mjs.map +1 -1
  61. package/dist/jsx/SelectTrigger.mjs +16 -5
  62. package/dist/jsx/SelectTrigger.mjs.map +1 -1
  63. package/dist/jsx/SelectTrigger.native.cjs +15 -5
  64. package/dist/jsx/SelectTrigger.native.js +15 -5
  65. package/dist/jsx/SelectTrigger.native.js.map +1 -1
  66. package/dist/jsx/SelectViewport.mjs +22 -30
  67. package/dist/jsx/SelectViewport.mjs.map +1 -1
  68. package/dist/jsx/SelectViewport.native.cjs +2 -2
  69. package/dist/jsx/SelectViewport.native.js +2 -2
  70. package/dist/jsx/SelectViewport.native.js.map +1 -1
  71. package/dist/jsx/selectionController.mjs +15 -5
  72. package/dist/jsx/selectionController.mjs.map +1 -1
  73. package/dist/jsx/selectionController.native.cjs +20 -15
  74. package/dist/jsx/selectionController.native.js +20 -15
  75. package/dist/jsx/selectionController.native.js.map +1 -1
  76. package/package.json +30 -29
  77. package/src/Select.tsx +41 -41
  78. package/src/SelectImpl.tsx +83 -81
  79. package/src/SelectItem.tsx +66 -91
  80. package/src/SelectScrollButton.tsx +2 -2
  81. package/src/SelectTrigger.tsx +19 -2
  82. package/src/SelectViewport.native.tsx +4 -4
  83. package/src/SelectViewport.tsx +21 -27
  84. package/src/selectionController.ts +20 -5
  85. package/src/types.tsx +26 -21
  86. package/types/Select.d.ts +42 -81
  87. package/types/Select.d.ts.map +1 -1
  88. package/types/SelectImpl.d.ts.map +1 -1
  89. package/types/SelectItem.d.ts +3 -5
  90. package/types/SelectItem.d.ts.map +1 -1
  91. package/types/SelectItemText.d.ts +3 -5
  92. package/types/SelectItemText.d.ts.map +1 -1
  93. package/types/SelectScrollButton.d.ts +5 -9
  94. package/types/SelectScrollButton.d.ts.map +1 -1
  95. package/types/SelectScrollButton.native.d.ts +5 -9
  96. package/types/SelectScrollButton.native.d.ts.map +1 -1
  97. package/types/SelectTrigger.d.ts +3 -5
  98. package/types/SelectTrigger.d.ts.map +1 -1
  99. package/types/SelectViewport.d.ts +4 -9
  100. package/types/SelectViewport.d.ts.map +1 -1
  101. package/types/SelectViewport.native.d.ts +4 -9
  102. package/types/SelectViewport.native.d.ts.map +1 -1
  103. package/types/selectionController.d.ts +2 -0
  104. package/types/selectionController.d.ts.map +1 -1
  105. package/types/types.d.ts +30 -21
  106. package/types/types.d.ts.map +1 -1
@@ -32,7 +32,6 @@ var import_constants = require("@tamagui/constants");
32
32
  var import_core = require("@tamagui/core");
33
33
  var import_helpers = require("@tamagui/helpers");
34
34
  var React = __toESM(require("react"), 1);
35
- var import_react_dom = require("react-dom");
36
35
  var import_constants2 = require("./constants.cjs");
37
36
  var import_context = require("./context.cjs");
38
37
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -42,7 +41,6 @@ const SelectInlineImpl = (props) => {
42
41
  const selectItemParentContext = (0, import_context.useSelectItemParentContext)(scope);
43
42
  const { setActiveIndex, selectedIndex, activeIndexRef } = selectContext;
44
43
  const { requestOpenChange, registry } = selectItemParentContext;
45
- const [scrollTop, setScrollTop] = React.useState(0);
46
44
  const touch = (0, import_core.useIsTouchDevice)();
47
45
  const listItemsRef = selectItemParentContext.listRef;
48
46
  const overflowRef = React.useRef(null);
@@ -60,10 +58,10 @@ const SelectInlineImpl = (props) => {
60
58
  const [fallback, setFallback] = React.useState(false);
61
59
  const [innerOffset, setInnerOffset] = React.useState(0);
62
60
  const [blockSelection, setBlockSelection] = React.useState(false);
63
- const floatingStyle = React.useRef({});
64
61
  React.useEffect(() => {
65
62
  if (!open) {
66
- setScrollTop(0);
63
+ setCanScrollUp(false);
64
+ setCanScrollDown(false);
67
65
  setFallback(false);
68
66
  setControlledScrolling(false);
69
67
  }
@@ -83,9 +81,8 @@ const SelectInlineImpl = (props) => {
83
81
  placement: "bottom-start",
84
82
  whileElementsMounted: import_floating.autoUpdate,
85
83
  middleware: [
86
- (0, import_floating.size)({ apply({ rects: { reference: { width } } }) {
87
- Object.assign(floatingStyle.current, { minWidth: width + 8 });
88
- if (refs.floating.current) Object.assign(refs.floating.current.style, floatingStyle.current);
84
+ (0, import_floating.size)({ apply({ rects, elements }) {
85
+ elements.floating.style.minWidth = `${rects.reference.width + 8}px`;
89
86
  } }),
90
87
  (0, import_floating.inner)({
91
88
  listRef: listItemsRef,
@@ -97,18 +94,22 @@ const SelectInlineImpl = (props) => {
97
94
  minItemsVisible: touch ? 10 : 4,
98
95
  referenceOverflowThreshold: 20
99
96
  }),
100
- (0, import_floating.offset)({ crossAxis: -5 })
97
+ (0, import_floating.offset)({ crossAxis: -4 })
101
98
  ]
102
99
  });
103
- const floatingRef = refs.floating;
104
- const showUpArrow = open && scrollTop > import_constants2.SCROLL_ARROW_THRESHOLD;
105
- const showDownArrow = open && floatingRef.current && scrollTop < floatingRef.current.scrollHeight - floatingRef.current.clientHeight - import_constants2.SCROLL_ARROW_THRESHOLD;
100
+ const [canScrollUp, setCanScrollUp] = React.useState(false);
101
+ const [canScrollDown, setCanScrollDown] = React.useState(false);
102
+ const updateScrollArrows = React.useCallback(() => {
103
+ const el = refs.floating.current;
104
+ if (!el) return;
105
+ setCanScrollUp(el.scrollTop > import_constants2.SCROLL_ARROW_THRESHOLD);
106
+ setCanScrollDown(el.scrollTop < el.scrollHeight - el.clientHeight - import_constants2.SCROLL_ARROW_THRESHOLD);
107
+ }, [refs]);
108
+ const showUpArrow = open && canScrollUp;
109
+ const showDownArrow = open && canScrollDown;
106
110
  const isScrollable = showDownArrow || showUpArrow;
107
111
  (0, import_constants.useIsomorphicLayoutEffect)(() => {
108
- if (typeof window === "undefined") return;
109
- window.addEventListener("resize", update);
110
112
  if (open) update();
111
- return () => window.removeEventListener("resize", update);
112
113
  }, [update, open]);
113
114
  const onMatch = (0, import_core.useEvent)((index) => {
114
115
  if (!open) return;
@@ -121,23 +122,32 @@ const SelectInlineImpl = (props) => {
121
122
  });
122
123
  const dataRef = React.useRef({});
123
124
  dataRef.current.placement = computedPlacement;
124
- const interactionContext = {
125
+ const onOpenChange = (0, import_core.useEvent)((nextOpen, event, reason) => {
126
+ requestOpenChange(nextOpen, (0, import_core.createChangeEventDetails)(reason === "list-navigation" ? "keyboard" : "trigger-press", event, refs.reference.current));
127
+ });
128
+ const referenceElement = refs.reference.current || null;
129
+ const floatingElement = refs.floating.current || null;
130
+ const interactionContext = React.useMemo(() => ({
125
131
  open,
126
- onOpenChange: (nextOpen, event, reason) => {
127
- requestOpenChange(nextOpen, (0, import_core.createChangeEventDetails)(reason === "list-navigation" ? "keyboard" : "trigger-press", event, refs.reference.current));
128
- },
132
+ onOpenChange,
129
133
  refs: {
130
134
  reference: refs.reference,
131
135
  floating: refs.floating,
132
136
  domReference: refs.reference
133
137
  },
134
138
  elements: {
135
- reference: refs.reference?.current || null,
136
- floating: refs.floating?.current || null,
137
- domReference: refs.reference?.current || null
139
+ reference: referenceElement,
140
+ floating: floatingElement,
141
+ domReference: referenceElement
138
142
  },
139
143
  dataRef
140
- };
144
+ }), [
145
+ open,
146
+ onOpenChange,
147
+ refs,
148
+ referenceElement,
149
+ floatingElement
150
+ ]);
141
151
  const interactionsProps = [
142
152
  (0, import_floating.useClick)(interactionContext, {
143
153
  event: "mousedown",
@@ -152,7 +162,7 @@ const SelectInlineImpl = (props) => {
152
162
  }),
153
163
  (0, import_floating.useListNavigation)(interactionContext, {
154
164
  listRef: listItemsRef,
155
- activeIndex: selectContext.activeIndex ?? 0,
165
+ activeIndex: null,
156
166
  selectedIndex,
157
167
  onNavigate: (index) => {
158
168
  if (index !== null) setActiveIndex(index, {
@@ -163,13 +173,14 @@ const SelectInlineImpl = (props) => {
163
173
  });
164
174
  },
165
175
  disabledIndices: registry.getDisabledIndices(),
166
- scrollItemIntoView: false
176
+ scrollItemIntoView: false,
177
+ focusItemOnHover: false
167
178
  }),
168
179
  (0, import_floating.useTypeahead)(interactionContext, {
169
180
  listRef: listContentRef,
170
181
  onMatch,
171
182
  selectedIndex,
172
- activeIndex: selectContext.activeIndex,
183
+ activeIndex: null,
173
184
  onTypingChange: (e) => {
174
185
  state.current.isTyping = e;
175
186
  }
@@ -180,7 +191,6 @@ const SelectInlineImpl = (props) => {
180
191
  }, interactionsProps));
181
192
  const interactionsContext = React.useMemo(() => {
182
193
  return {
183
- ...interactions,
184
194
  getReferenceProps(props2 = {}) {
185
195
  return interactions.getReferenceProps({
186
196
  ...props2,
@@ -196,17 +206,7 @@ const SelectInlineImpl = (props) => {
196
206
  getFloatingProps(props2) {
197
207
  return interactions.getFloatingProps({
198
208
  ref: refs.floating,
199
- className: "Select",
200
209
  ...props2,
201
- style: {
202
- position: strategy,
203
- top: y ?? "",
204
- left: x ?? "",
205
- outline: 0,
206
- scrollbarWidth: "none",
207
- ...floatingStyle.current,
208
- ...props2?.style
209
- },
210
210
  onPointerEnter() {
211
211
  setControlledScrolling(false);
212
212
  state.current.isMouseOutside = false;
@@ -225,20 +225,24 @@ const SelectInlineImpl = (props) => {
225
225
  onContextMenu(e) {
226
226
  e.preventDefault();
227
227
  },
228
- onScroll(event) {
229
- (0, import_react_dom.flushSync)(() => {
230
- setScrollTop(event.currentTarget.scrollTop);
231
- });
232
- }
228
+ onScroll: updateScrollArrows
233
229
  });
234
230
  }
235
231
  };
236
232
  }, [
237
- refs.reference.current,
233
+ refs,
234
+ interactions,
235
+ requestOpenChange,
236
+ updateScrollArrows
237
+ ]);
238
+ const floatingPosition = React.useMemo(() => ({
239
+ position: strategy,
240
+ top: y ?? "",
241
+ left: x ?? ""
242
+ }), [
243
+ strategy,
238
244
  x,
239
- y,
240
- refs.floating.current,
241
- interactions
245
+ y
242
246
  ]);
243
247
  (0, import_constants.useIsomorphicLayoutEffect)(() => {
244
248
  if (open) {
@@ -264,15 +268,15 @@ const SelectInlineImpl = (props) => {
264
268
  if (!open) return;
265
269
  const scrollActiveIntoView = (index) => {
266
270
  if (controlledScrolling && index != null) listItemsRef.current[index]?.scrollIntoView({ block: "nearest" });
267
- setScrollTop(refs.floating.current?.scrollTop ?? 0);
271
+ updateScrollArrows();
268
272
  };
269
273
  scrollActiveIntoView(activeIndexRef.current);
270
274
  return selectItemParentContext.activeIndexSubscribe(scrollActiveIntoView);
271
275
  }, [
272
276
  open,
273
- refs,
274
277
  controlledScrolling,
275
- selectItemParentContext.activeIndexSubscribe
278
+ selectItemParentContext.activeIndexSubscribe,
279
+ updateScrollArrows
276
280
  ]);
277
281
  React.useEffect(() => {
278
282
  if (open && fallback) {
@@ -293,10 +297,12 @@ const SelectInlineImpl = (props) => {
293
297
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_context.SelectProvider, {
294
298
  scope,
295
299
  ...selectContext,
296
- setScrollTop,
300
+ updateScrollArrows,
297
301
  setInnerOffset,
298
302
  fallback,
299
303
  floatingContext,
304
+ interactions: interactionsContext,
305
+ floatingPosition,
300
306
  canScrollDown: !!showDownArrow,
301
307
  canScrollUp: !!showUpArrow,
302
308
  controlledScrolling,
@@ -310,7 +316,7 @@ const SelectInlineImpl = (props) => {
310
316
  allowMouseUpRef,
311
317
  allowSelectRef,
312
318
  dataRef,
313
- interactions: interactionsContext,
319
+ getItemProps: interactions.getItemProps,
314
320
  listRef: listItemsRef,
315
321
  selectTimeoutRef,
316
322
  children
@@ -52,34 +52,22 @@ const SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Se
52
52
  const { scope, value, disabled: disabledProp, "aria-disabled": ariaDisabled, textValue: textValueProp, ...restProps } = props;
53
53
  const disabled = disabledProp ?? ariaDisabled === true;
54
54
  const context = (0, import_context.useSelectItemParentContext)(scope);
55
- const selectContext = (0, import_context.useSelectContext)(scope);
56
- const isAdapted = (0, import_adapt.useAdaptIsActive)(selectContext.adaptScope);
57
- const { listRef, registry, mode, selectedValues, selectValue, activeIndexSubscribe, activeIndexRef, allowMouseUpRef, allowSelectRef, selectTimeoutRef, interactions, shouldRenderWebNative, setActiveIndexFast, moveActive, search } = context;
55
+ const isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
56
+ const { registry, mode, selectedValues, selectValue, activeIndexSubscribe, activeIndexRef, allowMouseUpRef, allowSelectRef, selectTimeoutRef, getItemProps, shouldRenderWebNative, setActiveIndex, lastPointerRef, moveActive, search } = context;
58
57
  const isSelected = selectedValues.includes(value);
59
58
  const pendingMouseUpSelectionRef = React.useRef(false);
60
59
  const itemNodeRef = React.useRef(null);
61
- const [, rerenderRegistry] = React.useReducer((version) => version + 1, 0);
62
60
  const registrationRef = React.useRef(null);
63
61
  const initialRegistration = React.useRef({
64
62
  value,
65
63
  disabled,
66
64
  textValue: textValueProp
67
65
  });
68
- (0, import_constants.useIsomorphicLayoutEffect)(() => registry.subscribe(() => rerenderRegistry()), [registry]);
69
66
  (0, import_constants.useIsomorphicLayoutEffect)(() => {
70
67
  const registration = registry.registerItem(initialRegistration.current);
71
68
  registrationRef.current = registration;
72
- const registeredNode = itemNodeRef.current;
73
- registration.setNode(registeredNode);
74
- const registeredIndex = registry.getItems().findIndex((item) => item.id === registration.id);
75
- if (import_constants.isWeb && listRef && registeredIndex >= 0 && registeredNode instanceof HTMLElement) {
76
- listRef.current[registeredIndex] = registeredNode;
77
- }
69
+ registration.setNode(itemNodeRef.current);
78
70
  return () => {
79
- const currentIndex = registry.getItems().findIndex((item) => item.id === registration.id);
80
- if (listRef && currentIndex >= 0 && listRef.current[currentIndex] === registeredNode) {
81
- listRef.current[currentIndex] = null;
82
- }
83
71
  registrationRef.current = null;
84
72
  registration.unregister();
85
73
  };
@@ -98,37 +86,34 @@ const SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Se
98
86
  (0, import_constants.useIsomorphicLayoutEffect)(() => {
99
87
  registrationRef.current?.setNode(itemNodeRef.current);
100
88
  });
101
- const index = registry.getIndex(value);
89
+ const [isActive, setIsActive] = React.useState(false);
90
+ const isActiveRef = React.useRef(false);
102
91
  React.useEffect(() => {
103
92
  const handleActiveIndex = (i) => {
104
- if (index === i) {
105
- if (import_constants.isWeb) {
106
- requestAnimationFrame(() => {
107
- listRef?.current[index]?.focus();
108
- });
109
- }
93
+ const next = i != null && registry.getIndex(value) === i;
94
+ if (next !== isActiveRef.current) {
95
+ isActiveRef.current = next;
96
+ setIsActive(next);
97
+ }
98
+ if (next && import_constants.isWeb) {
99
+ requestAnimationFrame(() => {
100
+ itemNodeRef.current?.focus?.();
101
+ });
110
102
  }
111
103
  };
112
- const currentActiveIndex = activeIndexRef?.current;
113
- if (currentActiveIndex !== null && currentActiveIndex !== void 0) {
114
- handleActiveIndex(currentActiveIndex);
115
- }
104
+ handleActiveIndex(activeIndexRef?.current ?? null);
116
105
  return activeIndexSubscribe(handleActiveIndex);
117
106
  }, [
118
107
  activeIndexRef,
119
108
  activeIndexSubscribe,
120
- index,
121
- listRef
109
+ registry,
110
+ value
122
111
  ]);
123
112
  const textId = React.useId();
124
113
  const refCallback = React.useCallback((node) => {
125
114
  itemNodeRef.current = node;
126
115
  registrationRef.current?.setNode(node);
127
- if (!import_constants.isWeb) return;
128
- if (listRef && index >= 0) {
129
- listRef.current[index] = node instanceof HTMLElement ? node : null;
130
- }
131
- }, [index, listRef]);
116
+ }, []);
132
117
  const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, refCallback);
133
118
  const handleSelect = React.useCallback((event, reason = "item-press") => {
134
119
  if (disabled) return;
@@ -139,6 +124,27 @@ const SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Se
139
124
  selectValue,
140
125
  value
141
126
  ]);
127
+ const handleMouseMove = React.useCallback((event) => {
128
+ if (disabled) return;
129
+ const index = registry.getIndex(value);
130
+ if (index < 0) return;
131
+ const last = lastPointerRef.current;
132
+ if (event.clientX === last.x && event.clientY === last.y) return;
133
+ last.x = event.clientX;
134
+ last.y = event.clientY;
135
+ setActiveIndex(index, {
136
+ reason: "item-hover",
137
+ event: event.nativeEvent || event,
138
+ trigger: event.currentTarget,
139
+ index
140
+ });
141
+ }, [
142
+ disabled,
143
+ lastPointerRef,
144
+ registry,
145
+ setActiveIndex,
146
+ value
147
+ ]);
142
148
  const handleKeyDown = React.useCallback((event) => {
143
149
  if (disabled) return;
144
150
  if (event.key === "Enter" || event.key === " ") {
@@ -152,7 +158,7 @@ const SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Se
152
158
  moveActive(event.key === "ArrowDown" ? 1 : -1, event.nativeEvent || event);
153
159
  return;
154
160
  }
155
- if (!interactions && event.key?.length === 1 && !event.metaKey && !event.ctrlKey) {
161
+ if (!getItemProps && event.key?.length === 1 && !event.metaKey && !event.ctrlKey) {
156
162
  search(event.key, event.nativeEvent || event);
157
163
  }
158
164
  if (allowSelectRef) {
@@ -162,14 +168,14 @@ const SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Se
162
168
  allowSelectRef,
163
169
  disabled,
164
170
  handleSelect,
165
- interactions,
171
+ getItemProps,
166
172
  moveActive,
167
173
  search
168
174
  ]);
169
175
  const selectItemProps = React.useMemo(() => {
170
- if (interactions) {
176
+ if (getItemProps) {
171
177
  const { onTouchMove, onTouchEnd, onKeyDown, onClick, onMouseUp, onMouseMove, onPress, ...itemProps } = restProps;
172
- const interactionProps = interactions.getItemProps({
178
+ const interactionProps = getItemProps({
173
179
  ...itemProps,
174
180
  onTouchMove() {
175
181
  allowSelectRef.current = true;
@@ -179,15 +185,7 @@ const SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Se
179
185
  allowSelectRef.current = false;
180
186
  allowMouseUpRef.current = true;
181
187
  },
182
- onMouseMove(event) {
183
- if (disabled || index < 0) return;
184
- setActiveIndexFast?.(index, {
185
- reason: "item-hover",
186
- event: event.nativeEvent || event,
187
- trigger: event.currentTarget,
188
- index
189
- });
190
- },
188
+ onMouseMove: handleMouseMove,
191
189
  onKeyDown: handleKeyDown,
192
190
  onClick(event) {
193
191
  if (disabled) return;
@@ -240,15 +238,7 @@ const SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Se
240
238
  return {
241
239
  ...restProps,
242
240
  onKeyDown: (0, import_helpers.composeEventHandlers)(restProps.onKeyDown, handleKeyDown),
243
- onMouseMove: (0, import_helpers.composeEventHandlers)(restProps.onMouseMove, (event) => {
244
- if (disabled || index < 0) return;
245
- setActiveIndexFast?.(index, {
246
- reason: "item-hover",
247
- event: event.nativeEvent || event,
248
- trigger: event.currentTarget,
249
- index
250
- });
251
- }),
241
+ onMouseMove: (0, import_helpers.composeEventHandlers)(restProps.onMouseMove, handleMouseMove),
252
242
  onPress: (0, import_helpers.composeEventHandlers)(restProps.onPress, handleSelect)
253
243
  };
254
244
  }, [
@@ -256,12 +246,11 @@ const SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Se
256
246
  allowSelectRef,
257
247
  disabled,
258
248
  handleKeyDown,
249
+ handleMouseMove,
259
250
  handleSelect,
260
- index,
261
- interactions,
251
+ getItemProps,
262
252
  restProps,
263
- selectTimeoutRef,
264
- setActiveIndexFast
253
+ selectTimeoutRef
265
254
  ]);
266
255
  const accessibilityProps = (0, import_selectionController.getSelectOptionProps)(mode, isSelected, disabled, import_constants.isWeb ? "web" : "native");
267
256
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItemContextProvider, {
@@ -280,7 +269,7 @@ const SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Se
280
269
  "aria-labelledby": textId,
281
270
  "data-state": isSelected ? "active" : "inactive",
282
271
  "data-disabled": disabled ? "" : void 0,
283
- tabIndex: disabled ? void 0 : import_constants.isWeb && isAdapted ? index === (selectContext.activeIndex ?? selectContext.selectedIndex) ? 0 : -1 : -1,
272
+ tabIndex: disabled ? void 0 : import_constants.isWeb && isAdapted && (isActive || activeIndexRef?.current == null && isSelected) ? 0 : -1,
284
273
  zIndex: 100,
285
274
  ...selectItemProps,
286
275
  ...accessibilityProps
@@ -43,13 +43,6 @@ var import_helpers = require("@tamagui/helpers");
43
43
  var React = __toESM(require("react"), 1);
44
44
  var import_context = require("./context.native.js");
45
45
  var import_selectionController = require("./selectionController.native.js");
46
- function _instanceof(left, right) {
47
- if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
48
- return !!right[Symbol.hasInstance](left);
49
- } else {
50
- return left instanceof right;
51
- }
52
- }
53
46
  var ITEM_NAME = "SelectItem";
54
47
  var { Provider: SelectItemContextProvider, useStyledContext: useSelectItemContext } = (0, import_core.createStyledContext)(null, ITEM_NAME);
55
48
  var SelectItemFrame = (0, import_core.styled)(import_core.View, {
@@ -61,44 +54,22 @@ var SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Sele
61
54
  var { scope, value, disabled: disabledProp, "aria-disabled": ariaDisabled, textValue: textValueProp, ...restProps } = props;
62
55
  var disabled = disabledProp !== null && disabledProp !== void 0 ? disabledProp : ariaDisabled === true;
63
56
  var context = (0, import_context.useSelectItemParentContext)(scope);
64
- var selectContext = (0, import_context.useSelectContext)(scope);
65
- var isAdapted = (0, import_adapt.useAdaptIsActive)(selectContext.adaptScope);
66
- var { listRef, registry, mode, selectedValues, selectValue, activeIndexSubscribe, activeIndexRef, allowMouseUpRef, allowSelectRef, selectTimeoutRef, interactions, shouldRenderWebNative, setActiveIndexFast, moveActive, search } = context;
57
+ var isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
58
+ var { registry, mode, selectedValues, selectValue, activeIndexSubscribe, activeIndexRef, allowMouseUpRef, allowSelectRef, selectTimeoutRef, getItemProps, shouldRenderWebNative, setActiveIndex, lastPointerRef, moveActive, search } = context;
67
59
  var isSelected = selectedValues.includes(value);
68
60
  var pendingMouseUpSelectionRef = React.useRef(false);
69
61
  var itemNodeRef = React.useRef(null);
70
- var [, rerenderRegistry] = React.useReducer(function(version) {
71
- return version + 1;
72
- }, 0);
73
62
  var registrationRef = React.useRef(null);
74
63
  var initialRegistration = React.useRef({
75
64
  value,
76
65
  disabled,
77
66
  textValue: textValueProp
78
67
  });
79
- (0, import_constants.useIsomorphicLayoutEffect)(function() {
80
- return registry.subscribe(function() {
81
- return rerenderRegistry();
82
- });
83
- }, [registry]);
84
68
  (0, import_constants.useIsomorphicLayoutEffect)(function() {
85
69
  var registration = registry.registerItem(initialRegistration.current);
86
70
  registrationRef.current = registration;
87
- var registeredNode = itemNodeRef.current;
88
- registration.setNode(registeredNode);
89
- var registeredIndex = registry.getItems().findIndex(function(item) {
90
- return item.id === registration.id;
91
- });
92
- if (import_constants.isWeb && listRef && registeredIndex >= 0 && _instanceof(registeredNode, HTMLElement)) {
93
- listRef.current[registeredIndex] = registeredNode;
94
- }
71
+ registration.setNode(itemNodeRef.current);
95
72
  return function() {
96
- var currentIndex = registry.getItems().findIndex(function(item) {
97
- return item.id === registration.id;
98
- });
99
- if (listRef && currentIndex >= 0 && listRef.current[currentIndex] === registeredNode) {
100
- listRef.current[currentIndex] = null;
101
- }
102
73
  registrationRef.current = null;
103
74
  registration.unregister();
104
75
  };
@@ -119,39 +90,37 @@ var SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Sele
119
90
  var _registrationRef_current;
120
91
  (_registrationRef_current = registrationRef.current) === null || _registrationRef_current === void 0 ? void 0 : _registrationRef_current.setNode(itemNodeRef.current);
121
92
  });
122
- var index = registry.getIndex(value);
93
+ var [isActive, setIsActive] = React.useState(false);
94
+ var isActiveRef = React.useRef(false);
123
95
  React.useEffect(function() {
124
96
  var handleActiveIndex = function(i) {
125
- if (index === i) {
126
- if (import_constants.isWeb) {
127
- requestAnimationFrame(function() {
128
- var _listRef_current_index;
129
- listRef === null || listRef === void 0 ? void 0 : (_listRef_current_index = listRef.current[index]) === null || _listRef_current_index === void 0 ? void 0 : _listRef_current_index.focus();
130
- });
131
- }
97
+ var next = i != null && registry.getIndex(value) === i;
98
+ if (next !== isActiveRef.current) {
99
+ isActiveRef.current = next;
100
+ setIsActive(next);
101
+ }
102
+ if (next && import_constants.isWeb) {
103
+ requestAnimationFrame(function() {
104
+ var _itemNodeRef_current_focus, _itemNodeRef_current;
105
+ (_itemNodeRef_current = itemNodeRef.current) === null || _itemNodeRef_current === void 0 ? void 0 : (_itemNodeRef_current_focus = _itemNodeRef_current.focus) === null || _itemNodeRef_current_focus === void 0 ? void 0 : _itemNodeRef_current_focus.call(_itemNodeRef_current);
106
+ });
132
107
  }
133
108
  };
134
- var currentActiveIndex = activeIndexRef === null || activeIndexRef === void 0 ? void 0 : activeIndexRef.current;
135
- if (currentActiveIndex !== null && currentActiveIndex !== void 0) {
136
- handleActiveIndex(currentActiveIndex);
137
- }
109
+ var _activeIndexRef_current;
110
+ handleActiveIndex((_activeIndexRef_current = activeIndexRef === null || activeIndexRef === void 0 ? void 0 : activeIndexRef.current) !== null && _activeIndexRef_current !== void 0 ? _activeIndexRef_current : null);
138
111
  return activeIndexSubscribe(handleActiveIndex);
139
112
  }, [
140
113
  activeIndexRef,
141
114
  activeIndexSubscribe,
142
- index,
143
- listRef
115
+ registry,
116
+ value
144
117
  ]);
145
118
  var textId = React.useId();
146
119
  var refCallback = React.useCallback(function(node) {
147
120
  var _registrationRef_current;
148
121
  itemNodeRef.current = node;
149
122
  (_registrationRef_current = registrationRef.current) === null || _registrationRef_current === void 0 ? void 0 : _registrationRef_current.setNode(node);
150
- if (!import_constants.isWeb) return;
151
- if (listRef && index >= 0) {
152
- listRef.current[index] = _instanceof(node, HTMLElement) ? node : null;
153
- }
154
- }, [index, listRef]);
123
+ }, []);
155
124
  var composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, refCallback);
156
125
  var handleSelect = React.useCallback(function(event) {
157
126
  var reason = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "item-press";
@@ -163,6 +132,27 @@ var SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Sele
163
132
  selectValue,
164
133
  value
165
134
  ]);
135
+ var handleMouseMove = React.useCallback(function(event) {
136
+ if (disabled) return;
137
+ var index = registry.getIndex(value);
138
+ if (index < 0) return;
139
+ var last = lastPointerRef.current;
140
+ if (event.clientX === last.x && event.clientY === last.y) return;
141
+ last.x = event.clientX;
142
+ last.y = event.clientY;
143
+ setActiveIndex(index, {
144
+ reason: "item-hover",
145
+ event: event.nativeEvent || event,
146
+ trigger: event.currentTarget,
147
+ index
148
+ });
149
+ }, [
150
+ disabled,
151
+ lastPointerRef,
152
+ registry,
153
+ setActiveIndex,
154
+ value
155
+ ]);
166
156
  var handleKeyDown = React.useCallback(function(event) {
167
157
  var _event_key;
168
158
  if (disabled) return;
@@ -177,7 +167,7 @@ var SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Sele
177
167
  moveActive(event.key === "ArrowDown" ? 1 : -1, event.nativeEvent || event);
178
168
  return;
179
169
  }
180
- if (!interactions && ((_event_key = event.key) === null || _event_key === void 0 ? void 0 : _event_key.length) === 1 && !event.metaKey && !event.ctrlKey) {
170
+ if (!getItemProps && ((_event_key = event.key) === null || _event_key === void 0 ? void 0 : _event_key.length) === 1 && !event.metaKey && !event.ctrlKey) {
181
171
  search(event.key, event.nativeEvent || event);
182
172
  }
183
173
  if (allowSelectRef) {
@@ -187,14 +177,14 @@ var SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Sele
187
177
  allowSelectRef,
188
178
  disabled,
189
179
  handleSelect,
190
- interactions,
180
+ getItemProps,
191
181
  moveActive,
192
182
  search
193
183
  ]);
194
184
  var selectItemProps = React.useMemo(function() {
195
- if (interactions) {
185
+ if (getItemProps) {
196
186
  var { onTouchMove, onTouchEnd, onKeyDown, onClick, onMouseUp, onMouseMove, onPress, ...itemProps } = restProps;
197
- var interactionProps = interactions.getItemProps({
187
+ var interactionProps = getItemProps({
198
188
  ...itemProps,
199
189
  onTouchMove() {
200
190
  allowSelectRef.current = true;
@@ -204,15 +194,7 @@ var SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Sele
204
194
  allowSelectRef.current = false;
205
195
  allowMouseUpRef.current = true;
206
196
  },
207
- onMouseMove(event) {
208
- if (disabled || index < 0) return;
209
- setActiveIndexFast === null || setActiveIndexFast === void 0 ? void 0 : setActiveIndexFast(index, {
210
- reason: "item-hover",
211
- event: event.nativeEvent || event,
212
- trigger: event.currentTarget,
213
- index
214
- });
215
- },
197
+ onMouseMove: handleMouseMove,
216
198
  onKeyDown: handleKeyDown,
217
199
  onClick(event) {
218
200
  if (disabled) return;
@@ -266,15 +248,7 @@ var SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Sele
266
248
  return {
267
249
  ...restProps,
268
250
  onKeyDown: (0, import_helpers.composeEventHandlers)(restProps.onKeyDown, handleKeyDown),
269
- onMouseMove: (0, import_helpers.composeEventHandlers)(restProps.onMouseMove, function(event) {
270
- if (disabled || index < 0) return;
271
- setActiveIndexFast === null || setActiveIndexFast === void 0 ? void 0 : setActiveIndexFast(index, {
272
- reason: "item-hover",
273
- event: event.nativeEvent || event,
274
- trigger: event.currentTarget,
275
- index
276
- });
277
- }),
251
+ onMouseMove: (0, import_helpers.composeEventHandlers)(restProps.onMouseMove, handleMouseMove),
278
252
  onPress: (0, import_helpers.composeEventHandlers)(restProps.onPress, handleSelect)
279
253
  };
280
254
  }, [
@@ -282,15 +256,13 @@ var SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Sele
282
256
  allowSelectRef,
283
257
  disabled,
284
258
  handleKeyDown,
259
+ handleMouseMove,
285
260
  handleSelect,
286
- index,
287
- interactions,
261
+ getItemProps,
288
262
  restProps,
289
- selectTimeoutRef,
290
- setActiveIndexFast
263
+ selectTimeoutRef
291
264
  ]);
292
265
  var accessibilityProps = (0, import_selectionController.getSelectOptionProps)(mode, isSelected, disabled, import_constants.isWeb ? "web" : "native");
293
- var _selectContext_activeIndex;
294
266
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItemContextProvider, {
295
267
  scope,
296
268
  value,
@@ -307,7 +279,7 @@ var SelectItem = (0, import_core.createStyledHOC)(SelectItemFrame, function Sele
307
279
  "aria-labelledby": textId,
308
280
  "data-state": isSelected ? "active" : "inactive",
309
281
  "data-disabled": disabled ? "" : void 0,
310
- tabIndex: disabled ? void 0 : import_constants.isWeb && isAdapted ? index === ((_selectContext_activeIndex = selectContext.activeIndex) !== null && _selectContext_activeIndex !== void 0 ? _selectContext_activeIndex : selectContext.selectedIndex) ? 0 : -1 : -1,
282
+ tabIndex: disabled ? void 0 : import_constants.isWeb && isAdapted && (isActive || (activeIndexRef === null || activeIndexRef === void 0 ? void 0 : activeIndexRef.current) == null && isSelected) ? 0 : -1,
311
283
  zIndex: 100,
312
284
  ...selectItemProps,
313
285
  ...accessibilityProps