@ankhorage/surface 4.4.1 → 5.0.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/CHANGELOG.md +12 -0
- package/README.md +2 -2
- package/dist/features/bottom-sheet/BottomSheetProvider.js +8 -6
- package/dist/features/bottom-sheet/BottomSheetProvider.js.map +1 -1
- package/dist/features/bottom-sheet/public.d.ts +2 -1
- package/dist/features/bottom-sheet/public.d.ts.map +1 -1
- package/dist/features/bottom-sheet/public.js +1 -0
- package/dist/features/bottom-sheet/public.js.map +1 -1
- package/dist/{components/modal → features/modal/adapters/inbound}/Modal.d.ts +2 -1
- package/dist/features/modal/adapters/inbound/Modal.d.ts.map +1 -0
- package/dist/features/modal/adapters/inbound/Modal.js +51 -0
- package/dist/features/modal/adapters/inbound/Modal.js.map +1 -0
- package/dist/features/modal/public.d.ts +3 -0
- package/dist/features/modal/public.d.ts.map +1 -0
- package/dist/features/modal/public.js +2 -0
- package/dist/features/modal/public.js.map +1 -0
- package/dist/features/popover-menu/adapters/inbound/PopoverMenu.d.ts +5 -0
- package/dist/features/popover-menu/adapters/inbound/PopoverMenu.d.ts.map +1 -0
- package/dist/features/popover-menu/adapters/inbound/PopoverMenu.js +85 -0
- package/dist/features/popover-menu/adapters/inbound/PopoverMenu.js.map +1 -0
- package/dist/features/popover-menu/composition/usePopoverMenuController.d.ts +19 -0
- package/dist/features/popover-menu/composition/usePopoverMenuController.d.ts.map +1 -0
- package/dist/features/popover-menu/composition/usePopoverMenuController.js +35 -0
- package/dist/features/popover-menu/composition/usePopoverMenuController.js.map +1 -0
- package/dist/features/popover-menu/public.d.ts +3 -0
- package/dist/features/popover-menu/public.d.ts.map +1 -0
- package/dist/features/popover-menu/public.js +2 -0
- package/dist/features/popover-menu/public.js.map +1 -0
- package/dist/features/popover-menu/utils/resolveNextMenuIndex.d.ts +5 -0
- package/dist/features/popover-menu/utils/resolveNextMenuIndex.d.ts.map +1 -0
- package/dist/features/popover-menu/utils/resolveNextMenuIndex.js +18 -0
- package/dist/features/popover-menu/utils/resolveNextMenuIndex.js.map +1 -0
- package/dist/features/tabs/adapters/inbound/Tab.d.ts +5 -0
- package/dist/features/tabs/adapters/inbound/Tab.d.ts.map +1 -0
- package/dist/features/tabs/adapters/inbound/Tab.js +33 -0
- package/dist/features/tabs/adapters/inbound/Tab.js.map +1 -0
- package/dist/features/tabs/adapters/inbound/TabList.d.ts +5 -0
- package/dist/features/tabs/adapters/inbound/TabList.d.ts.map +1 -0
- package/dist/features/tabs/adapters/inbound/TabList.js +42 -0
- package/dist/features/tabs/adapters/inbound/TabList.js.map +1 -0
- package/dist/features/tabs/adapters/inbound/TabPanel.d.ts +5 -0
- package/dist/features/tabs/adapters/inbound/TabPanel.d.ts.map +1 -0
- package/dist/features/tabs/adapters/inbound/TabPanel.js +14 -0
- package/dist/features/tabs/adapters/inbound/TabPanel.js.map +1 -0
- package/dist/features/tabs/adapters/inbound/Tabs.d.ts +5 -0
- package/dist/features/tabs/adapters/inbound/Tabs.d.ts.map +1 -0
- package/dist/features/tabs/adapters/inbound/Tabs.js +12 -0
- package/dist/features/tabs/adapters/inbound/Tabs.js.map +1 -0
- package/dist/features/tabs/composition/TabsContext.d.ts +4 -0
- package/dist/features/tabs/composition/TabsContext.d.ts.map +1 -0
- package/dist/features/tabs/composition/TabsContext.js +3 -0
- package/dist/features/tabs/composition/TabsContext.js.map +1 -0
- package/dist/features/tabs/composition/useTabRegistration.d.ts +7 -0
- package/dist/features/tabs/composition/useTabRegistration.d.ts.map +1 -0
- package/dist/features/tabs/composition/useTabRegistration.js +20 -0
- package/dist/features/tabs/composition/useTabRegistration.js.map +1 -0
- package/dist/features/tabs/composition/useTabsContext.d.ts +4 -0
- package/dist/features/tabs/composition/useTabsContext.d.ts.map +1 -0
- package/dist/{components/tabs/context.js → features/tabs/composition/useTabsContext.js} +4 -4
- package/dist/features/tabs/composition/useTabsContext.js.map +1 -0
- package/dist/features/tabs/composition/useTabsController.d.ts +4 -0
- package/dist/features/tabs/composition/useTabsController.d.ts.map +1 -0
- package/dist/features/tabs/composition/useTabsController.js +43 -0
- package/dist/features/tabs/composition/useTabsController.js.map +1 -0
- package/dist/features/tabs/public.d.ts +6 -0
- package/dist/features/tabs/public.d.ts.map +1 -0
- package/dist/features/tabs/public.js +5 -0
- package/dist/features/tabs/public.js.map +1 -0
- package/dist/features/tabs/utils/resolveNextTabValue.d.ts +4 -0
- package/dist/features/tabs/utils/resolveNextTabValue.d.ts.map +1 -0
- package/dist/{components/tabs/navigation.js → features/tabs/utils/resolveNextTabValue.js} +10 -13
- package/dist/features/tabs/utils/resolveNextTabValue.js.map +1 -0
- package/dist/features/tabs/utils/resolveTabElementId.d.ts +3 -0
- package/dist/features/tabs/utils/resolveTabElementId.d.ts.map +1 -0
- package/dist/features/tabs/utils/resolveTabElementId.js +10 -0
- package/dist/features/tabs/utils/resolveTabElementId.js.map +1 -0
- package/dist/features/tooltip/adapters/inbound/Tooltip.d.ts +5 -0
- package/dist/features/tooltip/adapters/inbound/Tooltip.d.ts.map +1 -0
- package/dist/features/tooltip/adapters/inbound/Tooltip.js +25 -0
- package/dist/features/tooltip/adapters/inbound/Tooltip.js.map +1 -0
- package/dist/features/tooltip/composition/useTooltipVisibility.d.ts +9 -0
- package/dist/features/tooltip/composition/useTooltipVisibility.d.ts.map +1 -0
- package/dist/features/tooltip/composition/useTooltipVisibility.js +25 -0
- package/dist/features/tooltip/composition/useTooltipVisibility.js.map +1 -0
- package/dist/features/tooltip/public.d.ts +3 -0
- package/dist/features/tooltip/public.d.ts.map +1 -0
- package/dist/features/tooltip/public.js +2 -0
- package/dist/features/tooltip/public.js.map +1 -0
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/types/bottomSheet.d.ts +3 -0
- package/dist/types/bottomSheet.d.ts.map +1 -1
- package/dist/types/bottomSheet.js.map +1 -1
- package/dist/{components/modal/types.d.ts → types/modal.d.ts} +2 -2
- package/dist/types/modal.d.ts.map +1 -0
- package/dist/types/modal.js +2 -0
- package/dist/types/modal.js.map +1 -0
- package/dist/types/popoverMenu.d.ts +24 -0
- package/dist/types/popoverMenu.d.ts.map +1 -0
- package/dist/types/popoverMenu.js +2 -0
- package/dist/types/popoverMenu.js.map +1 -0
- package/dist/types/tabs.d.ts +43 -0
- package/dist/types/tabs.d.ts.map +1 -0
- package/dist/types/tabs.js +2 -0
- package/dist/types/tabs.js.map +1 -0
- package/dist/{components/tooltip/types.d.ts → types/tooltip.d.ts} +2 -2
- package/dist/types/tooltip.d.ts.map +1 -0
- package/dist/types/tooltip.js +2 -0
- package/dist/types/tooltip.js.map +1 -0
- package/package.json +1 -1
- package/src/features/bottom-sheet/BottomSheetProvider.tsx +13 -8
- package/src/features/bottom-sheet/public.test.ts +23 -0
- package/src/features/bottom-sheet/public.ts +12 -1
- package/src/features/modal/adapters/inbound/Modal.tsx +74 -0
- package/src/features/modal/public.ts +2 -0
- package/src/features/popover-menu/adapters/inbound/PopoverMenu.tsx +201 -0
- package/src/features/popover-menu/composition/usePopoverMenuController.ts +55 -0
- package/src/features/popover-menu/public.test.ts +13 -0
- package/src/features/popover-menu/public.ts +6 -0
- package/src/{components/menu/navigation.test.ts → features/popover-menu/utils/resolveNextMenuIndex.test.ts} +4 -4
- package/src/features/popover-menu/utils/resolveNextMenuIndex.ts +21 -0
- package/src/features/tabs/adapters/inbound/Tab.tsx +67 -0
- package/src/features/tabs/adapters/inbound/TabList.tsx +50 -0
- package/src/{components/tabs → features/tabs/adapters/inbound}/TabPanel.tsx +6 -10
- package/src/features/tabs/adapters/inbound/Tabs.tsx +17 -0
- package/src/features/tabs/composition/TabsContext.tsx +5 -0
- package/src/features/tabs/composition/useTabRegistration.ts +27 -0
- package/src/features/tabs/composition/useTabsContext.ts +13 -0
- package/src/features/tabs/composition/useTabsController.ts +55 -0
- package/src/features/tabs/public.ts +5 -0
- package/src/{components/tabs/navigation.test.ts → features/tabs/utils/resolveNextTabValue.test.ts} +2 -2
- package/src/features/tabs/utils/resolveNextTabValue.ts +24 -0
- package/src/features/tabs/utils/resolveTabElementId.test.ts +19 -0
- package/src/features/tabs/utils/resolveTabElementId.ts +14 -0
- package/src/features/tooltip/adapters/inbound/Tooltip.tsx +56 -0
- package/src/features/tooltip/composition/useTooltipVisibility.ts +29 -0
- package/src/features/tooltip/public.test.ts +11 -0
- package/src/features/tooltip/public.ts +2 -0
- package/src/index.test.ts +12 -5
- package/src/index.ts +12 -8
- package/src/types/bottomSheet.ts +4 -0
- package/src/{components/modal/types.ts → types/modal.ts} +1 -1
- package/src/types/popoverMenu.ts +27 -0
- package/src/types/tabs.ts +51 -0
- package/src/{components/tooltip/types.ts → types/tooltip.ts} +1 -1
- package/dist/components/menu/Menu.d.ts +0 -4
- package/dist/components/menu/Menu.d.ts.map +0 -1
- package/dist/components/menu/Menu.js +0 -152
- package/dist/components/menu/Menu.js.map +0 -1
- package/dist/components/menu/index.d.ts +0 -3
- package/dist/components/menu/index.d.ts.map +0 -1
- package/dist/components/menu/index.js +0 -2
- package/dist/components/menu/index.js.map +0 -1
- package/dist/components/menu/navigation.d.ts +0 -4
- package/dist/components/menu/navigation.d.ts.map +0 -1
- package/dist/components/menu/navigation.js +0 -25
- package/dist/components/menu/navigation.js.map +0 -1
- package/dist/components/menu/types.d.ts +0 -23
- package/dist/components/menu/types.d.ts.map +0 -1
- package/dist/components/menu/types.js +0 -2
- package/dist/components/menu/types.js.map +0 -1
- package/dist/components/modal/Modal.d.ts.map +0 -1
- package/dist/components/modal/Modal.js +0 -59
- package/dist/components/modal/Modal.js.map +0 -1
- package/dist/components/modal/index.d.ts +0 -3
- package/dist/components/modal/index.d.ts.map +0 -1
- package/dist/components/modal/index.js +0 -2
- package/dist/components/modal/index.js.map +0 -1
- package/dist/components/modal/types.d.ts.map +0 -1
- package/dist/components/modal/types.js +0 -2
- package/dist/components/modal/types.js.map +0 -1
- package/dist/components/tabs/Tab.d.ts +0 -4
- package/dist/components/tabs/Tab.d.ts.map +0 -1
- package/dist/components/tabs/Tab.js +0 -48
- package/dist/components/tabs/Tab.js.map +0 -1
- package/dist/components/tabs/TabList.d.ts +0 -4
- package/dist/components/tabs/TabList.d.ts.map +0 -1
- package/dist/components/tabs/TabList.js +0 -37
- package/dist/components/tabs/TabList.js.map +0 -1
- package/dist/components/tabs/TabPanel.d.ts +0 -4
- package/dist/components/tabs/TabPanel.d.ts.map +0 -1
- package/dist/components/tabs/TabPanel.js +0 -16
- package/dist/components/tabs/TabPanel.js.map +0 -1
- package/dist/components/tabs/Tabs.d.ts +0 -4
- package/dist/components/tabs/Tabs.d.ts.map +0 -1
- package/dist/components/tabs/Tabs.js +0 -54
- package/dist/components/tabs/Tabs.js.map +0 -1
- package/dist/components/tabs/a11y.d.ts +0 -3
- package/dist/components/tabs/a11y.d.ts.map +0 -1
- package/dist/components/tabs/a11y.js +0 -13
- package/dist/components/tabs/a11y.js.map +0 -1
- package/dist/components/tabs/context.d.ts +0 -20
- package/dist/components/tabs/context.d.ts.map +0 -1
- package/dist/components/tabs/context.js.map +0 -1
- package/dist/components/tabs/index.d.ts +0 -6
- package/dist/components/tabs/index.d.ts.map +0 -1
- package/dist/components/tabs/index.js +0 -5
- package/dist/components/tabs/index.js.map +0 -1
- package/dist/components/tabs/navigation.d.ts +0 -3
- package/dist/components/tabs/navigation.d.ts.map +0 -1
- package/dist/components/tabs/navigation.js.map +0 -1
- package/dist/components/tabs/types.d.ts +0 -26
- package/dist/components/tabs/types.d.ts.map +0 -1
- package/dist/components/tabs/types.js +0 -2
- package/dist/components/tabs/types.js.map +0 -1
- package/dist/components/tooltip/Tooltip.d.ts +0 -4
- package/dist/components/tooltip/Tooltip.d.ts.map +0 -1
- package/dist/components/tooltip/Tooltip.js +0 -75
- package/dist/components/tooltip/Tooltip.js.map +0 -1
- package/dist/components/tooltip/index.d.ts +0 -3
- package/dist/components/tooltip/index.d.ts.map +0 -1
- package/dist/components/tooltip/index.js +0 -2
- package/dist/components/tooltip/index.js.map +0 -1
- package/dist/components/tooltip/types.d.ts.map +0 -1
- package/dist/components/tooltip/types.js +0 -2
- package/dist/components/tooltip/types.js.map +0 -1
- package/src/components/menu/Menu.tsx +0 -228
- package/src/components/menu/index.ts +0 -2
- package/src/components/menu/navigation.ts +0 -34
- package/src/components/menu/types.ts +0 -26
- package/src/components/modal/Modal.tsx +0 -96
- package/src/components/modal/index.ts +0 -2
- package/src/components/tabs/Tab.tsx +0 -89
- package/src/components/tabs/TabList.tsx +0 -51
- package/src/components/tabs/Tabs.tsx +0 -67
- package/src/components/tabs/a11y.test.ts +0 -15
- package/src/components/tabs/a11y.ts +0 -15
- package/src/components/tabs/context.tsx +0 -31
- package/src/components/tabs/index.ts +0 -5
- package/src/components/tabs/navigation.ts +0 -32
- package/src/components/tabs/types.ts +0 -30
- package/src/components/tooltip/Tooltip.tsx +0 -117
- package/src/components/tooltip/index.ts +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @ankhorage/surface
|
|
2
2
|
|
|
3
|
+
## 5.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 14c083f: Move Modal and the accessible Tabs system to canonical feature ownership without changing their public root API.
|
|
8
|
+
|
|
9
|
+
## 5.0.0
|
|
10
|
+
|
|
11
|
+
### Major Changes
|
|
12
|
+
|
|
13
|
+
- 33ee8c2: Replace the ambiguous `Menu` API with feature-owned `PopoverMenu`, migrate Tooltip onto the shared Popover capability, and expose Gorhom-integrated bottom-sheet scrollables with direct scrollable content hosting.
|
|
14
|
+
|
|
3
15
|
## 4.4.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# @ankhorage/surface
|
|
5
5
|
|
|
6
|
-
         
|
|
7
7
|
|
|
8
8
|
Cross-platform UI foundation for React Native and React Native Web. Provides theming, layout primitives, and core building blocks for modern apps.
|
|
9
9
|
|
|
@@ -27,9 +27,9 @@ Cross-platform UI foundation for React Native and React Native Web. Provides the
|
|
|
27
27
|
- [IconButton sequence](././paradox/diagrams/sequences/icon-button.mmd)
|
|
28
28
|
- [isDeepEqual sequence](././paradox/diagrams/sequences/is-deep-equal.mmd)
|
|
29
29
|
- [ListItem sequence](././paradox/diagrams/sequences/list-item.mmd)
|
|
30
|
-
- [Menu sequence](././paradox/diagrams/sequences/menu.mmd)
|
|
31
30
|
- [Modal sequence](././paradox/diagrams/sequences/modal.mmd)
|
|
32
31
|
- [Popover sequence](././paradox/diagrams/sequences/popover.mmd)
|
|
32
|
+
- [PopoverMenu sequence](././paradox/diagrams/sequences/popover-menu.mmd)
|
|
33
33
|
- [Radio sequence](././paradox/diagrams/sequences/radio.mmd)
|
|
34
34
|
- [resolveResponsive sequence](././paradox/diagrams/sequences/resolve-responsive.mmd)
|
|
35
35
|
- [ResponsiveProvider sequence](././paradox/diagrams/sequences/responsive-provider.mmd)
|
|
@@ -39,21 +39,23 @@ export function BottomSheetProvider({ children }) {
|
|
|
39
39
|
/*** Renders and presents the single Gorhom modal owned by the provider. */
|
|
40
40
|
function BottomSheetHost({ activeRequest, handleDismiss, modalRef, presentedRef, }) {
|
|
41
41
|
React.useEffect(() => {
|
|
42
|
-
if (!activeRequest || presentedRef.current)
|
|
42
|
+
if (!activeRequest || presentedRef.current)
|
|
43
43
|
return;
|
|
44
|
-
}
|
|
45
44
|
presentedRef.current = true;
|
|
46
45
|
modalRef.current?.present();
|
|
47
46
|
}, [activeRequest, modalRef, presentedRef]);
|
|
48
47
|
const renderBackdrop = useBottomSheetBackdrop(activeRequest?.dismissOnBackdropPress);
|
|
49
48
|
const snapPoints = React.useMemo(() => (activeRequest?.snapPoints ? [...activeRequest.snapPoints] : undefined), [activeRequest?.snapPoints]);
|
|
50
|
-
if (!activeRequest)
|
|
49
|
+
if (!activeRequest)
|
|
51
50
|
return null;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
<BottomSheetView>{activeRequest.content}</BottomSheetView>
|
|
51
|
+
return (<BottomSheetModal ref={modalRef} backdropComponent={renderBackdrop} enableDynamicSizing={activeRequest.enableDynamicSizing ?? true} enablePanDownToClose={activeRequest.enablePanDownToClose ?? true} index={activeRequest.initialIndex ?? 0} keyboardBehavior={activeRequest.keyboardBehavior ?? 'interactive'} keyboardBlurBehavior={activeRequest.keyboardBlurBehavior ?? 'restore'} maxDynamicContentSize={activeRequest.maxDynamicContentSize} onChange={activeRequest.onIndexChange} onDismiss={handleDismiss} snapPoints={snapPoints}>
|
|
52
|
+
{renderBottomSheetContent(activeRequest)}
|
|
55
53
|
</BottomSheetModal>);
|
|
56
54
|
}
|
|
55
|
+
/*** Renders default content in BottomSheetView and direct content without an extra wrapper. */
|
|
56
|
+
function renderBottomSheetContent(activeRequest) {
|
|
57
|
+
return activeRequest.contentMode === 'direct' ? (activeRequest.content) : (<BottomSheetView>{activeRequest.content}</BottomSheetView>);
|
|
58
|
+
}
|
|
57
59
|
/*** Creates the backdrop renderer for the active bottom-sheet request. */
|
|
58
60
|
function useBottomSheetBackdrop(dismissOnBackdropPress) {
|
|
59
61
|
return React.useCallback((props) => (<BottomSheetBackdrop {...props} appearsOnIndex={0} disappearsOnIndex={-1} pressBehavior={dismissOnBackdropPress === false ? 'none' : 'close'}/>), [dismissOnBackdropPress]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomSheetProvider.js","sourceRoot":"","sources":["../../../src/features/bottom-sheet/BottomSheetProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAEnB,gBAAgB,EAChB,wBAAwB,EACxB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,4FAA4F;AAC5F,MAAM,UAAU,mBAAmB,CAAC,EAAE,QAAQ,EAAiC;IAC7E,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAmB,IAAI,CAAC,CAAC;IACtD,MAAM,gBAAgB,GAAG,KAAK,CAAC,MAAM,CAAmC,IAAI,CAAC,CAAC;IAC9E,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAmC,IAAI,CAAC,CAAC;IAEjG,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,OAAkC,EAAE,EAAE;QACvE,gBAAgB,CAAC,OAAO,GAAG,OAAO,CAAC;QACnC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QACrC,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;YACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;YAC5B,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC;QACzC,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC;QAChC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC;IACzB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,aAAa,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAC3C,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC;QACzC,YAAY,CAAC,OAAO,GAAG,KAAK,CAAC;QAC7B,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC;QAChC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC;IACzB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAC9B,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAC5B,CAAC,OAAO,EAAE,OAAO,CAAC,CACnB,CAAC;IAEF,OAAO,CACL,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CACpC;MAAA,CAAC,wBAAwB,CACvB;QAAA,CAAC,QAAQ,CACT;QAAA,CAAC,eAAe,CACd,aAAa,CAAC,CAAC,aAAa,CAAC,CAC7B,aAAa,CAAC,CAAC,aAAa,CAAC,CAC7B,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,YAAY,CAAC,CAAC,YAAY,CAAC,EAE/B;MAAA,EAAE,wBAAwB,CAC5B;IAAA,EAAE,kBAAkB,CAAC,CACtB,CAAC;AACJ,CAAC;AASD,2EAA2E;AAC3E,SAAS,eAAe,CAAC,EACvB,aAAa,EACb,aAAa,EACb,QAAQ,EACR,YAAY,GACS;IACrB,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,aAAa,IAAI,YAAY,CAAC,OAAO
|
|
1
|
+
{"version":3,"file":"BottomSheetProvider.js","sourceRoot":"","sources":["../../../src/features/bottom-sheet/BottomSheetProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n BottomSheetBackdrop,\n type BottomSheetBackdropProps,\n BottomSheetModal,\n BottomSheetModalProvider,\n BottomSheetView,\n} from '@gorhom/bottom-sheet';\nimport React from 'react';\n\nimport type { BottomSheetController, BottomSheetPresentOptions } from '../../types/bottomSheet';\nimport { BottomSheetContext } from './BottomSheetContext';\n\n/*** Installs the shared bottom-sheet modal host and controller for descendant consumers. */\nexport function BottomSheetProvider({ children }: { children: React.ReactNode }) {\n const modalRef = React.useRef<BottomSheetModal>(null);\n const activeRequestRef = React.useRef<BottomSheetPresentOptions | null>(null);\n const presentedRef = React.useRef(false);\n const [activeRequest, setActiveRequest] = React.useState<BottomSheetPresentOptions | null>(null);\n\n const present = React.useCallback((options: BottomSheetPresentOptions) => {\n activeRequestRef.current = options;\n setActiveRequest(options);\n }, []);\n\n const dismiss = React.useCallback(() => {\n if (presentedRef.current) {\n modalRef.current?.dismiss();\n return;\n }\n\n const request = activeRequestRef.current;\n activeRequestRef.current = null;\n setActiveRequest(null);\n request?.onDismiss?.();\n }, []);\n\n const handleDismiss = React.useCallback(() => {\n const request = activeRequestRef.current;\n presentedRef.current = false;\n activeRequestRef.current = null;\n setActiveRequest(null);\n request?.onDismiss?.();\n }, []);\n\n const controller = React.useMemo<BottomSheetController>(\n () => ({ dismiss, present }),\n [dismiss, present],\n );\n\n return (\n <BottomSheetContext value={controller}>\n <BottomSheetModalProvider>\n {children}\n <BottomSheetHost\n activeRequest={activeRequest}\n handleDismiss={handleDismiss}\n modalRef={modalRef}\n presentedRef={presentedRef}\n />\n </BottomSheetModalProvider>\n </BottomSheetContext>\n );\n}\n\ninterface BottomSheetHostProps {\n readonly activeRequest: BottomSheetPresentOptions | null;\n readonly handleDismiss: () => void;\n readonly modalRef: React.RefObject<BottomSheetModal | null>;\n readonly presentedRef: React.RefObject<boolean>;\n}\n\n/*** Renders and presents the single Gorhom modal owned by the provider. */\nfunction BottomSheetHost({\n activeRequest,\n handleDismiss,\n modalRef,\n presentedRef,\n}: BottomSheetHostProps) {\n React.useEffect(() => {\n if (!activeRequest || presentedRef.current) return;\n presentedRef.current = true;\n modalRef.current?.present();\n }, [activeRequest, modalRef, presentedRef]);\n\n const renderBackdrop = useBottomSheetBackdrop(activeRequest?.dismissOnBackdropPress);\n const snapPoints = React.useMemo(\n () => (activeRequest?.snapPoints ? [...activeRequest.snapPoints] : undefined),\n [activeRequest?.snapPoints],\n );\n\n if (!activeRequest) return null;\n\n return (\n <BottomSheetModal\n ref={modalRef}\n backdropComponent={renderBackdrop}\n enableDynamicSizing={activeRequest.enableDynamicSizing ?? true}\n enablePanDownToClose={activeRequest.enablePanDownToClose ?? true}\n index={activeRequest.initialIndex ?? 0}\n keyboardBehavior={activeRequest.keyboardBehavior ?? 'interactive'}\n keyboardBlurBehavior={activeRequest.keyboardBlurBehavior ?? 'restore'}\n maxDynamicContentSize={activeRequest.maxDynamicContentSize}\n onChange={activeRequest.onIndexChange}\n onDismiss={handleDismiss}\n snapPoints={snapPoints}\n >\n {renderBottomSheetContent(activeRequest)}\n </BottomSheetModal>\n );\n}\n\n/*** Renders default content in BottomSheetView and direct content without an extra wrapper. */\nfunction renderBottomSheetContent(activeRequest: BottomSheetPresentOptions): React.ReactNode {\n return activeRequest.contentMode === 'direct' ? (\n activeRequest.content\n ) : (\n <BottomSheetView>{activeRequest.content}</BottomSheetView>\n );\n}\n\n/*** Creates the backdrop renderer for the active bottom-sheet request. */\nfunction useBottomSheetBackdrop(dismissOnBackdropPress: boolean | undefined) {\n return React.useCallback(\n (props: BottomSheetBackdropProps) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={0}\n disappearsOnIndex={-1}\n pressBehavior={dismissOnBackdropPress === false ? 'none' : 'close'}\n />\n ),\n [dismissOnBackdropPress],\n );\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export type { BottomSheetController, BottomSheetPresentOptions } from '../../types/bottomSheet';
|
|
1
|
+
export type { BottomSheetContentMode, BottomSheetController, BottomSheetPresentOptions, } from '../../types/bottomSheet';
|
|
2
2
|
export { BottomSheetProvider } from './BottomSheetProvider';
|
|
3
3
|
export { useBottomSheet } from './useBottomSheet';
|
|
4
|
+
export { BottomSheetFlatList, BottomSheetScrollView, BottomSheetSectionList, BottomSheetView, BottomSheetVirtualizedList, } from '@gorhom/bottom-sheet';
|
|
4
5
|
//# sourceMappingURL=public.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/bottom-sheet/public.ts"],"names":[],"mappings":"AAAA,YAAY,
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/bottom-sheet/public.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,sBAAsB,EACtB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { BottomSheetProvider } from './BottomSheetProvider';
|
|
2
2
|
export { useBottomSheet } from './useBottomSheet';
|
|
3
|
+
export { BottomSheetFlatList, BottomSheetScrollView, BottomSheetSectionList, BottomSheetView, BottomSheetVirtualizedList, } from '@gorhom/bottom-sheet';
|
|
3
4
|
//# sourceMappingURL=public.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/bottom-sheet/public.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/bottom-sheet/public.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC","sourcesContent":["export type {\n BottomSheetContentMode,\n BottomSheetController,\n BottomSheetPresentOptions,\n} from '../../types/bottomSheet';\nexport { BottomSheetProvider } from './BottomSheetProvider';\nexport { useBottomSheet } from './useBottomSheet';\nexport {\n BottomSheetFlatList,\n BottomSheetScrollView,\n BottomSheetSectionList,\n BottomSheetView,\n BottomSheetVirtualizedList,\n} from '@gorhom/bottom-sheet';\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { ModalProps } from '
|
|
2
|
+
import type { ModalProps } from '../../../../types/modal';
|
|
3
|
+
/*** Renders the generic Surface modal overlay and focus boundary. */
|
|
3
4
|
export declare function Modal({ visible, onDismiss, children, closeOnBackdrop, interactionPolicy, testID, }: ModalProps): React.JSX.Element | null;
|
|
4
5
|
//# sourceMappingURL=Modal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../../../../src/features/modal/adapters/inbound/Modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAK1D,qEAAqE;AACrE,wBAAgB,KAAK,CAAC,EACpB,OAAO,EACP,SAAS,EACT,QAAQ,EACR,eAAsB,EACtB,iBAA6B,EAC7B,MAAM,GACP,EAAE,UAAU,4BAmCZ"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Pressable, StyleSheet, View } from 'react-native';
|
|
3
|
+
import { FocusScope } from '../../../../internal/focus/FocusScope';
|
|
4
|
+
import { Portal } from '../../../../internal/overlay/Portal';
|
|
5
|
+
import { resolvePointerEvents } from '../../../../internal/resolvePointerEvents';
|
|
6
|
+
import { resolveOverlayAnimation } from '../../../../internal/resolvers';
|
|
7
|
+
import { Center } from '../../../../layout';
|
|
8
|
+
import { useTheme } from '../../../../theme/ThemeContext';
|
|
9
|
+
import { Surface } from '../../../surface/public';
|
|
10
|
+
const boxNonePointerEvents = resolvePointerEvents('box-none');
|
|
11
|
+
/*** Renders the generic Surface modal overlay and focus boundary. */
|
|
12
|
+
export function Modal({ visible, onDismiss, children, closeOnBackdrop = true, interactionPolicy = 'enabled', testID, }) {
|
|
13
|
+
const { theme } = useTheme();
|
|
14
|
+
const animation = resolveOverlayAnimation('modal');
|
|
15
|
+
const passive = interactionPolicy === 'passive';
|
|
16
|
+
const backdropPress = passive || !closeOnBackdrop ? undefined : onDismiss;
|
|
17
|
+
if (!visible)
|
|
18
|
+
return null;
|
|
19
|
+
return (<Portal layer="modal" visible={visible}>
|
|
20
|
+
<View {...boxNonePointerEvents.props} style={[boxNonePointerEvents.style, styles.fill]}>
|
|
21
|
+
<Pressable onPress={backdropPress} style={[
|
|
22
|
+
styles.fill,
|
|
23
|
+
resolveBackdropStyle(theme.semantics.neutral.text, animation.backdropOpacity),
|
|
24
|
+
]} testID={testID ? `${testID}-backdrop` : undefined}/>
|
|
25
|
+
<FocusScope active={visible} onEscape={passive ? undefined : onDismiss} testID={testID ? `${testID}-focus` : undefined}>
|
|
26
|
+
<Center p="l" style={styles.center}>
|
|
27
|
+
<View accessible accessibilityViewIsModal style={styles.content}>
|
|
28
|
+
<Surface p="l" style={styles.surface} testID={testID} variant="raised">
|
|
29
|
+
{children}
|
|
30
|
+
</Surface>
|
|
31
|
+
</View>
|
|
32
|
+
</Center>
|
|
33
|
+
</FocusScope>
|
|
34
|
+
</View>
|
|
35
|
+
</Portal>);
|
|
36
|
+
}
|
|
37
|
+
/*** Resolves the runtime backdrop color and opacity without inline JSX styles. */
|
|
38
|
+
function resolveBackdropStyle(backgroundColor, opacity) {
|
|
39
|
+
return { backgroundColor, opacity };
|
|
40
|
+
}
|
|
41
|
+
const styles = StyleSheet.create({
|
|
42
|
+
center: { flex: 1 },
|
|
43
|
+
content: { maxWidth: 560, width: '100%' },
|
|
44
|
+
fill: { bottom: 0, left: 0, position: 'absolute', right: 0, top: 0 },
|
|
45
|
+
surface: {
|
|
46
|
+
shadowOffset: { height: 8, width: 0 },
|
|
47
|
+
shadowOpacity: 0.14,
|
|
48
|
+
shadowRadius: 18,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
//# sourceMappingURL=Modal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../../../../src/features/modal/adapters/inbound/Modal.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Pressable, StyleSheet, View, type ViewStyle } from 'react-native';\n\nimport { FocusScope } from '../../../../internal/focus/FocusScope';\nimport { Portal } from '../../../../internal/overlay/Portal';\nimport { resolvePointerEvents } from '../../../../internal/resolvePointerEvents';\nimport { resolveOverlayAnimation } from '../../../../internal/resolvers';\nimport { Center } from '../../../../layout';\nimport { useTheme } from '../../../../theme/ThemeContext';\nimport type { ModalProps } from '../../../../types/modal';\nimport { Surface } from '../../../surface/public';\n\nconst boxNonePointerEvents = resolvePointerEvents('box-none');\n\n/*** Renders the generic Surface modal overlay and focus boundary. */\nexport function Modal({\n visible,\n onDismiss,\n children,\n closeOnBackdrop = true,\n interactionPolicy = 'enabled',\n testID,\n}: ModalProps) {\n const { theme } = useTheme();\n const animation = resolveOverlayAnimation('modal');\n const passive = interactionPolicy === 'passive';\n const backdropPress = passive || !closeOnBackdrop ? undefined : onDismiss;\n\n if (!visible) return null;\n\n return (\n <Portal layer=\"modal\" visible={visible}>\n <View {...boxNonePointerEvents.props} style={[boxNonePointerEvents.style, styles.fill]}>\n <Pressable\n onPress={backdropPress}\n style={[\n styles.fill,\n resolveBackdropStyle(theme.semantics.neutral.text, animation.backdropOpacity),\n ]}\n testID={testID ? `${testID}-backdrop` : undefined}\n />\n <FocusScope\n active={visible}\n onEscape={passive ? undefined : onDismiss}\n testID={testID ? `${testID}-focus` : undefined}\n >\n <Center p=\"l\" style={styles.center}>\n <View accessible accessibilityViewIsModal style={styles.content}>\n <Surface p=\"l\" style={styles.surface} testID={testID} variant=\"raised\">\n {children}\n </Surface>\n </View>\n </Center>\n </FocusScope>\n </View>\n </Portal>\n );\n}\n\n/*** Resolves the runtime backdrop color and opacity without inline JSX styles. */\nfunction resolveBackdropStyle(backgroundColor: string, opacity: number): ViewStyle {\n return { backgroundColor, opacity };\n}\n\nconst styles = StyleSheet.create({\n center: { flex: 1 },\n content: { maxWidth: 560, width: '100%' },\n fill: { bottom: 0, left: 0, position: 'absolute', right: 0, top: 0 },\n surface: {\n shadowOffset: { height: 8, width: 0 },\n shadowOpacity: 0.14,\n shadowRadius: 18,\n },\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/modal/public.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/modal/public.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC","sourcesContent":["export type { ModalProps } from '../../types/modal';\nexport { Modal } from './adapters/inbound/Modal';\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { PopoverMenuProps } from '../../../../types/popoverMenu';
|
|
3
|
+
/*** Presents an anchored action menu using the shared Popover capability. */
|
|
4
|
+
export declare function PopoverMenu({ trigger, actions, dismiss, closeOnSelect, interactionPolicy, testID, }: PopoverMenuProps): React.JSX.Element;
|
|
5
|
+
//# sourceMappingURL=PopoverMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PopoverMenu.d.ts","sourceRoot":"","sources":["../../../../../src/features/popover-menu/adapters/inbound/PopoverMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,KAAK,EAAqB,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAQzF,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,OAAO,EACP,OAAO,EACP,aAAoB,EACpB,iBAA6B,EAC7B,MAAM,GACP,EAAE,gBAAgB,qBAyBlB"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Pressable } from 'react-native';
|
|
3
|
+
import { FocusScope } from '../../../../internal/focus/FocusScope';
|
|
4
|
+
import { useFocusManager } from '../../../../internal/focus/useFocusManager';
|
|
5
|
+
import { Inline } from '../../../../layout';
|
|
6
|
+
import { useTheme } from '../../../../theme/ThemeContext';
|
|
7
|
+
import { Box, Stack } from '../../../layout/public';
|
|
8
|
+
import { Popover } from '../../../popover/public';
|
|
9
|
+
import { Surface } from '../../../surface/public';
|
|
10
|
+
import { Text } from '../../../typography/public';
|
|
11
|
+
import { usePopoverMenuController } from '../../composition/usePopoverMenuController';
|
|
12
|
+
import { resolveNextMenuIndex } from '../../utils/resolveNextMenuIndex';
|
|
13
|
+
/*** Presents an anchored action menu using the shared Popover capability. */
|
|
14
|
+
export function PopoverMenu({ trigger, actions, dismiss, closeOnSelect = true, interactionPolicy = 'enabled', testID, }) {
|
|
15
|
+
const passive = interactionPolicy === 'passive';
|
|
16
|
+
const controller = usePopoverMenuController({ actions, closeOnSelect, dismiss, passive });
|
|
17
|
+
return (<Popover anchor={trigger} closeOnOutsidePress interactionPolicy={interactionPolicy} onOpenChange={controller.handleOpenChange} open={controller.open} placement="bottom-start" testID={testID}>
|
|
18
|
+
<PopoverMenuContent actions={actions} activeIndex={controller.activeIndex} activateAction={controller.activateAction} close={controller.close} passive={passive} setActiveIndex={controller.setActiveIndex} testID={testID}/>
|
|
19
|
+
</Popover>);
|
|
20
|
+
}
|
|
21
|
+
/*** Renders menu semantics and keyboard navigation inside an open Popover. */
|
|
22
|
+
function PopoverMenuContent({ actions, activeIndex, activateAction, close, passive, setActiveIndex, testID, }) {
|
|
23
|
+
usePopoverMenuKeyboard({ actions, activeIndex, activateAction, close, passive, setActiveIndex });
|
|
24
|
+
return (<FocusScope active onEscape={passive ? undefined : close}>
|
|
25
|
+
<Surface accessibilityRole="menu" p="xs" testID={testID} variant="raised">
|
|
26
|
+
{actions.map((action, index) => (<PopoverMenuItem action={action} active={index === activeIndex} activateAction={activateAction} key={action.id} passive={passive} testID={testID}/>))}
|
|
27
|
+
</Surface>
|
|
28
|
+
</FocusScope>);
|
|
29
|
+
}
|
|
30
|
+
/*** Subscribes an open PopoverMenu to standard menu keyboard controls. */
|
|
31
|
+
function usePopoverMenuKeyboard({ actions, activeIndex, activateAction, close, passive, setActiveIndex, }) {
|
|
32
|
+
const { bindKeydown } = useFocusManager();
|
|
33
|
+
React.useEffect(() => bindKeydown((event) => {
|
|
34
|
+
if (passive)
|
|
35
|
+
return;
|
|
36
|
+
const { key } = event;
|
|
37
|
+
if (key === undefined)
|
|
38
|
+
return;
|
|
39
|
+
if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(key)) {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
setActiveIndex((current) => resolveNextMenuIndex(actions, current, key));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (key === 'Enter') {
|
|
45
|
+
event.preventDefault();
|
|
46
|
+
const action = actions.at(activeIndex);
|
|
47
|
+
if (action)
|
|
48
|
+
activateAction(action);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (key === 'Escape') {
|
|
52
|
+
event.preventDefault();
|
|
53
|
+
close();
|
|
54
|
+
}
|
|
55
|
+
}), [actions, activeIndex, activateAction, bindKeydown, close, passive, setActiveIndex]);
|
|
56
|
+
}
|
|
57
|
+
/*** Renders one accessible PopoverMenu action row. */
|
|
58
|
+
function PopoverMenuItem({ action, active, activateAction, passive, testID, }) {
|
|
59
|
+
const { theme } = useTheme();
|
|
60
|
+
const selected = action.selected ?? active;
|
|
61
|
+
return (<Pressable accessibilityRole="menuitem" accessibilityState={{ disabled: action.disabled, selected }} disabled={action.disabled} onPress={passive ? undefined : () => activateAction(action)} testID={testID ? `${testID}-item-${action.id}` : undefined}>
|
|
62
|
+
<Box bg={selected ? theme.semantics.action.neutral.softBg : 'transparent'} opacity={action.disabled ? 0.56 : 1} px="m" py="s" radius="s">
|
|
63
|
+
<PopoverMenuItemContent action={action} active={active}/>
|
|
64
|
+
</Box>
|
|
65
|
+
</Pressable>);
|
|
66
|
+
}
|
|
67
|
+
/*** Renders the leading, textual, and trailing content of one menu action. */
|
|
68
|
+
function PopoverMenuItemContent({ action, active, }) {
|
|
69
|
+
const titleColor = action.intent === 'danger' ? 'danger' : active || action.selected ? 'neutral' : undefined;
|
|
70
|
+
return (<Inline align="center" gap="s" justify="space-between" wrap="nowrap">
|
|
71
|
+
{action.leading ? <Box>{action.leading}</Box> : null}
|
|
72
|
+
<Box flex={1}>
|
|
73
|
+
<Stack gap="xxs">
|
|
74
|
+
<Text color={titleColor} variant="bodySmall" weight={action.selected ? 'semiBold' : 'medium'}>
|
|
75
|
+
{action.title}
|
|
76
|
+
</Text>
|
|
77
|
+
{action.description ? (<Text emphasis="muted" variant="caption">
|
|
78
|
+
{action.description}
|
|
79
|
+
</Text>) : null}
|
|
80
|
+
</Stack>
|
|
81
|
+
</Box>
|
|
82
|
+
{action.trailing ? <Box>{action.trailing}</Box> : null}
|
|
83
|
+
</Inline>);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=PopoverMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PopoverMenu.js","sourceRoot":"","sources":["../../../../../src/features/popover-menu/adapters/inbound/PopoverMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Pressable } from 'react-native';\n\nimport { FocusScope } from '../../../../internal/focus/FocusScope';\nimport { useFocusManager } from '../../../../internal/focus/useFocusManager';\nimport { Inline } from '../../../../layout';\nimport { useTheme } from '../../../../theme/ThemeContext';\nimport type { PopoverMenuAction, PopoverMenuProps } from '../../../../types/popoverMenu';\nimport { Box, Stack } from '../../../layout/public';\nimport { Popover } from '../../../popover/public';\nimport { Surface } from '../../../surface/public';\nimport { Text } from '../../../typography/public';\nimport { usePopoverMenuController } from '../../composition/usePopoverMenuController';\nimport { resolveNextMenuIndex } from '../../utils/resolveNextMenuIndex';\n\n/*** Presents an anchored action menu using the shared Popover capability. */\nexport function PopoverMenu({\n trigger,\n actions,\n dismiss,\n closeOnSelect = true,\n interactionPolicy = 'enabled',\n testID,\n}: PopoverMenuProps) {\n const passive = interactionPolicy === 'passive';\n const controller = usePopoverMenuController({ actions, closeOnSelect, dismiss, passive });\n\n return (\n <Popover\n anchor={trigger}\n closeOnOutsidePress\n interactionPolicy={interactionPolicy}\n onOpenChange={controller.handleOpenChange}\n open={controller.open}\n placement=\"bottom-start\"\n testID={testID}\n >\n <PopoverMenuContent\n actions={actions}\n activeIndex={controller.activeIndex}\n activateAction={controller.activateAction}\n close={controller.close}\n passive={passive}\n setActiveIndex={controller.setActiveIndex}\n testID={testID}\n />\n </Popover>\n );\n}\n\ninterface PopoverMenuContentProps {\n actions: readonly PopoverMenuAction[];\n activeIndex: number;\n activateAction: (action: PopoverMenuAction) => void;\n close: () => void;\n passive: boolean;\n setActiveIndex: React.Dispatch<React.SetStateAction<number>>;\n testID?: string;\n}\n\n/*** Renders menu semantics and keyboard navigation inside an open Popover. */\nfunction PopoverMenuContent({\n actions,\n activeIndex,\n activateAction,\n close,\n passive,\n setActiveIndex,\n testID,\n}: PopoverMenuContentProps) {\n usePopoverMenuKeyboard({ actions, activeIndex, activateAction, close, passive, setActiveIndex });\n\n return (\n <FocusScope active onEscape={passive ? undefined : close}>\n <Surface accessibilityRole=\"menu\" p=\"xs\" testID={testID} variant=\"raised\">\n {actions.map((action, index) => (\n <PopoverMenuItem\n action={action}\n active={index === activeIndex}\n activateAction={activateAction}\n key={action.id}\n passive={passive}\n testID={testID}\n />\n ))}\n </Surface>\n </FocusScope>\n );\n}\n\n/*** Subscribes an open PopoverMenu to standard menu keyboard controls. */\nfunction usePopoverMenuKeyboard({\n actions,\n activeIndex,\n activateAction,\n close,\n passive,\n setActiveIndex,\n}: Omit<PopoverMenuContentProps, 'testID'>) {\n const { bindKeydown } = useFocusManager();\n\n React.useEffect(\n () =>\n bindKeydown((event) => {\n if (passive) return;\n\n const { key } = event;\n if (key === undefined) return;\n\n if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(key)) {\n event.preventDefault();\n setActiveIndex((current) => resolveNextMenuIndex(actions, current, key));\n return;\n }\n if (key === 'Enter') {\n event.preventDefault();\n const action = actions.at(activeIndex);\n if (action) activateAction(action);\n return;\n }\n if (key === 'Escape') {\n event.preventDefault();\n close();\n }\n }),\n [actions, activeIndex, activateAction, bindKeydown, close, passive, setActiveIndex],\n );\n}\n\n/*** Renders one accessible PopoverMenu action row. */\nfunction PopoverMenuItem({\n action,\n active,\n activateAction,\n passive,\n testID,\n}: {\n action: PopoverMenuAction;\n active: boolean;\n activateAction: (action: PopoverMenuAction) => void;\n passive: boolean;\n testID?: string;\n}) {\n const { theme } = useTheme();\n const selected = action.selected ?? active;\n\n return (\n <Pressable\n accessibilityRole=\"menuitem\"\n accessibilityState={{ disabled: action.disabled, selected }}\n disabled={action.disabled}\n onPress={passive ? undefined : () => activateAction(action)}\n testID={testID ? `${testID}-item-${action.id}` : undefined}\n >\n <Box\n bg={selected ? theme.semantics.action.neutral.softBg : 'transparent'}\n opacity={action.disabled ? 0.56 : 1}\n px=\"m\"\n py=\"s\"\n radius=\"s\"\n >\n <PopoverMenuItemContent action={action} active={active} />\n </Box>\n </Pressable>\n );\n}\n\n/*** Renders the leading, textual, and trailing content of one menu action. */\nfunction PopoverMenuItemContent({\n action,\n active,\n}: {\n action: PopoverMenuAction;\n active: boolean;\n}) {\n const titleColor =\n action.intent === 'danger' ? 'danger' : active || action.selected ? 'neutral' : undefined;\n\n return (\n <Inline align=\"center\" gap=\"s\" justify=\"space-between\" wrap=\"nowrap\">\n {action.leading ? <Box>{action.leading}</Box> : null}\n <Box flex={1}>\n <Stack gap=\"xxs\">\n <Text\n color={titleColor}\n variant=\"bodySmall\"\n weight={action.selected ? 'semiBold' : 'medium'}\n >\n {action.title}\n </Text>\n {action.description ? (\n <Text emphasis=\"muted\" variant=\"caption\">\n {action.description}\n </Text>\n ) : null}\n </Stack>\n </Box>\n {action.trailing ? <Box>{action.trailing}</Box> : null}\n </Inline>\n );\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { PopoverMenuAction } from '../../../types/popoverMenu';
|
|
3
|
+
interface PopoverMenuControllerOptions {
|
|
4
|
+
actions: readonly PopoverMenuAction[];
|
|
5
|
+
closeOnSelect: boolean;
|
|
6
|
+
dismiss?: () => void;
|
|
7
|
+
passive: boolean;
|
|
8
|
+
}
|
|
9
|
+
/*** Owns PopoverMenu visibility, active action state, and selection behavior. */
|
|
10
|
+
export declare function usePopoverMenuController({ actions, closeOnSelect, dismiss, passive, }: PopoverMenuControllerOptions): {
|
|
11
|
+
readonly activeIndex: number;
|
|
12
|
+
readonly activateAction: (action: PopoverMenuAction) => void;
|
|
13
|
+
readonly close: () => void;
|
|
14
|
+
readonly handleOpenChange: (nextOpen: boolean) => void;
|
|
15
|
+
readonly open: boolean;
|
|
16
|
+
readonly setActiveIndex: React.Dispatch<React.SetStateAction<number>>;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=usePopoverMenuController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePopoverMenuController.d.ts","sourceRoot":"","sources":["../../../../src/features/popover-menu/composition/usePopoverMenuController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,UAAU,4BAA4B;IACpC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtC,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,iFAAiF;AACjF,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,aAAa,EACb,OAAO,EACP,OAAO,GACR,EAAE,4BAA4B;;sCAelB,iBAAiB;;0CAVf,OAAO;;;EA0BrB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/*** Owns PopoverMenu visibility, active action state, and selection behavior. */
|
|
3
|
+
export function usePopoverMenuController({ actions, closeOnSelect, dismiss, passive, }) {
|
|
4
|
+
const [open, setOpen] = React.useState(false);
|
|
5
|
+
const [activeIndex, setActiveIndex] = React.useState(0);
|
|
6
|
+
const handleOpenChange = React.useCallback((nextOpen) => {
|
|
7
|
+
if (nextOpen)
|
|
8
|
+
setActiveIndex(resolveInitialIndex(actions));
|
|
9
|
+
if (open && !nextOpen)
|
|
10
|
+
dismiss?.();
|
|
11
|
+
setOpen(nextOpen);
|
|
12
|
+
}, [actions, dismiss, open]);
|
|
13
|
+
const close = React.useCallback(() => handleOpenChange(false), [handleOpenChange]);
|
|
14
|
+
const activateAction = React.useCallback((action) => {
|
|
15
|
+
if (action.disabled || passive)
|
|
16
|
+
return;
|
|
17
|
+
action.activate?.();
|
|
18
|
+
if (closeOnSelect)
|
|
19
|
+
close();
|
|
20
|
+
}, [close, closeOnSelect, passive]);
|
|
21
|
+
return {
|
|
22
|
+
activeIndex,
|
|
23
|
+
activateAction,
|
|
24
|
+
close,
|
|
25
|
+
handleOpenChange,
|
|
26
|
+
open,
|
|
27
|
+
setActiveIndex,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/*** Returns the first enabled action index for a newly opened menu. */
|
|
31
|
+
function resolveInitialIndex(actions) {
|
|
32
|
+
const index = actions.findIndex((action) => !action.disabled);
|
|
33
|
+
return index === -1 ? 0 : index;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=usePopoverMenuController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePopoverMenuController.js","sourceRoot":"","sources":["../../../../src/features/popover-menu/composition/usePopoverMenuController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAW1B,iFAAiF;AACjF,MAAM,UAAU,wBAAwB,CAAC,EACvC,OAAO,EACP,aAAa,EACb,OAAO,EACP,OAAO,GACsB;IAC7B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAExD,MAAM,gBAAgB,GAAG,KAAK,CAAC,WAAW,CACxC,CAAC,QAAiB,EAAE,EAAE;QACpB,IAAI,QAAQ;YAAE,cAAc,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3D,IAAI,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,EAAE,EAAE,CAAC;QACnC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpB,CAAC,EACD,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CACzB,CAAC;IAEF,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACnF,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CAAC,MAAyB,EAAE,EAAE;QAC5B,IAAI,MAAM,CAAC,QAAQ,IAAI,OAAO;YAAE,OAAO;QACvC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QACpB,IAAI,aAAa;YAAE,KAAK,EAAE,CAAC;IAC7B,CAAC,EACD,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,CAChC,CAAC;IAEF,OAAO;QACL,WAAW;QACX,cAAc;QACd,KAAK;QACL,gBAAgB;QAChB,IAAI;QACJ,cAAc;KACN,CAAC;AACb,CAAC;AAED,uEAAuE;AACvE,SAAS,mBAAmB,CAAC,OAAqC;IAChE,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9D,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAClC,CAAC","sourcesContent":["import React from 'react';\n\nimport type { PopoverMenuAction } from '../../../types/popoverMenu';\n\ninterface PopoverMenuControllerOptions {\n actions: readonly PopoverMenuAction[];\n closeOnSelect: boolean;\n dismiss?: () => void;\n passive: boolean;\n}\n\n/*** Owns PopoverMenu visibility, active action state, and selection behavior. */\nexport function usePopoverMenuController({\n actions,\n closeOnSelect,\n dismiss,\n passive,\n}: PopoverMenuControllerOptions) {\n const [open, setOpen] = React.useState(false);\n const [activeIndex, setActiveIndex] = React.useState(0);\n\n const handleOpenChange = React.useCallback(\n (nextOpen: boolean) => {\n if (nextOpen) setActiveIndex(resolveInitialIndex(actions));\n if (open && !nextOpen) dismiss?.();\n setOpen(nextOpen);\n },\n [actions, dismiss, open],\n );\n\n const close = React.useCallback(() => handleOpenChange(false), [handleOpenChange]);\n const activateAction = React.useCallback(\n (action: PopoverMenuAction) => {\n if (action.disabled || passive) return;\n action.activate?.();\n if (closeOnSelect) close();\n },\n [close, closeOnSelect, passive],\n );\n\n return {\n activeIndex,\n activateAction,\n close,\n handleOpenChange,\n open,\n setActiveIndex,\n } as const;\n}\n\n/*** Returns the first enabled action index for a newly opened menu. */\nfunction resolveInitialIndex(actions: readonly PopoverMenuAction[]): number {\n const index = actions.findIndex((action) => !action.disabled);\n return index === -1 ? 0 : index;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/popover-menu/public.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,iBAAiB,EACjB,uBAAuB,EACvB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/popover-menu/public.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC","sourcesContent":["export type {\n PopoverMenuAction,\n PopoverMenuActionIntent,\n PopoverMenuProps,\n} from '../../types/popoverMenu';\nexport { PopoverMenu } from './adapters/inbound/PopoverMenu';\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/*** Resolves the next enabled action index for standard menu keyboard navigation. */
|
|
2
|
+
export declare function resolveNextMenuIndex(items: readonly {
|
|
3
|
+
disabled?: boolean;
|
|
4
|
+
}[], currentIndex: number, key: string): number;
|
|
5
|
+
//# sourceMappingURL=resolveNextMenuIndex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveNextMenuIndex.d.ts","sourceRoot":"","sources":["../../../../src/features/popover-menu/utils/resolveNextMenuIndex.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,EACxC,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,GACV,MAAM,CAeR"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*** Resolves the next enabled action index for standard menu keyboard navigation. */
|
|
2
|
+
export function resolveNextMenuIndex(items, currentIndex, key) {
|
|
3
|
+
const enabledIndexes = items.flatMap((item, index) => (item.disabled ? [] : [index]));
|
|
4
|
+
if (enabledIndexes.length === 0)
|
|
5
|
+
return -1;
|
|
6
|
+
if (key === 'Home')
|
|
7
|
+
return enabledIndexes.at(0) ?? -1;
|
|
8
|
+
if (key === 'End')
|
|
9
|
+
return enabledIndexes.at(-1) ?? -1;
|
|
10
|
+
const activeEnabledIndex = enabledIndexes.indexOf(currentIndex);
|
|
11
|
+
const nextEnabledIndex = activeEnabledIndex === -1
|
|
12
|
+
? 0
|
|
13
|
+
: key === 'ArrowUp'
|
|
14
|
+
? (activeEnabledIndex - 1 + enabledIndexes.length) % enabledIndexes.length
|
|
15
|
+
: (activeEnabledIndex + 1) % enabledIndexes.length;
|
|
16
|
+
return enabledIndexes.at(nextEnabledIndex) ?? -1;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=resolveNextMenuIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveNextMenuIndex.js","sourceRoot":"","sources":["../../../../src/features/popover-menu/utils/resolveNextMenuIndex.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,MAAM,UAAU,oBAAoB,CAClC,KAAwC,EACxC,YAAoB,EACpB,GAAW;IAEX,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACtF,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC;IAC3C,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACtD,IAAI,GAAG,KAAK,KAAK;QAAE,OAAO,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEtD,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAChE,MAAM,gBAAgB,GACpB,kBAAkB,KAAK,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,GAAG,KAAK,SAAS;YACjB,CAAC,CAAC,CAAC,kBAAkB,GAAG,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,cAAc,CAAC,MAAM;YAC1E,CAAC,CAAC,CAAC,kBAAkB,GAAG,CAAC,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC;IAEzD,OAAO,cAAc,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;AACnD,CAAC","sourcesContent":["/*** Resolves the next enabled action index for standard menu keyboard navigation. */\nexport function resolveNextMenuIndex(\n items: readonly { disabled?: boolean }[],\n currentIndex: number,\n key: string,\n): number {\n const enabledIndexes = items.flatMap((item, index) => (item.disabled ? [] : [index]));\n if (enabledIndexes.length === 0) return -1;\n if (key === 'Home') return enabledIndexes.at(0) ?? -1;\n if (key === 'End') return enabledIndexes.at(-1) ?? -1;\n\n const activeEnabledIndex = enabledIndexes.indexOf(currentIndex);\n const nextEnabledIndex =\n activeEnabledIndex === -1\n ? 0\n : key === 'ArrowUp'\n ? (activeEnabledIndex - 1 + enabledIndexes.length) % enabledIndexes.length\n : (activeEnabledIndex + 1) % enabledIndexes.length;\n\n return enabledIndexes.at(nextEnabledIndex) ?? -1;\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { TabProps } from '../../../../types/tabs';
|
|
3
|
+
/*** Renders one accessible selectable tab inside a Tabs context. */
|
|
4
|
+
export declare function Tab({ value, children, disabled, interactionPolicy, testID, }: TabProps): React.JSX.Element;
|
|
5
|
+
//# sourceMappingURL=Tab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tab.d.ts","sourceRoot":"","sources":["../../../../../src/features/tabs/adapters/inbound/Tab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAMvD,oEAAoE;AACpE,wBAAgB,GAAG,CAAC,EAClB,KAAK,EACL,QAAQ,EACR,QAAgB,EAChB,iBAA6B,EAC7B,MAAM,GACP,EAAE,QAAQ,qBAsCV"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Pressable } from 'react-native';
|
|
3
|
+
import { useTheme } from '../../../../theme/ThemeContext';
|
|
4
|
+
import { Box } from '../../../layout/public';
|
|
5
|
+
import { Text } from '../../../typography/public';
|
|
6
|
+
import { useTabRegistration } from '../../composition/useTabRegistration';
|
|
7
|
+
import { useTabsContext } from '../../composition/useTabsContext';
|
|
8
|
+
/*** Renders one accessible selectable tab inside a Tabs context. */
|
|
9
|
+
export function Tab({ value, children, disabled = false, interactionPolicy = 'enabled', testID, }) {
|
|
10
|
+
const { theme } = useTheme();
|
|
11
|
+
const { activeValue, getPanelId, getTabId, setActiveValue, setFocusedValue } = useTabsContext();
|
|
12
|
+
const pressableRef = useTabRegistration({ disabled, value });
|
|
13
|
+
const selected = activeValue === value;
|
|
14
|
+
const passive = interactionPolicy === 'passive';
|
|
15
|
+
const onPress = passive || disabled ? undefined : () => setActiveValue(value);
|
|
16
|
+
return (<Pressable accessibilityLabel={undefined} accessibilityRole="tab" accessibilityState={{ disabled, selected }} aria-controls={getPanelId(value)} disabled={disabled} nativeID={getTabId(value)} onBlur={() => setFocusedValue(undefined)} onFocus={() => setFocusedValue(value)} onPress={onPress} ref={pressableRef} testID={testID}>
|
|
17
|
+
<Box px="m" py="s" style={resolveTabStyle({
|
|
18
|
+
borderColor: selected
|
|
19
|
+
? theme.semantics.action.primary.base
|
|
20
|
+
: theme.semantics.border.default,
|
|
21
|
+
disabled,
|
|
22
|
+
})}>
|
|
23
|
+
<Text color={selected ? 'primary' : undefined} variant="label" weight="medium">
|
|
24
|
+
{children}
|
|
25
|
+
</Text>
|
|
26
|
+
</Box>
|
|
27
|
+
</Pressable>);
|
|
28
|
+
}
|
|
29
|
+
/*** Resolves active and disabled visual state without inline JSX styles. */
|
|
30
|
+
function resolveTabStyle({ borderColor, disabled, }) {
|
|
31
|
+
return { borderBottomColor: borderColor, borderBottomWidth: 2, opacity: disabled ? 0.64 : 1 };
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=Tab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tab.js","sourceRoot":"","sources":["../../../../../src/features/tabs/adapters/inbound/Tab.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAkB,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAE1D,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAElE,oEAAoE;AACpE,MAAM,UAAU,GAAG,CAAC,EAClB,KAAK,EACL,QAAQ,EACR,QAAQ,GAAG,KAAK,EAChB,iBAAiB,GAAG,SAAS,EAC7B,MAAM,GACG;IACT,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC7B,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,GAAG,cAAc,EAAE,CAAC;IAChG,MAAM,YAAY,GAAG,kBAAkB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAG,WAAW,KAAK,KAAK,CAAC;IACvC,MAAM,OAAO,GAAG,iBAAiB,KAAK,SAAS,CAAC;IAChD,MAAM,OAAO,GAAG,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAE9E,OAAO,CACL,CAAC,SAAS,CACR,kBAAkB,CAAC,CAAC,SAAS,CAAC,CAC9B,iBAAiB,CAAC,KAAK,CACvB,kBAAkB,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAC3C,aAAa,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CACjC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,QAAQ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAC1B,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CACzC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CACtC,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,GAAG,CAAC,CAAC,YAAY,CAAC,CAClB,MAAM,CAAC,CAAC,MAAM,CAAC,CAEf;MAAA,CAAC,GAAG,CACF,EAAE,CAAC,GAAG,CACN,EAAE,CAAC,GAAG,CACN,KAAK,CAAC,CAAC,eAAe,CAAC;YACrB,WAAW,EAAE,QAAQ;gBACnB,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI;gBACrC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO;YAClC,QAAQ;SACT,CAAC,CAAC,CAEH;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAC5E;UAAA,CAAC,QAAQ,CACX;QAAA,EAAE,IAAI,CACR;MAAA,EAAE,GAAG,CACP;IAAA,EAAE,SAAS,CAAC,CACb,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,SAAS,eAAe,CAAC,EACvB,WAAW,EACX,QAAQ,GAIT;IACC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAChG,CAAC","sourcesContent":["import React from 'react';\nimport { Pressable, type ViewStyle } from 'react-native';\n\nimport { useTheme } from '../../../../theme/ThemeContext';\nimport type { TabProps } from '../../../../types/tabs';\nimport { Box } from '../../../layout/public';\nimport { Text } from '../../../typography/public';\nimport { useTabRegistration } from '../../composition/useTabRegistration';\nimport { useTabsContext } from '../../composition/useTabsContext';\n\n/*** Renders one accessible selectable tab inside a Tabs context. */\nexport function Tab({\n value,\n children,\n disabled = false,\n interactionPolicy = 'enabled',\n testID,\n}: TabProps) {\n const { theme } = useTheme();\n const { activeValue, getPanelId, getTabId, setActiveValue, setFocusedValue } = useTabsContext();\n const pressableRef = useTabRegistration({ disabled, value });\n const selected = activeValue === value;\n const passive = interactionPolicy === 'passive';\n const onPress = passive || disabled ? undefined : () => setActiveValue(value);\n\n return (\n <Pressable\n accessibilityLabel={undefined}\n accessibilityRole=\"tab\"\n accessibilityState={{ disabled, selected }}\n aria-controls={getPanelId(value)}\n disabled={disabled}\n nativeID={getTabId(value)}\n onBlur={() => setFocusedValue(undefined)}\n onFocus={() => setFocusedValue(value)}\n onPress={onPress}\n ref={pressableRef}\n testID={testID}\n >\n <Box\n px=\"m\"\n py=\"s\"\n style={resolveTabStyle({\n borderColor: selected\n ? theme.semantics.action.primary.base\n : theme.semantics.border.default,\n disabled,\n })}\n >\n <Text color={selected ? 'primary' : undefined} variant=\"label\" weight=\"medium\">\n {children}\n </Text>\n </Box>\n </Pressable>\n );\n}\n\n/*** Resolves active and disabled visual state without inline JSX styles. */\nfunction resolveTabStyle({\n borderColor,\n disabled,\n}: {\n borderColor: string;\n disabled: boolean;\n}): ViewStyle {\n return { borderBottomColor: borderColor, borderBottomWidth: 2, opacity: disabled ? 0.64 : 1 };\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { TabListProps } from '../../../../types/tabs';
|
|
3
|
+
/*** Renders the accessible tab list and owns keyboard focus navigation. */
|
|
4
|
+
export declare function TabList({ children, testID }: TabListProps): React.JSX.Element;
|
|
5
|
+
//# sourceMappingURL=TabList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabList.d.ts","sourceRoot":"","sources":["../../../../../src/features/tabs/adapters/inbound/TabList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,wBAAwB,CAAC;AAc7E,2EAA2E;AAC3E,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,YAAY,qBAuBzD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleSheet } from 'react-native';
|
|
3
|
+
import { useFocusManager } from '../../../../internal/focus/useFocusManager';
|
|
4
|
+
import { Box } from '../../../layout/public';
|
|
5
|
+
import { useTabsContext } from '../../composition/useTabsContext';
|
|
6
|
+
import { resolveNextTabValue } from '../../utils/resolveNextTabValue';
|
|
7
|
+
const navigationKeys = [
|
|
8
|
+
'ArrowLeft',
|
|
9
|
+
'ArrowRight',
|
|
10
|
+
'ArrowUp',
|
|
11
|
+
'ArrowDown',
|
|
12
|
+
'Home',
|
|
13
|
+
'End',
|
|
14
|
+
];
|
|
15
|
+
/*** Renders the accessible tab list and owns keyboard focus navigation. */
|
|
16
|
+
export function TabList({ children, testID }) {
|
|
17
|
+
const { bindKeydown } = useFocusManager();
|
|
18
|
+
const { focusedValue, setActiveValue, tabs } = useTabsContext();
|
|
19
|
+
React.useEffect(() => {
|
|
20
|
+
if (!focusedValue)
|
|
21
|
+
return undefined;
|
|
22
|
+
return bindKeydown((event) => {
|
|
23
|
+
if (!isTabNavigationKey(event.key))
|
|
24
|
+
return;
|
|
25
|
+
const nextValue = resolveNextTabValue(tabs, focusedValue, event.key);
|
|
26
|
+
if (!nextValue)
|
|
27
|
+
return;
|
|
28
|
+
event.preventDefault();
|
|
29
|
+
tabs.find((tab) => tab.value === nextValue)?.focus();
|
|
30
|
+
setActiveValue(nextValue);
|
|
31
|
+
});
|
|
32
|
+
}, [bindKeydown, focusedValue, setActiveValue, tabs]);
|
|
33
|
+
return (<Box accessibilityRole="tablist" style={styles.list} testID={testID}>
|
|
34
|
+
{children}
|
|
35
|
+
</Box>);
|
|
36
|
+
}
|
|
37
|
+
/*** Narrows keyboard event keys to the tab navigation key contract. */
|
|
38
|
+
function isTabNavigationKey(key) {
|
|
39
|
+
return key !== undefined && navigationKeys.includes(key);
|
|
40
|
+
}
|
|
41
|
+
const styles = StyleSheet.create({ list: { flexDirection: 'row' } });
|
|
42
|
+
//# sourceMappingURL=TabList.js.map
|