@tamagui/select 2.7.7 → 3.0.0-beta.643.1
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.
- package/dist/cjs/Select.cjs +409 -467
- package/dist/cjs/Select.native.cjs +495 -0
- package/dist/cjs/Select.native.js +445 -492
- package/dist/cjs/Select.native.js.map +1 -1
- package/dist/cjs/SelectContent.cjs +80 -79
- package/dist/cjs/SelectContent.native.cjs +30 -0
- package/dist/cjs/SelectContent.native.js +18 -22
- package/dist/cjs/SelectContent.native.js.map +1 -1
- package/dist/cjs/SelectImpl.cjs +299 -319
- package/dist/cjs/SelectImpl.native.cjs +30 -0
- package/dist/cjs/SelectImpl.native.js +17 -24
- package/dist/cjs/SelectImpl.native.js.map +1 -1
- package/dist/cjs/SelectItem.cjs +268 -205
- package/dist/cjs/SelectItem.native.cjs +317 -0
- package/dist/cjs/SelectItem.native.js +291 -211
- package/dist/cjs/SelectItem.native.js.map +1 -1
- package/dist/cjs/SelectItemText.cjs +49 -79
- package/dist/cjs/SelectItemText.native.cjs +74 -0
- package/dist/cjs/SelectItemText.native.js +50 -79
- package/dist/cjs/SelectItemText.native.js.map +1 -1
- package/dist/cjs/SelectScrollButton.cjs +111 -130
- package/dist/cjs/SelectScrollButton.native.cjs +38 -0
- package/dist/cjs/SelectScrollButton.native.js +25 -22
- package/dist/cjs/SelectScrollButton.native.js.map +1 -1
- package/dist/cjs/SelectTrigger.cjs +69 -84
- package/dist/cjs/SelectTrigger.native.cjs +91 -0
- package/dist/cjs/SelectTrigger.native.js +71 -66
- package/dist/cjs/SelectTrigger.native.js.map +1 -1
- package/dist/cjs/SelectViewport.cjs +119 -142
- package/dist/cjs/SelectViewport.native.cjs +73 -0
- package/dist/cjs/SelectViewport.native.js +54 -50
- package/dist/cjs/SelectViewport.native.js.map +1 -1
- package/dist/cjs/constants.cjs +21 -22
- package/dist/cjs/constants.native.cjs +41 -0
- package/dist/cjs/constants.native.js +21 -21
- package/dist/cjs/constants.native.js.map +1 -1
- package/dist/cjs/context.cjs +38 -48
- package/dist/cjs/context.native.cjs +58 -0
- package/dist/cjs/context.native.js +40 -49
- package/dist/cjs/context.native.js.map +1 -1
- package/dist/cjs/index.cjs +15 -11
- package/dist/cjs/index.native.cjs +27 -0
- package/dist/cjs/index.native.js +15 -10
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/selectionController.cjs +334 -0
- package/dist/cjs/selectionController.native.cjs +403 -0
- package/dist/cjs/selectionController.native.js +405 -0
- package/dist/cjs/selectionController.native.js.map +1 -0
- package/dist/cjs/types.cjs +10 -11
- package/dist/cjs/types.native.cjs +19 -0
- package/dist/cjs/types.native.js +10 -10
- package/dist/cjs/types.native.js.map +1 -1
- package/dist/esm/Select.mjs +382 -443
- package/dist/esm/Select.mjs.map +1 -1
- package/dist/esm/Select.native.js +418 -469
- package/dist/esm/Select.native.js.map +1 -1
- package/dist/esm/SelectContent.mjs +67 -61
- package/dist/esm/SelectContent.mjs.map +1 -1
- package/dist/esm/SelectContent.native.js +4 -5
- package/dist/esm/SelectContent.native.js.map +1 -1
- package/dist/esm/SelectImpl.mjs +284 -294
- package/dist/esm/SelectImpl.mjs.map +1 -1
- package/dist/esm/SelectImpl.native.js +5 -8
- package/dist/esm/SelectImpl.native.js.map +1 -1
- package/dist/esm/SelectItem.mjs +252 -182
- package/dist/esm/SelectItem.mjs.map +1 -1
- package/dist/esm/SelectItem.native.js +276 -190
- package/dist/esm/SelectItem.native.js.map +1 -1
- package/dist/esm/SelectItemText.mjs +33 -55
- package/dist/esm/SelectItemText.mjs.map +1 -1
- package/dist/esm/SelectItemText.native.js +34 -56
- package/dist/esm/SelectItemText.native.js.map +1 -1
- package/dist/esm/SelectScrollButton.mjs +95 -107
- package/dist/esm/SelectScrollButton.mjs.map +1 -1
- package/dist/esm/SelectScrollButton.native.js +11 -7
- package/dist/esm/SelectScrollButton.native.js.map +1 -1
- package/dist/esm/SelectTrigger.mjs +56 -58
- package/dist/esm/SelectTrigger.mjs.map +1 -1
- package/dist/esm/SelectTrigger.native.js +54 -44
- package/dist/esm/SelectTrigger.native.js.map +1 -1
- package/dist/esm/SelectViewport.mjs +104 -119
- package/dist/esm/SelectViewport.mjs.map +1 -1
- package/dist/esm/SelectViewport.native.js +44 -39
- package/dist/esm/SelectViewport.native.js.map +1 -1
- package/dist/esm/constants.mjs +1 -0
- package/dist/esm/constants.mjs.map +1 -1
- package/dist/esm/constants.native.js +1 -0
- package/dist/esm/constants.native.js.map +1 -1
- package/dist/esm/context.mjs +20 -28
- package/dist/esm/context.mjs.map +1 -1
- package/dist/esm/context.native.js +23 -31
- package/dist/esm/context.native.js.map +1 -1
- package/dist/esm/index.js +13 -3
- package/dist/esm/index.mjs +13 -3
- package/dist/esm/index.native.js +13 -3
- package/dist/esm/selectionController.mjs +305 -0
- package/dist/esm/selectionController.mjs.map +1 -0
- package/dist/esm/selectionController.native.js +372 -0
- package/dist/esm/selectionController.native.js.map +1 -0
- package/dist/esm/types.mjs +0 -2
- package/dist/esm/types.native.js +0 -2
- package/dist/jsx/Select.mjs +382 -443
- package/dist/jsx/Select.mjs.map +1 -1
- package/dist/jsx/Select.native.cjs +495 -0
- package/dist/jsx/Select.native.js +445 -492
- package/dist/jsx/Select.native.js.map +1 -1
- package/dist/jsx/SelectContent.mjs +67 -61
- package/dist/jsx/SelectContent.mjs.map +1 -1
- package/dist/jsx/SelectContent.native.cjs +30 -0
- package/dist/jsx/SelectContent.native.js +18 -22
- package/dist/jsx/SelectContent.native.js.map +1 -1
- package/dist/jsx/SelectImpl.mjs +284 -294
- package/dist/jsx/SelectImpl.mjs.map +1 -1
- package/dist/jsx/SelectImpl.native.cjs +30 -0
- package/dist/jsx/SelectImpl.native.js +17 -24
- package/dist/jsx/SelectImpl.native.js.map +1 -1
- package/dist/jsx/SelectItem.mjs +252 -182
- package/dist/jsx/SelectItem.mjs.map +1 -1
- package/dist/jsx/SelectItem.native.cjs +317 -0
- package/dist/jsx/SelectItem.native.js +291 -211
- package/dist/jsx/SelectItem.native.js.map +1 -1
- package/dist/jsx/SelectItemText.mjs +33 -55
- package/dist/jsx/SelectItemText.mjs.map +1 -1
- package/dist/jsx/SelectItemText.native.cjs +74 -0
- package/dist/jsx/SelectItemText.native.js +50 -79
- package/dist/jsx/SelectItemText.native.js.map +1 -1
- package/dist/jsx/SelectScrollButton.mjs +95 -107
- package/dist/jsx/SelectScrollButton.mjs.map +1 -1
- package/dist/jsx/SelectScrollButton.native.cjs +38 -0
- package/dist/jsx/SelectScrollButton.native.js +25 -22
- package/dist/jsx/SelectScrollButton.native.js.map +1 -1
- package/dist/jsx/SelectTrigger.mjs +56 -58
- package/dist/jsx/SelectTrigger.mjs.map +1 -1
- package/dist/jsx/SelectTrigger.native.cjs +91 -0
- package/dist/jsx/SelectTrigger.native.js +71 -66
- package/dist/jsx/SelectTrigger.native.js.map +1 -1
- package/dist/jsx/SelectViewport.mjs +104 -119
- package/dist/jsx/SelectViewport.mjs.map +1 -1
- package/dist/jsx/SelectViewport.native.cjs +73 -0
- package/dist/jsx/SelectViewport.native.js +54 -50
- package/dist/jsx/SelectViewport.native.js.map +1 -1
- package/dist/jsx/constants.mjs +1 -0
- package/dist/jsx/constants.mjs.map +1 -1
- package/dist/jsx/constants.native.cjs +41 -0
- package/dist/jsx/constants.native.js +21 -21
- package/dist/jsx/constants.native.js.map +1 -1
- package/dist/jsx/context.mjs +20 -28
- package/dist/jsx/context.mjs.map +1 -1
- package/dist/jsx/context.native.cjs +58 -0
- package/dist/jsx/context.native.js +40 -49
- package/dist/jsx/context.native.js.map +1 -1
- package/dist/jsx/index.js +13 -3
- package/dist/jsx/index.mjs +13 -3
- package/dist/jsx/index.native.cjs +27 -0
- package/dist/jsx/index.native.js +15 -10
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/selectionController.mjs +305 -0
- package/dist/jsx/selectionController.mjs.map +1 -0
- package/dist/jsx/selectionController.native.cjs +403 -0
- package/dist/jsx/selectionController.native.js +405 -0
- package/dist/jsx/selectionController.native.js.map +1 -0
- package/dist/jsx/types.mjs +0 -2
- package/dist/jsx/types.native.cjs +19 -0
- package/dist/jsx/types.native.js +10 -10
- package/dist/jsx/types.native.js.map +1 -1
- package/package.json +28 -28
- package/src/Select.tsx +457 -357
- package/src/SelectContent.tsx +46 -16
- package/src/SelectImpl.native.tsx +0 -8
- package/src/SelectImpl.tsx +87 -100
- package/src/SelectItem.tsx +282 -136
- package/src/SelectItemText.tsx +16 -33
- package/src/SelectScrollButton.native.tsx +13 -4
- package/src/SelectScrollButton.tsx +56 -41
- package/src/SelectTrigger.tsx +77 -53
- package/src/SelectViewport.native.tsx +42 -25
- package/src/SelectViewport.tsx +52 -51
- package/src/context.tsx +6 -2
- package/src/index.tsx +5 -2
- package/src/selectionController.ts +389 -0
- package/src/types.tsx +88 -45
- package/types/Select.d.ts +139 -201
- package/types/Select.d.ts.map +1 -1
- package/types/SelectContent.d.ts +1 -1
- package/types/SelectContent.d.ts.map +1 -1
- package/types/SelectContent.native.d.ts.map +1 -1
- package/types/SelectImpl.d.ts +2 -1
- package/types/SelectImpl.d.ts.map +1 -1
- package/types/SelectImpl.native.d.ts +1 -5
- package/types/SelectImpl.native.d.ts.map +1 -1
- package/types/SelectItem.d.ts +13 -16
- package/types/SelectItem.d.ts.map +1 -1
- package/types/SelectItemText.d.ts +9 -13
- package/types/SelectItemText.d.ts.map +1 -1
- package/types/SelectScrollButton.d.ts +15 -2
- package/types/SelectScrollButton.d.ts.map +1 -1
- package/types/SelectScrollButton.native.d.ts +16 -3
- package/types/SelectScrollButton.native.d.ts.map +1 -1
- package/types/SelectTrigger.d.ts +11 -23
- package/types/SelectTrigger.d.ts.map +1 -1
- package/types/SelectViewport.d.ts +11 -38
- package/types/SelectViewport.d.ts.map +1 -1
- package/types/SelectViewport.native.d.ts +15 -4
- package/types/SelectViewport.native.d.ts.map +1 -1
- package/types/context.d.ts +2 -0
- package/types/context.d.ts.map +1 -1
- package/types/index.d.ts +5 -2
- package/types/index.d.ts.map +1 -1
- package/types/selectionController.d.ts +88 -0
- package/types/selectionController.d.ts.map +1 -0
- package/types/types.d.ts +47 -37
- package/types/types.d.ts.map +1 -1
- package/dist/cjs/BubbleSelect.cjs +0 -50
- package/dist/cjs/BubbleSelect.native.js +0 -30
- package/dist/cjs/BubbleSelect.native.js.map +0 -1
- package/dist/cjs/useSelectBreakpointActive.cjs +0 -32
- package/dist/cjs/useSelectBreakpointActive.native.js +0 -35
- package/dist/cjs/useSelectBreakpointActive.native.js.map +0 -1
- package/dist/esm/BubbleSelect.mjs +0 -27
- package/dist/esm/BubbleSelect.mjs.map +0 -1
- package/dist/esm/BubbleSelect.native.js +0 -4
- package/dist/esm/BubbleSelect.native.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/index.mjs.map +0 -1
- package/dist/esm/index.native.js.map +0 -1
- package/dist/esm/types.mjs.map +0 -1
- package/dist/esm/types.native.js.map +0 -1
- package/dist/esm/useSelectBreakpointActive.mjs +0 -7
- package/dist/esm/useSelectBreakpointActive.mjs.map +0 -1
- package/dist/esm/useSelectBreakpointActive.native.js +0 -7
- package/dist/esm/useSelectBreakpointActive.native.js.map +0 -1
- package/dist/jsx/BubbleSelect.mjs +0 -27
- package/dist/jsx/BubbleSelect.mjs.map +0 -1
- package/dist/jsx/BubbleSelect.native.js +0 -30
- package/dist/jsx/BubbleSelect.native.js.map +0 -1
- package/dist/jsx/index.js.map +0 -1
- package/dist/jsx/index.mjs.map +0 -1
- package/dist/jsx/types.mjs.map +0 -1
- package/dist/jsx/useSelectBreakpointActive.mjs +0 -7
- package/dist/jsx/useSelectBreakpointActive.mjs.map +0 -1
- package/dist/jsx/useSelectBreakpointActive.native.js +0 -35
- package/dist/jsx/useSelectBreakpointActive.native.js.map +0 -1
- package/src/BubbleSelect.tsx +0 -50
- package/src/useSelectBreakpointActive.tsx +0 -7
- package/types/BubbleSelect.d.ts +0 -2
- package/types/BubbleSelect.d.ts.map +0 -1
- package/types/useSelectBreakpointActive.d.ts +0 -3
- package/types/useSelectBreakpointActive.d.ts.map +0 -1
package/src/SelectContent.tsx
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useAdaptContext, useAdaptIsActive } from '@tamagui/adapt'
|
|
2
2
|
import { Dismissable } from '@tamagui/dismissable'
|
|
3
3
|
import type { FocusScopeProps } from '@tamagui/focus-scope'
|
|
4
4
|
import { FocusScope } from '@tamagui/focus-scope'
|
|
5
|
+
import { composeEventHandlers } from '@tamagui/helpers'
|
|
5
6
|
|
|
6
7
|
import { Portal } from '@tamagui/portal'
|
|
7
8
|
import { RemoveScroll } from '@tamagui/remove-scroll'
|
|
@@ -12,7 +13,7 @@ import {
|
|
|
12
13
|
useSelectItemParentContext,
|
|
13
14
|
} from './context'
|
|
14
15
|
import type { SelectContentProps } from './types'
|
|
15
|
-
import {
|
|
16
|
+
import type { SelectOpenChangeDetails } from './types'
|
|
16
17
|
|
|
17
18
|
/* -------------------------------------------------------------------------------------------------
|
|
18
19
|
* SelectContent
|
|
@@ -21,12 +22,17 @@ import { useShowSelectSheet } from './useSelectBreakpointActive'
|
|
|
21
22
|
export const SelectContent = ({
|
|
22
23
|
children,
|
|
23
24
|
scope,
|
|
25
|
+
onEscapeKeyDown,
|
|
26
|
+
onPointerDownOutside,
|
|
27
|
+
onFocusOutside,
|
|
28
|
+
onInteractOutside,
|
|
24
29
|
...focusScopeProps
|
|
25
30
|
}: SelectContentProps & FocusScopeProps) => {
|
|
26
31
|
const context = useSelectContext(scope)
|
|
27
32
|
const itemParentContext = useSelectItemParentContext(scope)
|
|
28
33
|
const zIndex = useContext(SelectZIndexContext)
|
|
29
|
-
const
|
|
34
|
+
const isAdapted = useAdaptIsActive(context.adaptScope)
|
|
35
|
+
const adaptContext = useAdaptContext(context.adaptScope)
|
|
30
36
|
|
|
31
37
|
const contents = children
|
|
32
38
|
|
|
@@ -34,8 +40,11 @@ export const SelectContent = ({
|
|
|
34
40
|
return <>{children}</>
|
|
35
41
|
}
|
|
36
42
|
|
|
37
|
-
if (
|
|
38
|
-
|
|
43
|
+
if (isAdapted) {
|
|
44
|
+
// content is published into the Sheet via SelectViewport's AdaptPortalContents;
|
|
45
|
+
// keep it mounted through the sheet slide-out (adaptContext.targetFullyHidden),
|
|
46
|
+
// otherwise the sheet body vanishes mid-slide on close. mirrors Popover/Dialog.
|
|
47
|
+
if (!context.open && adaptContext.targetFullyHidden) {
|
|
39
48
|
return null
|
|
40
49
|
}
|
|
41
50
|
return <>{contents}</>
|
|
@@ -47,13 +56,35 @@ export const SelectContent = ({
|
|
|
47
56
|
<Dismissable
|
|
48
57
|
asChild
|
|
49
58
|
forceUnmount={!context.open}
|
|
50
|
-
onDismiss={() =>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
onDismiss={(details) => {
|
|
60
|
+
if (details.reason !== 'focus-out') {
|
|
61
|
+
itemParentContext.requestOpenChange(
|
|
62
|
+
false,
|
|
63
|
+
details as SelectOpenChangeDetails
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
}}
|
|
67
|
+
onEscapeKeyDown={(details) => {
|
|
68
|
+
const event = details.event as unknown as KeyboardEvent | undefined
|
|
69
|
+
event?.stopImmediatePropagation()
|
|
70
|
+
onEscapeKeyDown?.(details)
|
|
71
|
+
}}
|
|
72
|
+
onInteractOutside={onInteractOutside}
|
|
73
|
+
// focus changes during open should not dismiss the list
|
|
74
|
+
onFocusOutside={composeEventHandlers(onFocusOutside, (e) => e.cancel(), {
|
|
75
|
+
checkDefaultPrevented: false,
|
|
76
|
+
})}
|
|
77
|
+
onPointerDownOutside={composeEventHandlers(
|
|
78
|
+
onPointerDownOutside,
|
|
79
|
+
(details) => {
|
|
80
|
+
const trigger = context.floatingContext?.refs?.reference?.current
|
|
81
|
+
const target = details.event?.target
|
|
82
|
+
if (trigger instanceof HTMLElement && target instanceof Node) {
|
|
83
|
+
if (trigger.contains(target)) details.cancel()
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{ checkDefaultPrevented: false }
|
|
87
|
+
)}
|
|
57
88
|
>
|
|
58
89
|
<FocusScope
|
|
59
90
|
{...focusScopeProps}
|
|
@@ -61,19 +92,18 @@ export const SelectContent = ({
|
|
|
61
92
|
trapped
|
|
62
93
|
onMountAutoFocus={(e) => {
|
|
63
94
|
// prevent FocusScope from auto-focusing - floating-ui handles focus in SelectItem
|
|
64
|
-
e.
|
|
95
|
+
e.cancel()
|
|
65
96
|
}}
|
|
66
97
|
onUnmountAutoFocus={(e) => {
|
|
67
98
|
// return focus to trigger on close
|
|
68
|
-
e.
|
|
99
|
+
e.cancel()
|
|
69
100
|
const trigger = context.floatingContext?.refs?.reference?.current
|
|
70
101
|
if (trigger instanceof HTMLElement) {
|
|
71
102
|
trigger.focus()
|
|
72
103
|
}
|
|
73
104
|
}}
|
|
74
105
|
>
|
|
75
|
-
{
|
|
76
|
-
{isWeb ? <div style={{ display: 'contents' }}>{contents}</div> : contents}
|
|
106
|
+
{contents}
|
|
77
107
|
</FocusScope>
|
|
78
108
|
</Dismissable>
|
|
79
109
|
</RemoveScroll>
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
import type { SelectImplProps } from './types'
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* TODO can just make it a sheet for native
|
|
5
|
-
* later on can have `native` prop
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
3
|
export const SelectInlineImpl = (props: SelectImplProps) => {
|
|
9
|
-
if (process.env.NODE_ENV === 'development') {
|
|
10
|
-
console.warn('Sheet not implemented inline on native')
|
|
11
|
-
}
|
|
12
4
|
return <>{props.children}</>
|
|
13
5
|
}
|
package/src/SelectImpl.tsx
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
autoUpdate,
|
|
3
|
-
flip,
|
|
4
3
|
inner,
|
|
5
4
|
offset,
|
|
6
|
-
shift,
|
|
7
5
|
size,
|
|
8
6
|
useClick,
|
|
9
7
|
useFloatingRaw as useFloatingDom,
|
|
@@ -16,38 +14,43 @@ import {
|
|
|
16
14
|
type SideObject,
|
|
17
15
|
} from '@tamagui/floating'
|
|
18
16
|
import { useIsomorphicLayoutEffect } from '@tamagui/constants'
|
|
19
|
-
import { useEvent, useIsTouchDevice } from '@tamagui/core'
|
|
17
|
+
import { createChangeEventDetails, useEvent, useIsTouchDevice } from '@tamagui/core'
|
|
18
|
+
import { composeEventHandlers } from '@tamagui/helpers'
|
|
20
19
|
import * as React from 'react'
|
|
21
20
|
import { flushSync } from 'react-dom'
|
|
22
|
-
import { SCROLL_ARROW_THRESHOLD
|
|
21
|
+
import { SCROLL_ARROW_THRESHOLD } from './constants'
|
|
23
22
|
import {
|
|
24
23
|
SelectItemParentProvider,
|
|
25
24
|
SelectProvider,
|
|
26
25
|
useSelectContext,
|
|
27
26
|
useSelectItemParentContext,
|
|
28
27
|
} from './context'
|
|
29
|
-
import type {
|
|
28
|
+
import type {
|
|
29
|
+
SelectActiveChangeDetails,
|
|
30
|
+
SelectImplProps,
|
|
31
|
+
SelectOpenChangeDetails,
|
|
32
|
+
} from './types'
|
|
30
33
|
|
|
31
|
-
// TODO use id for focusing from label
|
|
32
34
|
export const SelectInlineImpl = (props: SelectImplProps) => {
|
|
33
|
-
const { scope, children, open = false, listContentRef
|
|
35
|
+
const { scope, children, open = false, listContentRef } = props
|
|
34
36
|
|
|
35
37
|
const selectContext = useSelectContext(scope)
|
|
36
38
|
const selectItemParentContext = useSelectItemParentContext(scope)
|
|
37
39
|
const { setActiveIndex, selectedIndex, activeIndexRef } = selectContext
|
|
38
40
|
|
|
39
|
-
const {
|
|
41
|
+
const { requestOpenChange, registry } = selectItemParentContext
|
|
40
42
|
|
|
41
43
|
const [scrollTop, setScrollTop] = React.useState(0)
|
|
42
44
|
const touch = useIsTouchDevice()
|
|
43
45
|
|
|
44
|
-
const listItemsRef =
|
|
46
|
+
const listItemsRef = selectItemParentContext.listRef!
|
|
45
47
|
const overflowRef = React.useRef<null | SideObject>(null)
|
|
46
48
|
const upArrowRef = React.useRef<HTMLDivElement | null>(null)
|
|
47
49
|
const downArrowRef = React.useRef<HTMLDivElement | null>(null)
|
|
48
50
|
const allowSelectRef = React.useRef(false)
|
|
49
51
|
const allowMouseUpRef = React.useRef(true)
|
|
50
52
|
const selectTimeoutRef = React.useRef<any>(null)
|
|
53
|
+
const latestKeyboardEventRef = React.useRef<Event | undefined>(undefined)
|
|
51
54
|
const state = React.useRef({
|
|
52
55
|
isMouseOutside: false,
|
|
53
56
|
isTyping: false,
|
|
@@ -61,15 +64,12 @@ export const SelectInlineImpl = (props: SelectImplProps) => {
|
|
|
61
64
|
|
|
62
65
|
// sync activeIndex on open/close
|
|
63
66
|
React.useEffect(() => {
|
|
64
|
-
if (open) {
|
|
65
|
-
setActiveIndexFast(selectedIndex ?? 0)
|
|
66
|
-
} else {
|
|
67
|
+
if (!open) {
|
|
67
68
|
setScrollTop(0)
|
|
68
69
|
setFallback(false)
|
|
69
|
-
setActiveIndexFast(null)
|
|
70
70
|
setControlledScrolling(false)
|
|
71
71
|
}
|
|
72
|
-
}, [open
|
|
72
|
+
}, [open])
|
|
73
73
|
|
|
74
74
|
// close when mouseup outside select
|
|
75
75
|
if (process.env.TAMAGUI_TARGET === 'web') {
|
|
@@ -77,7 +77,10 @@ export const SelectInlineImpl = (props: SelectImplProps) => {
|
|
|
77
77
|
if (!open) return
|
|
78
78
|
const mouseUp = (e: MouseEvent) => {
|
|
79
79
|
if (state.current.isMouseOutside) {
|
|
80
|
-
|
|
80
|
+
requestOpenChange(
|
|
81
|
+
false,
|
|
82
|
+
createChangeEventDetails('outside-press', e) as SelectOpenChangeDetails
|
|
83
|
+
)
|
|
81
84
|
}
|
|
82
85
|
}
|
|
83
86
|
document.addEventListener('mouseup', mouseUp)
|
|
@@ -98,56 +101,36 @@ export const SelectInlineImpl = (props: SelectImplProps) => {
|
|
|
98
101
|
open,
|
|
99
102
|
placement: 'bottom-start',
|
|
100
103
|
whileElementsMounted: autoUpdate,
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
Object.assign(floatingStyle.current, {
|
|
132
|
-
minWidth: width + 8,
|
|
133
|
-
})
|
|
134
|
-
if (refs.floating.current) {
|
|
135
|
-
Object.assign(refs.floating.current.style, floatingStyle.current)
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
}),
|
|
139
|
-
inner({
|
|
140
|
-
listRef: listItemsRef,
|
|
141
|
-
overflowRef,
|
|
142
|
-
index: selectedIndex,
|
|
143
|
-
offset: innerOffset,
|
|
144
|
-
onFallbackChange: setFallback,
|
|
145
|
-
padding: 10,
|
|
146
|
-
minItemsVisible: touch ? 10 : 4,
|
|
147
|
-
referenceOverflowThreshold: 20,
|
|
148
|
-
}),
|
|
149
|
-
offset({ crossAxis: -5 }),
|
|
150
|
-
],
|
|
104
|
+
// The removed alternate stack was the logic from floating-ui,
|
|
105
|
+
// but it causes issues (open, drag select, close, then re-open its not positioned "over")
|
|
106
|
+
// https://github.com/floating-ui/floating-ui/blob/master/packages/react/test/visual/components/MacSelect.tsx
|
|
107
|
+
middleware: [
|
|
108
|
+
size({
|
|
109
|
+
apply({
|
|
110
|
+
rects: {
|
|
111
|
+
reference: { width },
|
|
112
|
+
},
|
|
113
|
+
}) {
|
|
114
|
+
Object.assign(floatingStyle.current, {
|
|
115
|
+
minWidth: width + 8,
|
|
116
|
+
})
|
|
117
|
+
if (refs.floating.current) {
|
|
118
|
+
Object.assign(refs.floating.current.style, floatingStyle.current)
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
inner({
|
|
123
|
+
listRef: listItemsRef,
|
|
124
|
+
overflowRef,
|
|
125
|
+
index: selectedIndex,
|
|
126
|
+
offset: innerOffset,
|
|
127
|
+
onFallbackChange: setFallback,
|
|
128
|
+
padding: 10,
|
|
129
|
+
minItemsVisible: touch ? 10 : 4,
|
|
130
|
+
referenceOverflowThreshold: 20,
|
|
131
|
+
}),
|
|
132
|
+
offset({ crossAxis: -5 }),
|
|
133
|
+
],
|
|
151
134
|
} as any)
|
|
152
135
|
|
|
153
136
|
const floatingRef = refs.floating
|
|
@@ -173,8 +156,13 @@ export const SelectInlineImpl = (props: SelectImplProps) => {
|
|
|
173
156
|
}, [update, open])
|
|
174
157
|
|
|
175
158
|
const onMatch = useEvent((index: number) => {
|
|
176
|
-
|
|
177
|
-
|
|
159
|
+
if (!open) return
|
|
160
|
+
setActiveIndex(index, {
|
|
161
|
+
reason: 'keyboard',
|
|
162
|
+
event: latestKeyboardEventRef.current,
|
|
163
|
+
trigger: undefined,
|
|
164
|
+
index,
|
|
165
|
+
} as SelectActiveChangeDetails)
|
|
178
166
|
})
|
|
179
167
|
|
|
180
168
|
// construct interaction context for our custom hooks
|
|
@@ -182,7 +170,16 @@ export const SelectInlineImpl = (props: SelectImplProps) => {
|
|
|
182
170
|
dataRef.current.placement = computedPlacement
|
|
183
171
|
const interactionContext: FloatingInteractionContext = {
|
|
184
172
|
open,
|
|
185
|
-
onOpenChange: (
|
|
173
|
+
onOpenChange: (nextOpen, event, reason) => {
|
|
174
|
+
requestOpenChange(
|
|
175
|
+
nextOpen,
|
|
176
|
+
createChangeEventDetails(
|
|
177
|
+
reason === 'list-navigation' ? 'keyboard' : 'trigger-press',
|
|
178
|
+
event,
|
|
179
|
+
refs.reference.current
|
|
180
|
+
) as SelectOpenChangeDetails
|
|
181
|
+
)
|
|
182
|
+
},
|
|
186
183
|
refs: {
|
|
187
184
|
reference: refs.reference as any,
|
|
188
185
|
floating: refs.floating,
|
|
@@ -212,9 +209,15 @@ export const SelectInlineImpl = (props: SelectImplProps) => {
|
|
|
212
209
|
selectedIndex,
|
|
213
210
|
onNavigate: (index) => {
|
|
214
211
|
if (index !== null) {
|
|
215
|
-
setActiveIndex(index
|
|
212
|
+
setActiveIndex(index, {
|
|
213
|
+
reason: 'list-navigation',
|
|
214
|
+
event: latestKeyboardEventRef.current,
|
|
215
|
+
trigger: undefined,
|
|
216
|
+
index,
|
|
217
|
+
} as SelectActiveChangeDetails)
|
|
216
218
|
}
|
|
217
219
|
},
|
|
220
|
+
disabledIndices: registry.getDisabledIndices(),
|
|
218
221
|
scrollItemIntoView: false,
|
|
219
222
|
}),
|
|
220
223
|
useTypeahead(interactionContext, {
|
|
@@ -237,20 +240,27 @@ export const SelectInlineImpl = (props: SelectImplProps) => {
|
|
|
237
240
|
const interactionsContext = React.useMemo(() => {
|
|
238
241
|
return {
|
|
239
242
|
...interactions,
|
|
240
|
-
getReferenceProps() {
|
|
243
|
+
getReferenceProps(props: Record<string, any> = {}) {
|
|
241
244
|
return interactions.getReferenceProps({
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
+
...props,
|
|
246
|
+
onKeyDown: composeEventHandlers(props.onKeyDown, (event: any) => {
|
|
247
|
+
latestKeyboardEventRef.current = event.nativeEvent || event
|
|
245
248
|
if (
|
|
246
249
|
event.key === 'Enter' ||
|
|
247
250
|
event.code === 'Space' ||
|
|
248
251
|
(event.key === ' ' && !state.current.isTyping)
|
|
249
252
|
) {
|
|
250
253
|
event.preventDefault()
|
|
251
|
-
|
|
254
|
+
requestOpenChange(
|
|
255
|
+
true,
|
|
256
|
+
createChangeEventDetails(
|
|
257
|
+
'keyboard',
|
|
258
|
+
event.nativeEvent || event,
|
|
259
|
+
refs.reference.current
|
|
260
|
+
) as SelectOpenChangeDetails
|
|
261
|
+
)
|
|
252
262
|
}
|
|
253
|
-
},
|
|
263
|
+
}),
|
|
254
264
|
})
|
|
255
265
|
},
|
|
256
266
|
getFloatingProps(props) {
|
|
@@ -278,7 +288,8 @@ export const SelectInlineImpl = (props: SelectImplProps) => {
|
|
|
278
288
|
state.current.isMouseOutside = false
|
|
279
289
|
setControlledScrolling(false)
|
|
280
290
|
},
|
|
281
|
-
onKeyDown() {
|
|
291
|
+
onKeyDown(event) {
|
|
292
|
+
latestKeyboardEventRef.current = event.nativeEvent || event
|
|
282
293
|
setControlledScrolling(true)
|
|
283
294
|
},
|
|
284
295
|
onContextMenu(e) {
|
|
@@ -322,30 +333,6 @@ export const SelectInlineImpl = (props: SelectImplProps) => {
|
|
|
322
333
|
}
|
|
323
334
|
}, [open])
|
|
324
335
|
|
|
325
|
-
// dismiss on outside pointer down (arrows are outside the floating DOM tree)
|
|
326
|
-
useIsomorphicLayoutEffect(() => {
|
|
327
|
-
function onPointerDown(e: PointerEvent) {
|
|
328
|
-
const target = e.target as Node
|
|
329
|
-
if (
|
|
330
|
-
!(
|
|
331
|
-
refs.floating.current?.contains(target) ||
|
|
332
|
-
upArrowRef.current?.contains(target) ||
|
|
333
|
-
downArrowRef.current?.contains(target)
|
|
334
|
-
)
|
|
335
|
-
) {
|
|
336
|
-
setOpen(false)
|
|
337
|
-
setControlledScrolling(false)
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
if (open) {
|
|
342
|
-
document.addEventListener('pointerdown', onPointerDown)
|
|
343
|
-
return () => {
|
|
344
|
-
document.removeEventListener('pointerdown', onPointerDown)
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}, [open, refs, setOpen])
|
|
348
|
-
|
|
349
336
|
// scroll activeIndex into view during keyboard nav
|
|
350
337
|
React.useEffect(() => {
|
|
351
338
|
if (!open) return
|