@ankhorage/surface 5.0.0 → 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 +6 -0
- package/README.md +2 -2
- 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/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/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.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/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/package.json +1 -1
- package/src/features/modal/adapters/inbound/Modal.tsx +74 -0
- package/src/features/modal/public.ts +2 -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/index.test.ts +4 -2
- package/src/index.ts +4 -4
- package/src/{components/modal/types.ts → types/modal.ts} +1 -1
- package/src/types/tabs.ts +51 -0
- 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/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/CHANGELOG.md
CHANGED
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)
|
|
@@ -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 { 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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabList.js","sourceRoot":"","sources":["../../../../../src/features/tabs/adapters/inbound/TabList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAE7E,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,MAAM,cAAc,GAAsB;IACxC,WAAW;IACX,YAAY;IACZ,SAAS;IACT,WAAW;IACX,MAAM;IACN,KAAK;CACN,CAAC;AAEF,2EAA2E;AAC3E,MAAM,UAAU,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAgB;IACxD,MAAM,EAAE,WAAW,EAAE,GAAG,eAAe,EAAE,CAAC;IAC1C,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,cAAc,EAAE,CAAC;IAEhE,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,YAAY;YAAE,OAAO,SAAS,CAAC;QAEpC,OAAO,WAAW,CAAC,CAAC,KAAK,EAAE,EAAE;YAC3B,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC;gBAAE,OAAO;YAC3C,MAAM,SAAS,GAAG,mBAAmB,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YACrE,IAAI,CAAC,SAAS;gBAAE,OAAO;YAEvB,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;YACrD,cAAc,CAAC,SAAS,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC;IAEtD,OAAO,CACL,CAAC,GAAG,CAAC,iBAAiB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAClE;MAAA,CAAC,QAAQ,CACX;IAAA,EAAE,GAAG,CAAC,CACP,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,SAAS,kBAAkB,CAAC,GAAuB;IACjD,OAAO,GAAG,KAAK,SAAS,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC","sourcesContent":["import React from 'react';\nimport { StyleSheet } from 'react-native';\n\nimport { useFocusManager } from '../../../../internal/focus/useFocusManager';\nimport type { TabListProps, TabNavigationKey } from '../../../../types/tabs';\nimport { Box } from '../../../layout/public';\nimport { useTabsContext } from '../../composition/useTabsContext';\nimport { resolveNextTabValue } from '../../utils/resolveNextTabValue';\n\nconst navigationKeys: readonly string[] = [\n 'ArrowLeft',\n 'ArrowRight',\n 'ArrowUp',\n 'ArrowDown',\n 'Home',\n 'End',\n];\n\n/*** Renders the accessible tab list and owns keyboard focus navigation. */\nexport function TabList({ children, testID }: TabListProps) {\n const { bindKeydown } = useFocusManager();\n const { focusedValue, setActiveValue, tabs } = useTabsContext();\n\n React.useEffect(() => {\n if (!focusedValue) return undefined;\n\n return bindKeydown((event) => {\n if (!isTabNavigationKey(event.key)) return;\n const nextValue = resolveNextTabValue(tabs, focusedValue, event.key);\n if (!nextValue) return;\n\n event.preventDefault();\n tabs.find((tab) => tab.value === nextValue)?.focus();\n setActiveValue(nextValue);\n });\n }, [bindKeydown, focusedValue, setActiveValue, tabs]);\n\n return (\n <Box accessibilityRole=\"tablist\" style={styles.list} testID={testID}>\n {children}\n </Box>\n );\n}\n\n/*** Narrows keyboard event keys to the tab navigation key contract. */\nfunction isTabNavigationKey(key: string | undefined): key is TabNavigationKey {\n return key !== undefined && navigationKeys.includes(key);\n}\n\nconst styles = StyleSheet.create({ list: { flexDirection: 'row' } });\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { TabPanelProps } from '../../../../types/tabs';
|
|
3
|
+
/*** Renders the content panel associated with the active tab value. */
|
|
4
|
+
export declare function TabPanel({ value, children, testID }: TabPanelProps): React.JSX.Element | null;
|
|
5
|
+
//# sourceMappingURL=TabPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabPanel.d.ts","sourceRoot":"","sources":["../../../../../src/features/tabs/adapters/inbound/TabPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAK5D,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,aAAa,4BAelE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { useTabsContext } from '../../composition/useTabsContext';
|
|
4
|
+
const TAB_PANEL_ROLE = 'tabpanel';
|
|
5
|
+
/*** Renders the content panel associated with the active tab value. */
|
|
6
|
+
export function TabPanel({ value, children, testID }) {
|
|
7
|
+
const { activeValue, getPanelId, getTabId } = useTabsContext();
|
|
8
|
+
if (activeValue !== value)
|
|
9
|
+
return null;
|
|
10
|
+
return (<View accessibilityLabelledBy={getTabId(value)} accessibilityRole={TAB_PANEL_ROLE} nativeID={getPanelId(value)} testID={testID}>
|
|
11
|
+
{children}
|
|
12
|
+
</View>);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=TabPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabPanel.js","sourceRoot":"","sources":["../../../../../src/features/tabs/adapters/inbound/TabPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAGpC,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAElE,MAAM,cAAc,GAAG,UAAoE,CAAC;AAE5F,uEAAuE;AACvE,MAAM,UAAU,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAiB;IACjE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,cAAc,EAAE,CAAC;IAE/D,IAAI,WAAW,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAEvC,OAAO,CACL,CAAC,IAAI,CACH,uBAAuB,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CACzC,iBAAiB,CAAC,CAAC,cAAc,CAAC,CAClC,QAAQ,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAC5B,MAAM,CAAC,CAAC,MAAM,CAAC,CAEf;MAAA,CAAC,QAAQ,CACX;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC","sourcesContent":["import React from 'react';\nimport { View } from 'react-native';\n\nimport type { TabPanelProps } from '../../../../types/tabs';\nimport { useTabsContext } from '../../composition/useTabsContext';\n\nconst TAB_PANEL_ROLE = 'tabpanel' as React.ComponentProps<typeof View>['accessibilityRole'];\n\n/*** Renders the content panel associated with the active tab value. */\nexport function TabPanel({ value, children, testID }: TabPanelProps) {\n const { activeValue, getPanelId, getTabId } = useTabsContext();\n\n if (activeValue !== value) return null;\n\n return (\n <View\n accessibilityLabelledBy={getTabId(value)}\n accessibilityRole={TAB_PANEL_ROLE}\n nativeID={getPanelId(value)}\n testID={testID}\n >\n {children}\n </View>\n );\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { TabsProps } from '../../../../types/tabs';
|
|
3
|
+
/*** Provides accessible tab selection state to TabList, Tab, and TabPanel children. */
|
|
4
|
+
export declare function Tabs({ children, ...props }: TabsProps): React.JSX.Element;
|
|
5
|
+
//# sourceMappingURL=Tabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../../../src/features/tabs/adapters/inbound/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAKxD,uFAAuF;AACvF,wBAAgB,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,SAAS,qBAQrD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Box } from '../../../layout/public';
|
|
3
|
+
import { TabsContext } from '../../composition/TabsContext';
|
|
4
|
+
import { useTabsController } from '../../composition/useTabsController';
|
|
5
|
+
/*** Provides accessible tab selection state to TabList, Tab, and TabPanel children. */
|
|
6
|
+
export function Tabs({ children, ...props }) {
|
|
7
|
+
const contextValue = useTabsController(props);
|
|
8
|
+
return (<TabsContext value={contextValue}>
|
|
9
|
+
<Box testID={props.testID}>{children}</Box>
|
|
10
|
+
</TabsContext>);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=Tabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.js","sourceRoot":"","sources":["../../../../../src/features/tabs/adapters/inbound/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAExE,uFAAuF;AACvF,MAAM,UAAU,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAa;IACpD,MAAM,YAAY,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAE9C,OAAO,CACL,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAC/B;MAAA,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,GAAG,CAC5C;IAAA,EAAE,WAAW,CAAC,CACf,CAAC;AACJ,CAAC","sourcesContent":["import React from 'react';\n\nimport type { TabsProps } from '../../../../types/tabs';\nimport { Box } from '../../../layout/public';\nimport { TabsContext } from '../../composition/TabsContext';\nimport { useTabsController } from '../../composition/useTabsController';\n\n/*** Provides accessible tab selection state to TabList, Tab, and TabPanel children. */\nexport function Tabs({ children, ...props }: TabsProps) {\n const contextValue = useTabsController(props);\n\n return (\n <TabsContext value={contextValue}>\n <Box testID={props.testID}>{children}</Box>\n </TabsContext>\n );\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabsContext.d.ts","sourceRoot":"","sources":["../../../../src/features/tabs/composition/TabsContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,eAAO,MAAM,WAAW,wCAAqD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabsContext.js","sourceRoot":"","sources":["../../../../src/features/tabs/composition/TabsContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAA0B,IAAI,CAAC,CAAC","sourcesContent":["import React from 'react';\n\nimport type { TabsContextValue } from '../../../types/tabs';\n\nexport const TabsContext = React.createContext<TabsContextValue | null>(null);\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/*** Registers one focusable tab with the owning Tabs context. */
|
|
3
|
+
export declare function useTabRegistration({ disabled, value }: {
|
|
4
|
+
disabled: boolean;
|
|
5
|
+
value: string;
|
|
6
|
+
}): React.RefObject<import("react-native").View | null>;
|
|
7
|
+
//# sourceMappingURL=useTabRegistration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTabRegistration.d.ts","sourceRoot":"","sources":["../../../../src/features/tabs/composition/useTabRegistration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,uDAoB3F"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useTabsContext } from './useTabsContext';
|
|
3
|
+
/*** Registers one focusable tab with the owning Tabs context. */
|
|
4
|
+
export function useTabRegistration({ disabled, value }) {
|
|
5
|
+
const { registerTab, unregisterTab } = useTabsContext();
|
|
6
|
+
const pressableRef = React.useRef(null);
|
|
7
|
+
React.useEffect(() => {
|
|
8
|
+
registerTab({
|
|
9
|
+
disabled,
|
|
10
|
+
focus: () => {
|
|
11
|
+
const focusable = pressableRef.current;
|
|
12
|
+
focusable?.focus?.();
|
|
13
|
+
},
|
|
14
|
+
value,
|
|
15
|
+
});
|
|
16
|
+
return () => unregisterTab(value);
|
|
17
|
+
}, [disabled, registerTab, unregisterTab, value]);
|
|
18
|
+
return pressableRef;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=useTabRegistration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTabRegistration.js","sourceRoot":"","sources":["../../../../src/features/tabs/composition/useTabRegistration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,iEAAiE;AACjE,MAAM,UAAU,kBAAkB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAwC;IAC1F,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,cAAc,EAAE,CAAC;IACxD,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAA4C,IAAI,CAAC,CAAC;IAEnF,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,WAAW,CAAC;YACV,QAAQ;YACR,KAAK,EAAE,GAAG,EAAE;gBACV,MAAM,SAAS,GAAG,YAAY,CAAC,OAEvB,CAAC;gBACT,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC;YACvB,CAAC;YACD,KAAK;SACN,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC;IAElD,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["import React from 'react';\nimport type { Pressable } from 'react-native';\n\nimport { useTabsContext } from './useTabsContext';\n\n/*** Registers one focusable tab with the owning Tabs context. */\nexport function useTabRegistration({ disabled, value }: { disabled: boolean; value: string }) {\n const { registerTab, unregisterTab } = useTabsContext();\n const pressableRef = React.useRef<React.ElementRef<typeof Pressable> | null>(null);\n\n React.useEffect(() => {\n registerTab({\n disabled,\n focus: () => {\n const focusable = pressableRef.current as unknown as {\n focus?: (() => void) | undefined;\n } | null;\n focusable?.focus?.();\n },\n value,\n });\n\n return () => unregisterTab(value);\n }, [disabled, registerTab, unregisterTab, value]);\n\n return pressableRef;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTabsContext.d.ts","sourceRoot":"","sources":["../../../../src/features/tabs/composition/useTabsContext.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,gDAAgD;AAChD,wBAAgB,cAAc,IAAI,gBAAgB,CAMjD"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
2
|
+
import { TabsContext } from './TabsContext';
|
|
3
|
+
/*** Returns the active Tabs feature context. */
|
|
3
4
|
export function useTabsContext() {
|
|
4
5
|
const value = React.use(TabsContext);
|
|
5
|
-
if (!value)
|
|
6
|
+
if (!value)
|
|
6
7
|
throw new Error('Tabs components must be used within <Tabs>.');
|
|
7
|
-
}
|
|
8
8
|
return value;
|
|
9
9
|
}
|
|
10
|
-
//# sourceMappingURL=
|
|
10
|
+
//# sourceMappingURL=useTabsContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTabsContext.js","sourceRoot":"","sources":["../../../../src/features/tabs/composition/useTabsContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,gDAAgD;AAChD,MAAM,UAAU,cAAc;IAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAErC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAE3E,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import React from 'react';\n\nimport type { TabsContextValue } from '../../../types/tabs';\nimport { TabsContext } from './TabsContext';\n\n/*** Returns the active Tabs feature context. */\nexport function useTabsContext(): TabsContextValue {\n const value = React.use(TabsContext);\n\n if (!value) throw new Error('Tabs components must be used within <Tabs>.');\n\n return value;\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TabsContextValue, TabsProps } from '../../../types/tabs';
|
|
2
|
+
/*** Owns controlled state, registration, focus state, and ids for one Tabs instance. */
|
|
3
|
+
export declare function useTabsController({ defaultValue, onValueChange, testID, value, }: Pick<TabsProps, 'defaultValue' | 'onValueChange' | 'testID' | 'value'>): TabsContextValue;
|
|
4
|
+
//# sourceMappingURL=useTabsController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTabsController.d.ts","sourceRoot":"","sources":["../../../../src/features/tabs/composition/useTabsController.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGxF,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,EAChC,YAAY,EACZ,aAAa,EACb,MAAM,EACN,KAAK,GACN,EAAE,IAAI,CAAC,SAAS,EAAE,cAAc,GAAG,eAAe,GAAG,QAAQ,GAAG,OAAO,CAAC,GAAG,gBAAgB,CA0C3F"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useControllableState } from '../../../internal/useControllableState';
|
|
3
|
+
import { resolveTabElementId } from '../utils/resolveTabElementId';
|
|
4
|
+
/*** Owns controlled state, registration, focus state, and ids for one Tabs instance. */
|
|
5
|
+
export function useTabsController({ defaultValue, onValueChange, testID, value, }) {
|
|
6
|
+
const [activeValue, setActiveValue] = useControllableState({
|
|
7
|
+
defaultValue,
|
|
8
|
+
onChange: (nextValue) => {
|
|
9
|
+
if (nextValue !== undefined)
|
|
10
|
+
onValueChange?.(nextValue);
|
|
11
|
+
},
|
|
12
|
+
value,
|
|
13
|
+
});
|
|
14
|
+
const [focusedValue, setFocusedValue] = React.useState(undefined);
|
|
15
|
+
const [tabs, setTabs] = React.useState([]);
|
|
16
|
+
const registerTab = React.useCallback((tab) => {
|
|
17
|
+
setTabs((current) => current.some((entry) => entry.value === tab.value)
|
|
18
|
+
? current.map((entry) => (entry.value === tab.value ? tab : entry))
|
|
19
|
+
: [...current, tab]);
|
|
20
|
+
}, []);
|
|
21
|
+
const unregisterTab = React.useCallback((valueToRemove) => {
|
|
22
|
+
setTabs((current) => current.filter((entry) => entry.value !== valueToRemove));
|
|
23
|
+
}, []);
|
|
24
|
+
React.useEffect(() => {
|
|
25
|
+
if (activeValue !== undefined)
|
|
26
|
+
return;
|
|
27
|
+
const firstEnabledTab = tabs.find((entry) => !entry.disabled);
|
|
28
|
+
if (firstEnabledTab)
|
|
29
|
+
setActiveValue(firstEnabledTab.value);
|
|
30
|
+
}, [activeValue, setActiveValue, tabs]);
|
|
31
|
+
return React.useMemo(() => ({
|
|
32
|
+
activeValue,
|
|
33
|
+
focusedValue,
|
|
34
|
+
getPanelId: (tabValue) => resolveTabElementId('panel', testID, tabValue),
|
|
35
|
+
getTabId: (tabValue) => resolveTabElementId('tab', testID, tabValue),
|
|
36
|
+
registerTab,
|
|
37
|
+
setActiveValue: (nextValue) => setActiveValue(nextValue),
|
|
38
|
+
setFocusedValue,
|
|
39
|
+
tabs,
|
|
40
|
+
unregisterTab,
|
|
41
|
+
}), [activeValue, focusedValue, registerTab, setActiveValue, tabs, testID, unregisterTab]);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=useTabsController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTabsController.js","sourceRoot":"","sources":["../../../../src/features/tabs/composition/useTabsController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAE9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE,wFAAwF;AACxF,MAAM,UAAU,iBAAiB,CAAC,EAChC,YAAY,EACZ,aAAa,EACb,MAAM,EACN,KAAK,GACkE;IACvE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,oBAAoB,CAAqB;QAC7E,YAAY;QACZ,QAAQ,EAAE,CAAC,SAAS,EAAE,EAAE;YACtB,IAAI,SAAS,KAAK,SAAS;gBAAE,aAAa,EAAE,CAAC,SAAS,CAAC,CAAC;QAC1D,CAAC;QACD,KAAK;KACN,CAAC,CAAC;IACH,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAqB,SAAS,CAAC,CAAC;IACtF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAA6B,EAAE,CAAC,CAAC;IAEvE,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,GAAoB,EAAE,EAAE;QAC7D,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAClB,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK,CAAC;YAChD,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACnE,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,CAAC,CACtB,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,MAAM,aAAa,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,aAAqB,EAAE,EAAE;QAChE,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC;IACjF,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO;QACtC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC9D,IAAI,eAAe;YAAE,cAAc,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC;IAExC,OAAO,KAAK,CAAC,OAAO,CAClB,GAAG,EAAE,CAAC,CAAC;QACL,WAAW;QACX,YAAY;QACZ,UAAU,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC;QAChF,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC;QAC5E,WAAW;QACX,cAAc,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC;QAChE,eAAe;QACf,IAAI;QACJ,aAAa;KACd,CAAC,EACF,CAAC,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,CACtF,CAAC;AACJ,CAAC","sourcesContent":["import React from 'react';\n\nimport { useControllableState } from '../../../internal/useControllableState';\nimport type { TabRegistration, TabsContextValue, TabsProps } from '../../../types/tabs';\nimport { resolveTabElementId } from '../utils/resolveTabElementId';\n\n/*** Owns controlled state, registration, focus state, and ids for one Tabs instance. */\nexport function useTabsController({\n defaultValue,\n onValueChange,\n testID,\n value,\n}: Pick<TabsProps, 'defaultValue' | 'onValueChange' | 'testID' | 'value'>): TabsContextValue {\n const [activeValue, setActiveValue] = useControllableState<string | undefined>({\n defaultValue,\n onChange: (nextValue) => {\n if (nextValue !== undefined) onValueChange?.(nextValue);\n },\n value,\n });\n const [focusedValue, setFocusedValue] = React.useState<string | undefined>(undefined);\n const [tabs, setTabs] = React.useState<readonly TabRegistration[]>([]);\n\n const registerTab = React.useCallback((tab: TabRegistration) => {\n setTabs((current) =>\n current.some((entry) => entry.value === tab.value)\n ? current.map((entry) => (entry.value === tab.value ? tab : entry))\n : [...current, tab],\n );\n }, []);\n const unregisterTab = React.useCallback((valueToRemove: string) => {\n setTabs((current) => current.filter((entry) => entry.value !== valueToRemove));\n }, []);\n\n React.useEffect(() => {\n if (activeValue !== undefined) return;\n const firstEnabledTab = tabs.find((entry) => !entry.disabled);\n if (firstEnabledTab) setActiveValue(firstEnabledTab.value);\n }, [activeValue, setActiveValue, tabs]);\n\n return React.useMemo(\n () => ({\n activeValue,\n focusedValue,\n getPanelId: (tabValue: string) => resolveTabElementId('panel', testID, tabValue),\n getTabId: (tabValue: string) => resolveTabElementId('tab', testID, tabValue),\n registerTab,\n setActiveValue: (nextValue: string) => setActiveValue(nextValue),\n setFocusedValue,\n tabs,\n unregisterTab,\n }),\n [activeValue, focusedValue, registerTab, setActiveValue, tabs, testID, unregisterTab],\n );\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { TabListProps, TabPanelProps, TabProps, TabsProps } from '../../types/tabs';
|
|
2
|
+
export { Tab } from './adapters/inbound/Tab';
|
|
3
|
+
export { TabList } from './adapters/inbound/TabList';
|
|
4
|
+
export { TabPanel } from './adapters/inbound/TabPanel';
|
|
5
|
+
export { Tabs } from './adapters/inbound/Tabs';
|
|
6
|
+
//# sourceMappingURL=public.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/tabs/public.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/tabs/public.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC","sourcesContent":["export type { TabListProps, TabPanelProps, TabProps, TabsProps } from '../../types/tabs';\nexport { Tab } from './adapters/inbound/Tab';\nexport { TabList } from './adapters/inbound/TabList';\nexport { TabPanel } from './adapters/inbound/TabPanel';\nexport { Tabs } from './adapters/inbound/Tabs';\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TabNavigationKey, TabRegistration } from '../../../types/tabs';
|
|
2
|
+
/*** Resolves the next enabled tab for keyboard focus navigation. */
|
|
3
|
+
export declare function resolveNextTabValue(tabs: readonly TabRegistration[], currentValue: string | undefined, key: TabNavigationKey): string | undefined;
|
|
4
|
+
//# sourceMappingURL=resolveNextTabValue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveNextTabValue.d.ts","sourceRoot":"","sources":["../../../../src/features/tabs/utils/resolveNextTabValue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE7E,oEAAoE;AACpE,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,eAAe,EAAE,EAChC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,GAAG,EAAE,gBAAgB,GACpB,MAAM,GAAG,SAAS,CAgBpB"}
|
|
@@ -1,21 +1,18 @@
|
|
|
1
|
+
/*** Resolves the next enabled tab for keyboard focus navigation. */
|
|
1
2
|
export function resolveNextTabValue(tabs, currentValue, key) {
|
|
2
3
|
const enabledTabs = tabs.filter((tab) => !tab.disabled);
|
|
3
|
-
if (enabledTabs.length === 0)
|
|
4
|
+
if (enabledTabs.length === 0)
|
|
4
5
|
return undefined;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (key === 'End') {
|
|
10
|
-
return enabledTabs[enabledTabs.length - 1]?.value;
|
|
11
|
-
}
|
|
6
|
+
if (key === 'Home')
|
|
7
|
+
return enabledTabs.at(0)?.value;
|
|
8
|
+
if (key === 'End')
|
|
9
|
+
return enabledTabs.at(-1)?.value;
|
|
12
10
|
const currentIndex = enabledTabs.findIndex((tab) => tab.value === currentValue);
|
|
13
|
-
if (currentIndex === -1)
|
|
14
|
-
return enabledTabs
|
|
15
|
-
}
|
|
11
|
+
if (currentIndex === -1)
|
|
12
|
+
return enabledTabs.at(0)?.value;
|
|
16
13
|
const nextIndex = key === 'ArrowLeft' || key === 'ArrowUp'
|
|
17
14
|
? (currentIndex - 1 + enabledTabs.length) % enabledTabs.length
|
|
18
15
|
: (currentIndex + 1) % enabledTabs.length;
|
|
19
|
-
return enabledTabs
|
|
16
|
+
return enabledTabs.at(nextIndex)?.value;
|
|
20
17
|
}
|
|
21
|
-
//# sourceMappingURL=
|
|
18
|
+
//# sourceMappingURL=resolveNextTabValue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveNextTabValue.js","sourceRoot":"","sources":["../../../../src/features/tabs/utils/resolveNextTabValue.ts"],"names":[],"mappings":"AAEA,oEAAoE;AACpE,MAAM,UAAU,mBAAmB,CACjC,IAAgC,EAChC,YAAgC,EAChC,GAAqB;IAErB,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAE/C,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;IACpD,IAAI,GAAG,KAAK,KAAK;QAAE,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;IAEpD,MAAM,YAAY,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC;IAChF,IAAI,YAAY,KAAK,CAAC,CAAC;QAAE,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;IAEzD,MAAM,SAAS,GACb,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,SAAS;QACtC,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM;QAC9D,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC;IAE9C,OAAO,WAAW,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC;AAC1C,CAAC","sourcesContent":["import type { TabNavigationKey, TabRegistration } from '../../../types/tabs';\n\n/*** Resolves the next enabled tab for keyboard focus navigation. */\nexport function resolveNextTabValue(\n tabs: readonly TabRegistration[],\n currentValue: string | undefined,\n key: TabNavigationKey,\n): string | undefined {\n const enabledTabs = tabs.filter((tab) => !tab.disabled);\n if (enabledTabs.length === 0) return undefined;\n\n if (key === 'Home') return enabledTabs.at(0)?.value;\n if (key === 'End') return enabledTabs.at(-1)?.value;\n\n const currentIndex = enabledTabs.findIndex((tab) => tab.value === currentValue);\n if (currentIndex === -1) return enabledTabs.at(0)?.value;\n\n const nextIndex =\n key === 'ArrowLeft' || key === 'ArrowUp'\n ? (currentIndex - 1 + enabledTabs.length) % enabledTabs.length\n : (currentIndex + 1) % enabledTabs.length;\n\n return enabledTabs.at(nextIndex)?.value;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveTabElementId.d.ts","sourceRoot":"","sources":["../../../../src/features/tabs/utils/resolveTabElementId.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,KAAK,GAAG,OAAO,EACrB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,KAAK,EAAE,MAAM,GACZ,MAAM,CAGR"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/*** Creates a stable tab or tab-panel id from a Tabs test id and tab value. */
|
|
2
|
+
export function resolveTabElementId(kind, testID, value) {
|
|
3
|
+
const base = testID ? `${testID}-tabs` : 'tabs';
|
|
4
|
+
return `${base}-${kind}-${sanitizeTabValue(value)}`;
|
|
5
|
+
}
|
|
6
|
+
/*** Normalizes a tab value for use inside an accessibility id. */
|
|
7
|
+
function sanitizeTabValue(value) {
|
|
8
|
+
return value.trim().replace(/[^a-zA-Z0-9_-]+/g, '-');
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=resolveTabElementId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveTabElementId.js","sourceRoot":"","sources":["../../../../src/features/tabs/utils/resolveTabElementId.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,UAAU,mBAAmB,CACjC,IAAqB,EACrB,MAA0B,EAC1B,KAAa;IAEb,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAChD,OAAO,GAAG,IAAI,IAAI,IAAI,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;AACtD,CAAC;AAED,kEAAkE;AAClE,SAAS,gBAAgB,CAAC,KAAa;IACrC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;AACvD,CAAC","sourcesContent":["/*** Creates a stable tab or tab-panel id from a Tabs test id and tab value. */\nexport function resolveTabElementId(\n kind: 'tab' | 'panel',\n testID: string | undefined,\n value: string,\n): string {\n const base = testID ? `${testID}-tabs` : 'tabs';\n return `${base}-${kind}-${sanitizeTabValue(value)}`;\n}\n\n/*** Normalizes a tab value for use inside an accessibility id. */\nfunction sanitizeTabValue(value: string): string {\n return value.trim().replace(/[^a-zA-Z0-9_-]+/g, '-');\n}\n"]}
|