@tamagui/select 1.0.1-beta.118 → 1.0.1-beta.121

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 (49) hide show
  1. package/dist/cjs/Select.js +36 -32
  2. package/dist/cjs/Select.js.map +2 -2
  3. package/dist/cjs/SelectContent.js +2 -1
  4. package/dist/cjs/SelectContent.js.map +2 -2
  5. package/dist/cjs/SelectImpl.js +154 -284
  6. package/dist/cjs/SelectImpl.js.map +2 -2
  7. package/dist/cjs/SelectScrollButton.js +54 -40
  8. package/dist/cjs/SelectScrollButton.js.map +2 -2
  9. package/dist/cjs/SelectViewport.js +10 -6
  10. package/dist/cjs/SelectViewport.js.map +2 -2
  11. package/dist/cjs/types.js.map +1 -1
  12. package/dist/esm/Select.js +36 -32
  13. package/dist/esm/Select.js.map +2 -2
  14. package/dist/esm/SelectContent.js +3 -2
  15. package/dist/esm/SelectContent.js.map +2 -2
  16. package/dist/esm/SelectImpl.js +158 -286
  17. package/dist/esm/SelectImpl.js.map +2 -2
  18. package/dist/esm/SelectScrollButton.js +54 -40
  19. package/dist/esm/SelectScrollButton.js.map +2 -2
  20. package/dist/esm/SelectViewport.js +10 -6
  21. package/dist/esm/SelectViewport.js.map +2 -2
  22. package/dist/jsx/Select.js +34 -34
  23. package/dist/jsx/Select.js.map +2 -2
  24. package/dist/jsx/SelectContent.js +3 -2
  25. package/dist/jsx/SelectContent.js.map +2 -2
  26. package/dist/jsx/SelectImpl.js +128 -266
  27. package/dist/jsx/SelectImpl.js.map +2 -2
  28. package/dist/jsx/SelectScrollButton.js +53 -39
  29. package/dist/jsx/SelectScrollButton.js.map +2 -2
  30. package/dist/jsx/SelectViewport.js +10 -6
  31. package/dist/jsx/SelectViewport.js.map +2 -2
  32. package/package.json +15 -15
  33. package/src/Select.tsx +47 -49
  34. package/src/SelectContent.tsx +4 -2
  35. package/src/SelectImpl.tsx +179 -369
  36. package/src/SelectScrollButton.tsx +72 -54
  37. package/src/SelectViewport.tsx +12 -6
  38. package/src/types.tsx +9 -1
  39. package/types/Select.d.ts +15 -15
  40. package/types/Select.d.ts.map +1 -1
  41. package/types/SelectContent.d.ts +0 -1
  42. package/types/SelectContent.d.ts.map +1 -1
  43. package/types/SelectImpl.d.ts.map +1 -1
  44. package/types/SelectViewport.d.ts +3 -3
  45. package/types/SelectViewport.d.ts.map +1 -1
  46. package/types/types.d.ts +9 -1
  47. package/types/types.d.ts.map +1 -1
  48. package/types/constants.d.ts +0 -8
  49. package/types/constants.d.ts.map +0 -1
@@ -1,18 +1,24 @@
1
1
  import {
2
+ SideObject,
2
3
  detectOverflow,
3
4
  flip,
5
+ inner,
4
6
  offset,
7
+ shift,
5
8
  size,
6
9
  useClick,
7
10
  useDismiss,
8
11
  useFloating,
12
+ useInnerOffset,
9
13
  useInteractions,
10
14
  useListNavigation,
11
15
  useRole,
12
16
  useTypeahead,
13
17
  } from '@floating-ui/react-dom-interactions'
14
18
  import { usePrevious } from '@radix-ui/react-use-previous'
19
+ import { useForceUpdate, useIsTouchDevice } from '@tamagui/core'
15
20
  import * as React from 'react'
21
+ import { flushSync } from 'react-dom'
16
22
 
17
23
  import { FALLBACK_THRESHOLD, MIN_HEIGHT, SCROLL_ARROW_THRESHOLD, WINDOW_PADDING } from './constants'
18
24
  import { SelectProvider, useSelectContext } from './context'
@@ -26,36 +32,35 @@ export type SelectImplProps = ScopedProps<SelectProps> & {
26
32
 
27
33
  // TODO use id for focusing from label
28
34
  export const SelectInlineImpl = (props: SelectImplProps) => {
29
- const {
30
- __scopeSelect,
31
- children,
32
- open = false,
33
- activeIndexRef,
34
- selectedIndexRef,
35
- listContentRef,
36
- } = props
35
+ const { __scopeSelect, children, open = false, selectedIndexRef, listContentRef } = props
37
36
 
38
37
  const selectContext = useSelectContext('SelectSheetImpl', __scopeSelect)
39
38
  const { setActiveIndex, setOpen, setSelectedIndex, selectedIndex, activeIndex, forceUpdate } =
40
39
  selectContext
41
- const [showArrows, setShowArrows] = React.useState(false)
42
40
  const [scrollTop, setScrollTop] = React.useState(0)
43
- const prevActiveIndex = usePrevious<number | null>(activeIndex)
41
+ const touch = useIsTouchDevice()
44
42
 
45
43
  const listItemsRef = React.useRef<Array<HTMLElement | null>>([])
44
+ const overflowRef = React.useRef<null | SideObject>(null)
45
+ const upArrowRef = React.useRef<HTMLDivElement | null>(null)
46
+ const downArrowRef = React.useRef<HTMLDivElement | null>(null)
47
+ const allowSelectRef = React.useRef(false)
48
+ const allowMouseUpRef = React.useRef(true)
49
+ const selectTimeoutRef = React.useRef<any>()
46
50
 
47
51
  const [controlledScrolling, setControlledScrolling] = React.useState(false)
48
- const [middlewareType, setMiddlewareType] = React.useState<'align' | 'fallback'>('align')
52
+ const [fallback, setFallback] = React.useState(false)
53
+ const [innerOffset, setInnerOffset] = React.useState(0)
54
+ const [blockSelection, setBlockSelection] = React.useState(false)
55
+ const floatingStyle = React.useRef({})
49
56
 
50
57
  // Wait for scroll position to settle before showing arrows to prevent
51
58
  // interference with pointer events.
52
59
  React.useEffect(() => {
53
60
  const frame = requestAnimationFrame(() => {
54
- setShowArrows(open)
55
-
56
61
  if (!open) {
57
62
  setScrollTop(0)
58
- setMiddlewareType('align')
63
+ setFallback(false)
59
64
  setActiveIndex(null)
60
65
  setControlledScrolling(false)
61
66
  }
@@ -65,113 +70,68 @@ export const SelectInlineImpl = (props: SelectImplProps) => {
65
70
  }
66
71
  }, [open, setActiveIndex])
67
72
 
68
- function getFloatingPadding(floating: HTMLElement | null) {
69
- if (!floating) {
70
- return 0
71
- }
72
- return Number(getComputedStyle(floating).paddingLeft?.replace('px', ''))
73
- }
74
-
75
- const { x, y, reference, floating, strategy, context, refs, middlewareData, update } =
76
- useFloating({
77
- open,
78
- onOpenChange: setOpen,
79
- placement: 'bottom',
80
- middleware:
81
- middlewareType === 'align'
82
- ? [
83
- offset(({ rects }) => {
84
- const index = activeIndexRef.current ?? selectedIndexRef.current
85
-
86
- if (index == null) {
87
- return 0
88
- }
89
-
90
- const item = listItemsRef.current[index]
91
-
92
- if (item == null) {
93
- return 0
94
- }
95
-
96
- const offsetTop = item.offsetTop
97
- const itemHeight = item.offsetHeight
98
- const height = rects.reference.height
99
-
100
- return -offsetTop - height - (itemHeight - height) / 2
101
- }),
102
- // Custom `size` that can handle the opposite direction of the placement
103
- {
104
- name: 'size',
105
- async fn(args) {
106
- const {
107
- elements: { floating },
108
- rects: { reference },
109
- middlewareData,
110
- } = args
111
-
112
- const overflow = await detectOverflow(args, {
113
- padding: WINDOW_PADDING,
114
- })
115
-
116
- const top = Math.max(0, overflow.top)
117
- const bottom = Math.max(0, overflow.bottom)
118
- const nextY = args.y + top
119
-
120
- if (middlewareData.size?.skip) {
121
- return {
122
- y: nextY,
123
- data: {
124
- y: middlewareData.size.y,
125
- },
126
- }
127
- }
128
-
129
- Object.assign(floating.style, {
130
- maxHeight: `${floating.scrollHeight - Math.abs(top + bottom)}px`,
131
- minWidth: `${reference.width + getFloatingPadding(floating) * 2}px`,
132
- })
73
+ const updateFloatingSize = size({
74
+ apply({
75
+ availableHeight,
76
+ rects: {
77
+ reference: { width },
78
+ },
79
+ }) {
80
+ floatingStyle.current = {
81
+ width: width,
82
+ maxHeight: availableHeight,
83
+ }
84
+ },
85
+ padding: WINDOW_PADDING,
86
+ })
133
87
 
134
- return {
135
- y: nextY,
136
- data: {
137
- y: top,
138
- skip: true,
139
- },
140
- reset: {
141
- rects: true,
142
- },
143
- }
144
- },
145
- },
146
- ]
147
- : [
148
- offset(5),
149
- flip(),
150
- size({
151
- apply({ rects, availableHeight, elements }) {
152
- Object.assign(elements.floating.style, {
153
- width: `${rects.reference.width}px`,
154
- maxHeight: `${availableHeight}px`,
155
- })
156
- },
157
- padding: WINDOW_PADDING,
158
- }),
159
- ],
160
- })
88
+ const { x, y, reference, floating, strategy, context, refs } = useFloating({
89
+ open,
90
+ onOpenChange: setOpen,
91
+ placement: 'bottom-start',
92
+ middleware: fallback
93
+ ? [
94
+ offset(5),
95
+ ...[
96
+ touch
97
+ ? shift({ crossAxis: true, padding: WINDOW_PADDING })
98
+ : flip({ padding: WINDOW_PADDING }),
99
+ ],
100
+ updateFloatingSize,
101
+ ]
102
+ : [
103
+ inner({
104
+ listRef: listItemsRef,
105
+ overflowRef,
106
+ index: selectedIndex,
107
+ offset: innerOffset,
108
+ onFallbackChange: setFallback,
109
+ padding: 10,
110
+ minItemsVisible: touch ? 10 : 4,
111
+ referenceOverflowThreshold: 20,
112
+ }),
113
+ updateFloatingSize,
114
+ ],
115
+ })
161
116
 
162
117
  const floatingRef = refs.floating
163
118
 
164
- const showUpArrow = showArrows && scrollTop > SCROLL_ARROW_THRESHOLD
119
+ const showUpArrow = open && scrollTop > SCROLL_ARROW_THRESHOLD
165
120
  const showDownArrow =
166
- showArrows &&
121
+ open &&
167
122
  floatingRef.current &&
168
123
  scrollTop <
169
124
  floatingRef.current.scrollHeight - floatingRef.current.clientHeight - SCROLL_ARROW_THRESHOLD
170
125
 
171
126
  const interactions = useInteractions([
172
127
  useClick(context, { pointerDown: true }),
128
+ useDismiss(context, { outsidePointerDown: false }),
173
129
  useRole(context, { role: 'listbox' }),
174
- useDismiss(context),
130
+ useInnerOffset(context, {
131
+ enabled: !fallback,
132
+ onChange: setInnerOffset,
133
+ overflowRef,
134
+ }),
175
135
  useListNavigation(context, {
176
136
  listRef: listItemsRef,
177
137
  activeIndex,
@@ -186,304 +146,148 @@ export const SelectInlineImpl = (props: SelectImplProps) => {
186
146
  }),
187
147
  ])
188
148
 
189
- const increaseHeight = React.useCallback(
190
- (floating: HTMLElement, amount = 0) => {
191
- if (middlewareType === 'fallback') {
192
- return
193
- }
194
-
195
- const currentMaxHeight = Number(floating.style.maxHeight.replace('px', ''))
196
- const currentTop = Number(floating.style.top.replace('px', ''))
197
- const rect = floating.getBoundingClientRect()
198
- const rectTop = rect.top
199
- const rectBottom = rect.bottom
200
- const viewportHeight = visualViewport?.height ?? 0
201
- const visualMaxHeight = viewportHeight - WINDOW_PADDING * 2
202
-
203
- if (
204
- amount < 0 &&
205
- selectedIndexRef.current != null &&
206
- Math.round(rectBottom) < Math.round(viewportHeight + getVisualOffsetTop() - WINDOW_PADDING)
207
- ) {
208
- floating.style.maxHeight = `${Math.min(visualMaxHeight, currentMaxHeight - amount)}px`
209
- }
210
-
211
- if (
212
- amount > 0 &&
213
- Math.round(rectTop) > Math.round(WINDOW_PADDING - getVisualOffsetTop()) &&
214
- floating.scrollHeight > floating.offsetHeight
215
- ) {
216
- const nextTop = Math.max(WINDOW_PADDING + getVisualOffsetTop(), currentTop - amount)
217
-
218
- const nextMaxHeight = Math.min(visualMaxHeight, currentMaxHeight + amount)
219
-
220
- Object.assign(floating.style, {
221
- maxHeight: `${nextMaxHeight}px`,
222
- top: `${nextTop}px`,
223
- })
224
-
225
- if (nextTop - WINDOW_PADDING > getVisualOffsetTop()) {
226
- floating.scrollTop -= nextMaxHeight - currentMaxHeight + getFloatingPadding(floating)
227
- }
228
-
229
- return currentTop - nextTop
230
- }
149
+ const interactionsContext = {
150
+ ...interactions,
151
+ getReferenceProps() {
152
+ return interactions.getReferenceProps({
153
+ ref: reference,
154
+ className: 'SelectTrigger',
155
+ onKeyDown(event) {
156
+ if (event.key === 'Enter' || (event.key === ' ' && !context.dataRef.current.typing)) {
157
+ event.preventDefault()
158
+ setOpen(true)
159
+ }
160
+ },
161
+ })
231
162
  },
232
- [middlewareType, selectedIndexRef]
233
- )
234
-
235
- const touchPageYRef = React.useRef<number | null>(null)
236
-
237
- const handleWheel = React.useCallback(
238
- (event: WheelEvent | TouchEvent) => {
239
- const pinching = event.ctrlKey
163
+ getFloatingProps(props) {
164
+ return interactions.getFloatingProps({
165
+ ref: floating,
166
+ className: 'Select',
167
+ ...props,
168
+ style: {
169
+ position: strategy,
170
+ top: y ?? '',
171
+ left: x ?? '',
172
+ outline: 0,
173
+ listStyleType: 'none',
174
+ scrollbarWidth: 'none',
175
+ ...floatingStyle.current,
176
+ ...props?.style,
177
+ },
178
+ onPointerEnter() {
179
+ setControlledScrolling(false)
180
+ },
181
+ onPointerMove() {
182
+ setControlledScrolling(false)
183
+ },
184
+ onKeyDown() {
185
+ setControlledScrolling(true)
186
+ },
187
+ onContextMenu(e) {
188
+ e.preventDefault()
189
+ },
190
+ onScroll(event) {
191
+ // In React 18, the ScrollArrows need to synchronously know this value to prevent
192
+ // painting at the wrong time.
193
+ flushSync(() => setScrollTop(event.currentTarget.scrollTop))
194
+ },
195
+ })
196
+ },
197
+ }
240
198
 
241
- const currentTarget = event.currentTarget as HTMLElement
199
+ // effects
242
200
 
243
- function isWheelEvent(event: any): event is WheelEvent {
244
- return typeof event.deltaY === 'number'
245
- }
201
+ React.useLayoutEffect(() => {
202
+ if (open) {
203
+ selectTimeoutRef.current = setTimeout(() => {
204
+ allowSelectRef.current = true
205
+ }, 300)
246
206
 
247
- function isTouchEvent(event: any): event is TouchEvent {
248
- return event.touches != null
207
+ return () => {
208
+ clearTimeout(selectTimeoutRef.current)
249
209
  }
210
+ } else {
211
+ allowSelectRef.current = false
212
+ allowMouseUpRef.current = true
213
+ setInnerOffset(0)
214
+ setFallback(false)
215
+ setBlockSelection(false)
216
+ }
217
+ }, [open])
250
218
 
219
+ // Replacement for `useDismiss` as the arrows are outside of the floating
220
+ // element DOM tree.
221
+ React.useLayoutEffect(() => {
222
+ function onPointerDown(e: PointerEvent) {
223
+ const target = e.target as Node
251
224
  if (
252
- Math.abs(
253
- (currentTarget?.offsetHeight ?? 0) - ((visualViewport?.height ?? 0) - WINDOW_PADDING * 2)
254
- ) > 1 &&
255
- !pinching
225
+ !refs.floating.current?.contains(target) &&
226
+ !upArrowRef.current?.contains(target) &&
227
+ !downArrowRef.current?.contains(target)
256
228
  ) {
257
- event.preventDefault()
258
- } else if (isWheelEvent(event) && isFirefox) {
259
- // Firefox needs this to propagate scrolling
260
- // during momentum scrolling phase if the
261
- // height reached its maximum (at boundaries)
262
- currentTarget.scrollTop += event.deltaY
263
- }
264
-
265
- if (!pinching) {
266
- let delta = 5
267
-
268
- if (isTouchEvent(event)) {
269
- const currentPageY = touchPageYRef.current
270
- const pageY = event.touches[0]?.pageY
271
-
272
- if (pageY != null) {
273
- touchPageYRef.current = pageY
274
-
275
- if (currentPageY != null) {
276
- delta = currentPageY - pageY
277
- }
278
- }
279
- }
280
-
281
- increaseHeight(currentTarget, isWheelEvent(event) ? event.deltaY : delta)
282
- setScrollTop(currentTarget.scrollTop)
283
- // Ensure derived data (scroll arrows) is fresh
284
- forceUpdate()
229
+ setOpen(false)
285
230
  }
286
- },
287
- [forceUpdate, increaseHeight]
288
- )
289
-
290
- // Handle `onWheel` event in an effect to remove the `passive` option so we
291
- // can .preventDefault() it
292
- React.useEffect(() => {
293
- function onTouchEnd() {
294
- touchPageYRef.current = null
295
231
  }
296
232
 
297
- const floating = floatingRef.current
298
- if (open && floating && middlewareType === 'align') {
299
- floating.addEventListener('wheel', handleWheel)
300
- floating.addEventListener('touchmove', handleWheel)
301
- floating.addEventListener('touchend', onTouchEnd, { passive: true })
233
+ if (open) {
234
+ document.addEventListener('pointerdown', onPointerDown)
302
235
  return () => {
303
- floating.removeEventListener('wheel', handleWheel)
304
- floating.removeEventListener('touchmove', handleWheel)
305
- floating.removeEventListener('touchend', onTouchEnd)
236
+ document.removeEventListener('pointerdown', onPointerDown)
306
237
  }
307
238
  }
308
- }, [open, floatingRef, handleWheel, middlewareType])
239
+ }, [open, refs, setOpen])
309
240
 
310
- // Ensure the menu remains attached to the reference element when resizing.
311
- React.useEffect(() => {
312
- window.addEventListener('resize', update)
313
- return () => {
314
- window.removeEventListener('resize', update)
315
- }
316
- }, [update])
317
-
318
- // Scroll the active or selected item into view when in `controlledScrolling`
319
- // mode (i.e. arrow key nav).
241
+ // Scroll the `activeIndex` item into view only in "controlledScrolling"
242
+ // (keyboard nav) mode.
320
243
  React.useLayoutEffect(() => {
321
- const floating = floatingRef.current
322
-
323
- if (open && controlledScrolling && floating) {
324
- const item =
325
- activeIndex != null
326
- ? listItemsRef.current[activeIndex]
327
- : selectedIndex != null
328
- ? listItemsRef.current[selectedIndex]
329
- : null
330
-
331
- if (item && prevActiveIndex != null) {
332
- const itemHeight = listItemsRef.current[prevActiveIndex]?.offsetHeight ?? 0
333
-
334
- const floatingHeight = floating.offsetHeight
335
- const top = item.offsetTop
336
- const bottom = top + itemHeight
337
-
338
- if (top < floating.scrollTop + 20) {
339
- const diff = floating.scrollTop - top + 20
340
- floating.scrollTop -= diff
341
-
342
- if (activeIndex != selectedIndex && activeIndex != null) {
343
- increaseHeight(floating, -diff)
344
- }
345
- } else if (bottom > floatingHeight + floating.scrollTop - 20) {
346
- const diff = bottom - floatingHeight - floating.scrollTop + 20
347
-
348
- floating.scrollTop += diff
349
-
350
- if (activeIndex != selectedIndex && activeIndex != null) {
351
- floating.scrollTop -= increaseHeight(floating, diff) ?? 0
352
- }
244
+ if (open && controlledScrolling) {
245
+ requestAnimationFrame(() => {
246
+ if (activeIndex != null) {
247
+ listItemsRef.current[activeIndex]?.scrollIntoView({ block: 'nearest' })
353
248
  }
354
- }
249
+ })
355
250
  }
356
- }, [
357
- open,
358
- controlledScrolling,
359
- prevActiveIndex,
360
- activeIndex,
361
- selectedIndex,
362
- floatingRef,
363
- increaseHeight,
364
- ])
365
251
 
366
- // Sync the height and the scrollTop values and device whether to use fallback
367
- // positioning.
368
- React.useLayoutEffect(() => {
369
- const floating = refs.floating.current
370
- const reference = refs.reference.current
371
-
372
- if (open && floating && reference && floating.offsetHeight < floating.scrollHeight) {
373
- const referenceRect = reference.getBoundingClientRect()
374
-
375
- if (middlewareType === 'fallback') {
376
- const item = listItemsRef.current[selectedIndex]
377
- if (item) {
378
- floating.scrollTop = item.offsetTop - floating.clientHeight + referenceRect.height
379
- }
380
- return
381
- }
382
-
383
- floating.scrollTop = middlewareData.size?.y
384
-
385
- const closeToBottom =
386
- (visualViewport?.height ?? 0) + getVisualOffsetTop() - referenceRect.bottom <
387
- FALLBACK_THRESHOLD
388
- const closeToTop = referenceRect.top < FALLBACK_THRESHOLD
389
-
390
- if (floating.offsetHeight < MIN_HEIGHT || closeToTop || closeToBottom) {
391
- setMiddlewareType('fallback')
392
- }
393
- }
394
- }, [
395
- open,
396
- increaseHeight,
397
- selectedIndex,
398
- middlewareType,
399
- refs.floating,
400
- refs.reference,
401
- // Always re-run this effect when the position has been computed so the
402
- // .scrollTop change works with fresh sizing.
403
- middlewareData,
404
- ])
252
+ setScrollTop(refs.floating.current?.scrollTop ?? 0)
253
+ }, [open, refs, controlledScrolling, activeIndex])
405
254
 
255
+ // Scroll the `selectedIndex` into view upon opening the floating element.
406
256
  React.useLayoutEffect(() => {
407
- if (open && selectedIndex != null) {
257
+ if (open && fallback) {
408
258
  requestAnimationFrame(() => {
409
- listItemsRef.current[selectedIndex]?.focus({ preventScroll: true })
259
+ if (selectedIndex != null) {
260
+ listItemsRef.current[selectedIndex]?.scrollIntoView({ block: 'nearest' })
261
+ }
410
262
  })
411
263
  }
412
- }, [listItemsRef, selectedIndex, open])
413
-
414
- // Wait for scroll position to settle before showing arrows to prevent
415
- // interference with pointer events.
416
- React.useEffect(() => {
417
- const frame = requestAnimationFrame(() => {
418
- setShowArrows(open)
264
+ }, [open, fallback, selectedIndex])
419
265
 
420
- if (!open) {
421
- setScrollTop(0)
422
- setMiddlewareType('align')
423
- setActiveIndex(null)
424
- setControlledScrolling(false)
425
- }
426
- })
427
- return () => cancelAnimationFrame(frame)
428
- }, [open, setActiveIndex])
266
+ // Unset the height limiting for fallback mode. This gets executed prior to
267
+ // the positioning call.
268
+ React.useLayoutEffect(() => {
269
+ if (refs.floating.current && fallback) {
270
+ refs.floating.current.style.maxHeight = ''
271
+ }
272
+ }, [refs, fallback])
429
273
 
430
274
  // We set this to true by default so that events bubble to forms without JS (SSR)
431
275
  // const isFormControl = trigger ? Boolean(trigger.closest('form')) : true
432
276
  // const [bubbleSelect, setBubbleSelect] = React.useState<HTMLSelectElement | null>(null)
433
277
  // const triggerPointerDownPosRef = React.useRef<{ x: number; y: number } | null>(null)
278
+
434
279
  return (
435
280
  <SelectProvider
436
281
  scope={__scopeSelect}
437
282
  {...(selectContext as Required<typeof selectContext>)}
438
- increaseHeight={increaseHeight}
283
+ setScrollTop={setScrollTop}
284
+ setInnerOffset={setInnerOffset}
439
285
  floatingRef={floatingRef}
440
286
  setValueAtIndex={(index, value) => {
441
287
  listContentRef.current[index] = value
442
288
  }}
443
- interactions={{
444
- ...interactions,
445
- getReferenceProps() {
446
- return interactions.getReferenceProps({
447
- ref: reference,
448
- className: 'SelectTrigger',
449
- onKeyDown(event) {
450
- if (event.key === 'Enter' || (event.key === ' ' && !context.dataRef.current.typing)) {
451
- event.preventDefault()
452
- setOpen(true)
453
- }
454
- },
455
- })
456
- },
457
- getFloatingProps(props) {
458
- return interactions.getFloatingProps({
459
- ref: floating,
460
- className: 'Select',
461
- ...props,
462
- style: {
463
- position: strategy,
464
- top: y ?? '',
465
- left: x ?? '',
466
- outline: 0,
467
- listStyleType: 'none',
468
- scrollbarWidth: 'none',
469
- userSelect: 'none',
470
- ...props?.style,
471
- },
472
- onPointerEnter() {
473
- setControlledScrolling(false)
474
- },
475
- onPointerMove() {
476
- setControlledScrolling(false)
477
- },
478
- onKeyDown() {
479
- setControlledScrolling(true)
480
- },
481
- onScroll(event) {
482
- setScrollTop(event.currentTarget.scrollTop)
483
- },
484
- })
485
- },
486
- }}
289
+ fallback={fallback}
290
+ interactions={interactionsContext}
487
291
  floatingContext={context}
488
292
  activeIndex={activeIndex}
489
293
  canScrollDown={!!showDownArrow}
@@ -491,6 +295,12 @@ export const SelectInlineImpl = (props: SelectImplProps) => {
491
295
  controlledScrolling
492
296
  dataRef={context.dataRef}
493
297
  listRef={listItemsRef}
298
+ blockSelection={blockSelection}
299
+ allowMouseUpRef={allowMouseUpRef}
300
+ upArrowRef={upArrowRef}
301
+ downArrowRef={downArrowRef}
302
+ selectTimeoutRef={selectTimeoutRef}
303
+ allowSelectRef={allowSelectRef}
494
304
  >
495
305
  {children}
496
306
  {/* {isFormControl ? (