@ankhorage/surface 3.4.6 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +1 -6
  3. package/dist/examples/DocsExamples.d.ts.map +1 -1
  4. package/dist/examples/DocsExamples.js +0 -6
  5. package/dist/examples/DocsExamples.js.map +1 -1
  6. package/dist/features/bottom-sheet/BottomSheetContext.d.ts +4 -0
  7. package/dist/features/bottom-sheet/BottomSheetContext.d.ts.map +1 -0
  8. package/dist/features/bottom-sheet/BottomSheetContext.js +3 -0
  9. package/dist/features/bottom-sheet/BottomSheetContext.js.map +1 -0
  10. package/dist/features/bottom-sheet/BottomSheetProvider.d.ts +6 -0
  11. package/dist/features/bottom-sheet/BottomSheetProvider.d.ts.map +1 -0
  12. package/dist/features/bottom-sheet/BottomSheetProvider.js +61 -0
  13. package/dist/features/bottom-sheet/BottomSheetProvider.js.map +1 -0
  14. package/dist/features/bottom-sheet/public.d.ts +4 -0
  15. package/dist/features/bottom-sheet/public.d.ts.map +1 -0
  16. package/dist/features/bottom-sheet/public.js +3 -0
  17. package/dist/features/bottom-sheet/public.js.map +1 -0
  18. package/dist/features/bottom-sheet/useBottomSheet.d.ts +4 -0
  19. package/dist/features/bottom-sheet/useBottomSheet.d.ts.map +1 -0
  20. package/dist/features/bottom-sheet/useBottomSheet.js +11 -0
  21. package/dist/features/bottom-sheet/useBottomSheet.js.map +1 -0
  22. package/dist/index.d.ts +0 -6
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +0 -3
  25. package/dist/index.js.map +1 -1
  26. package/dist/types/bottomSheet.d.ts +18 -0
  27. package/dist/types/bottomSheet.d.ts.map +1 -0
  28. package/dist/types/bottomSheet.js +2 -0
  29. package/dist/types/bottomSheet.js.map +1 -0
  30. package/package.json +17 -3
  31. package/src/examples/DocsExamples.tsx +0 -6
  32. package/src/features/bottom-sheet/BottomSheetContext.ts +5 -0
  33. package/src/features/bottom-sheet/BottomSheetProvider.tsx +129 -0
  34. package/src/features/bottom-sheet/public.ts +3 -0
  35. package/src/features/bottom-sheet/useBottomSheet.test.tsx +18 -0
  36. package/src/features/bottom-sheet/useBottomSheet.ts +15 -0
  37. package/src/index.test.ts +40 -12
  38. package/src/index.ts +0 -22
  39. package/src/types/bottomSheet.ts +19 -0
  40. package/dist/components/action-sheet/ActionSheet.d.ts +0 -4
  41. package/dist/components/action-sheet/ActionSheet.d.ts.map +0 -1
  42. package/dist/components/action-sheet/ActionSheet.js +0 -77
  43. package/dist/components/action-sheet/ActionSheet.js.map +0 -1
  44. package/dist/components/action-sheet/ActionSheetItem.d.ts +0 -4
  45. package/dist/components/action-sheet/ActionSheetItem.d.ts.map +0 -1
  46. package/dist/components/action-sheet/ActionSheetItem.js +0 -27
  47. package/dist/components/action-sheet/ActionSheetItem.js.map +0 -1
  48. package/dist/components/action-sheet/index.d.ts +0 -4
  49. package/dist/components/action-sheet/index.d.ts.map +0 -1
  50. package/dist/components/action-sheet/index.js +0 -3
  51. package/dist/components/action-sheet/index.js.map +0 -1
  52. package/dist/components/action-sheet/types.d.ts +0 -27
  53. package/dist/components/action-sheet/types.d.ts.map +0 -1
  54. package/dist/components/action-sheet/types.js +0 -2
  55. package/dist/components/action-sheet/types.js.map +0 -1
  56. package/dist/components/drawer/Drawer.d.ts +0 -4
  57. package/dist/components/drawer/Drawer.d.ts.map +0 -1
  58. package/dist/components/drawer/Drawer.js +0 -62
  59. package/dist/components/drawer/Drawer.js.map +0 -1
  60. package/dist/components/drawer/index.d.ts +0 -3
  61. package/dist/components/drawer/index.d.ts.map +0 -1
  62. package/dist/components/drawer/index.js +0 -2
  63. package/dist/components/drawer/index.js.map +0 -1
  64. package/dist/components/drawer/types.d.ts +0 -12
  65. package/dist/components/drawer/types.d.ts.map +0 -1
  66. package/dist/components/drawer/types.js +0 -2
  67. package/dist/components/drawer/types.js.map +0 -1
  68. package/dist/components/navigation/DrawerNavigation.d.ts +0 -4
  69. package/dist/components/navigation/DrawerNavigation.d.ts.map +0 -1
  70. package/dist/components/navigation/DrawerNavigation.js +0 -13
  71. package/dist/components/navigation/DrawerNavigation.js.map +0 -1
  72. package/dist/components/navigation/DrawerNavigationItem.d.ts +0 -4
  73. package/dist/components/navigation/DrawerNavigationItem.d.ts.map +0 -1
  74. package/dist/components/navigation/DrawerNavigationItem.js +0 -9
  75. package/dist/components/navigation/DrawerNavigationItem.js.map +0 -1
  76. package/dist/components/navigation/NavigationItem.d.ts +0 -4
  77. package/dist/components/navigation/NavigationItem.d.ts.map +0 -1
  78. package/dist/components/navigation/NavigationItem.js +0 -41
  79. package/dist/components/navigation/NavigationItem.js.map +0 -1
  80. package/dist/components/navigation/NavigationList.d.ts +0 -4
  81. package/dist/components/navigation/NavigationList.d.ts.map +0 -1
  82. package/dist/components/navigation/NavigationList.js +0 -9
  83. package/dist/components/navigation/NavigationList.js.map +0 -1
  84. package/dist/components/navigation/TabBar.d.ts +0 -4
  85. package/dist/components/navigation/TabBar.d.ts.map +0 -1
  86. package/dist/components/navigation/TabBar.js +0 -15
  87. package/dist/components/navigation/TabBar.js.map +0 -1
  88. package/dist/components/navigation/TabBarItem.d.ts +0 -4
  89. package/dist/components/navigation/TabBarItem.d.ts.map +0 -1
  90. package/dist/components/navigation/TabBarItem.js +0 -44
  91. package/dist/components/navigation/TabBarItem.js.map +0 -1
  92. package/dist/components/navigation/helpers.d.ts +0 -15
  93. package/dist/components/navigation/helpers.d.ts.map +0 -1
  94. package/dist/components/navigation/helpers.js +0 -48
  95. package/dist/components/navigation/helpers.js.map +0 -1
  96. package/dist/components/navigation/index.d.ts +0 -8
  97. package/dist/components/navigation/index.d.ts.map +0 -1
  98. package/dist/components/navigation/index.js +0 -7
  99. package/dist/components/navigation/index.js.map +0 -1
  100. package/dist/components/navigation/types.d.ts +0 -58
  101. package/dist/components/navigation/types.d.ts.map +0 -1
  102. package/dist/components/navigation/types.js +0 -2
  103. package/dist/components/navigation/types.js.map +0 -1
  104. package/src/components/action-sheet/ActionSheet.tsx +0 -130
  105. package/src/components/action-sheet/ActionSheetItem.tsx +0 -59
  106. package/src/components/action-sheet/index.ts +0 -3
  107. package/src/components/action-sheet/types.ts +0 -29
  108. package/src/components/drawer/Drawer.tsx +0 -100
  109. package/src/components/drawer/index.ts +0 -2
  110. package/src/components/drawer/types.ts +0 -13
  111. package/src/components/navigation/DrawerNavigation.tsx +0 -32
  112. package/src/components/navigation/DrawerNavigationItem.tsx +0 -23
  113. package/src/components/navigation/NavigationItem.tsx +0 -79
  114. package/src/components/navigation/NavigationList.tsx +0 -31
  115. package/src/components/navigation/TabBar.tsx +0 -31
  116. package/src/components/navigation/TabBarItem.tsx +0 -79
  117. package/src/components/navigation/helpers.test.ts +0 -74
  118. package/src/components/navigation/helpers.ts +0 -81
  119. package/src/components/navigation/index.ts +0 -16
  120. package/src/components/navigation/policy.test.ts +0 -140
  121. package/src/components/navigation/types.ts +0 -66
@@ -1,59 +0,0 @@
1
- import React from 'react';
2
-
3
- import { Box, Inline, Stack } from '../../layout';
4
- import { ButtonBase } from '../../primitives/button-base';
5
- import { Text } from '../../primitives/text';
6
- import type { ActionSheetItemProps } from './types';
7
-
8
- export function ActionSheetItem({
9
- label,
10
- description,
11
- leading,
12
- trailing,
13
- color,
14
- disabled = false,
15
- selected = false,
16
- interactionPolicy = 'enabled',
17
- onPress,
18
- testID,
19
- }: ActionSheetItemProps) {
20
- return (
21
- <ButtonBase
22
- accessibilityRole="button"
23
- accessibilityState={{ disabled, selected }}
24
- disabled={disabled}
25
- interactionPolicy={interactionPolicy}
26
- onPress={onPress}
27
- radius="m"
28
- testID={testID}
29
- >
30
- {(state) => (
31
- <Box
32
- px="m"
33
- py="m"
34
- radius="m"
35
- style={{
36
- opacity: state.disabled ? 0.56 : 1,
37
- }}
38
- >
39
- <Inline align="center" gap="m" justify="space-between" wrap="nowrap">
40
- {leading ? <Box>{leading}</Box> : null}
41
- <Box flex={1}>
42
- <Stack gap="xxs">
43
- <Text color={color} variant="body" weight={selected ? 'semiBold' : 'medium'}>
44
- {label}
45
- </Text>
46
- {description ? (
47
- <Text emphasis="muted" variant="bodySmall">
48
- {description}
49
- </Text>
50
- ) : null}
51
- </Stack>
52
- </Box>
53
- {trailing ? <Box>{trailing}</Box> : null}
54
- </Inline>
55
- </Box>
56
- )}
57
- </ButtonBase>
58
- );
59
- }
@@ -1,3 +0,0 @@
1
- export { ActionSheet } from './ActionSheet';
2
- export { ActionSheetItem } from './ActionSheetItem';
3
- export type { ActionSheetItemProps, ActionSheetProps } from './types';
@@ -1,29 +0,0 @@
1
- import type React from 'react';
2
-
3
- import type { InteractionPolicy } from '../../interactionPolicy';
4
- import type { SurfaceColor } from '../../surfaceColor';
5
-
6
- export interface ActionSheetProps {
7
- visible: boolean;
8
- onDismiss?: (() => void) | undefined;
9
- title?: React.ReactNode;
10
- description?: React.ReactNode;
11
- children?: React.ReactNode;
12
- cancelLabel?: React.ReactNode;
13
- closeOnBackdrop?: boolean;
14
- interactionPolicy?: InteractionPolicy;
15
- testID?: string;
16
- }
17
-
18
- export interface ActionSheetItemProps {
19
- label: React.ReactNode;
20
- description?: React.ReactNode;
21
- leading?: React.ReactNode;
22
- trailing?: React.ReactNode;
23
- color?: SurfaceColor;
24
- disabled?: boolean;
25
- selected?: boolean;
26
- interactionPolicy?: InteractionPolicy;
27
- onPress?: (() => void) | undefined;
28
- testID?: string;
29
- }
@@ -1,100 +0,0 @@
1
- import React from 'react';
2
- import { Pressable, View } from 'react-native';
3
-
4
- import { FocusScope } from '../../internal/focus/FocusScope';
5
- import { Portal } from '../../internal/overlay/Portal';
6
- import { resolvePointerEvents } from '../../internal/resolvePointerEvents';
7
- import { resolveOverlayAnimation } from '../../internal/resolvers';
8
- import { Box, Surface } from '../../layout';
9
- import { useTheme } from '../../theme/ThemeContext';
10
- import type { DrawerProps } from './types';
11
-
12
- const boxNonePointerEvents = resolvePointerEvents('box-none');
13
-
14
- export function Drawer({
15
- visible,
16
- onDismiss,
17
- position = 'right',
18
- children,
19
- closeOnBackdrop = true,
20
- interactionPolicy = 'enabled',
21
- testID,
22
- }: DrawerProps) {
23
- const { theme } = useTheme();
24
- const animation = resolveOverlayAnimation('drawer');
25
- const passive = interactionPolicy === 'passive';
26
-
27
- if (!visible) {
28
- return null;
29
- }
30
-
31
- return (
32
- <Portal layer="drawer" visible={visible}>
33
- <View
34
- {...boxNonePointerEvents.props}
35
- style={[
36
- boxNonePointerEvents.style,
37
- {
38
- bottom: 0,
39
- left: 0,
40
- position: 'absolute',
41
- right: 0,
42
- top: 0,
43
- },
44
- ]}
45
- >
46
- <Pressable
47
- onPress={passive ? undefined : closeOnBackdrop ? onDismiss : undefined}
48
- style={{
49
- backgroundColor: theme.semantics.neutral.text,
50
- bottom: 0,
51
- left: 0,
52
- opacity: animation.backdropOpacity,
53
- position: 'absolute',
54
- right: 0,
55
- top: 0,
56
- }}
57
- testID={testID ? `${testID}-backdrop` : undefined}
58
- />
59
- <FocusScope
60
- active={visible}
61
- onEscape={passive ? undefined : onDismiss}
62
- testID={testID ? `${testID}-focus` : undefined}
63
- >
64
- <Box
65
- pointerEvents="box-none"
66
- style={{
67
- flex: 1,
68
- justifyContent: 'flex-start',
69
- }}
70
- >
71
- <View
72
- accessible
73
- accessibilityViewIsModal
74
- style={{
75
- alignSelf: position === 'left' ? 'flex-start' : 'flex-end',
76
- height: '100%',
77
- maxWidth: 420,
78
- width: '88%',
79
- }}
80
- >
81
- <Surface
82
- p="l"
83
- style={{
84
- height: '100%',
85
- shadowOpacity: 0.14,
86
- shadowRadius: 14,
87
- shadowOffset: { width: position === 'left' ? 4 : -4, height: 0 },
88
- }}
89
- testID={testID}
90
- variant="raised"
91
- >
92
- {children}
93
- </Surface>
94
- </View>
95
- </Box>
96
- </FocusScope>
97
- </View>
98
- </Portal>
99
- );
100
- }
@@ -1,2 +0,0 @@
1
- export { Drawer } from './Drawer';
2
- export type { DrawerProps } from './types';
@@ -1,13 +0,0 @@
1
- import type React from 'react';
2
-
3
- import type { InteractionPolicy } from '../../interactionPolicy';
4
-
5
- export interface DrawerProps {
6
- visible: boolean;
7
- onDismiss?: (() => void) | undefined;
8
- position?: 'left' | 'right';
9
- children?: React.ReactNode;
10
- closeOnBackdrop?: boolean;
11
- interactionPolicy?: InteractionPolicy;
12
- testID?: string;
13
- }
@@ -1,32 +0,0 @@
1
- import React from 'react';
2
-
3
- import { Stack } from '../../layout';
4
- import { DrawerNavigationItem } from './DrawerNavigationItem';
5
- import type { DrawerNavigationProps } from './types';
6
-
7
- export function DrawerNavigation({
8
- items,
9
- header,
10
- footer,
11
- compact = false,
12
- testID,
13
- interactionPolicy,
14
- }: DrawerNavigationProps) {
15
- return (
16
- <Stack gap={compact ? 's' : 'm'} testID={testID}>
17
- {header}
18
- <Stack gap={compact ? 'xs' : 's'}>
19
- {items.map((item) => (
20
- <DrawerNavigationItem
21
- compact={compact}
22
- interactionPolicy={interactionPolicy}
23
- item={item}
24
- key={item.id}
25
- testID={testID}
26
- />
27
- ))}
28
- </Stack>
29
- {footer}
30
- </Stack>
31
- );
32
- }
@@ -1,23 +0,0 @@
1
- import React from 'react';
2
-
3
- import { NavigationItem } from './NavigationItem';
4
- import type { DrawerNavigationItemProps } from './types';
5
-
6
- export function DrawerNavigationItem({
7
- item,
8
- compact = false,
9
- testID,
10
- interactionPolicy,
11
- }: DrawerNavigationItemProps) {
12
- return (
13
- <NavigationItem
14
- compact={compact}
15
- interactionPolicy={interactionPolicy}
16
- item={{
17
- ...item,
18
- accessibilityRole: item.accessibilityRole ?? 'button',
19
- }}
20
- testID={testID}
21
- />
22
- );
23
- }
@@ -1,79 +0,0 @@
1
- import React from 'react';
2
- import { View } from 'react-native';
3
-
4
- import { Box } from '../../layout';
5
- import { ButtonBase } from '../../primitives/button-base';
6
- import { Icon } from '../../primitives/icon';
7
- import { Text } from '../../primitives/text';
8
- import { useTheme } from '../../theme/ThemeContext';
9
- import { resolveNavigationAccessibilityState, resolveNavigationItemPresentation } from './helpers';
10
- import type { NavigationItemProps } from './types';
11
-
12
- export function NavigationItem({
13
- item,
14
- compact = false,
15
- testID,
16
- interactionPolicy,
17
- }: NavigationItemProps) {
18
- const { theme } = useTheme();
19
- const active = Boolean(item.active);
20
- const disabled = Boolean(item.disabled);
21
- const resolvedTestID = item.testID ?? (testID ? `${testID}-item-${item.id}` : undefined);
22
- const resolvedAccessibilityState = resolveNavigationAccessibilityState(
23
- active,
24
- disabled,
25
- item.accessibilityState,
26
- );
27
-
28
- return (
29
- <ButtonBase
30
- accessibilityLabel={item.accessibilityLabel}
31
- accessibilityRole={item.accessibilityRole ?? 'button'}
32
- accessibilityState={resolvedAccessibilityState}
33
- disabled={disabled}
34
- interactionPolicy={interactionPolicy}
35
- onPress={item.onPress}
36
- testID={resolvedTestID}
37
- >
38
- {(state) => {
39
- const presentation = resolveNavigationItemPresentation(theme, {
40
- active,
41
- disabled,
42
- state,
43
- });
44
-
45
- return (
46
- <Box
47
- px="m"
48
- py={compact ? 's' : 'm'}
49
- radius="m"
50
- style={{
51
- backgroundColor: presentation.backgroundColor,
52
- flexDirection: 'row',
53
- alignItems: 'center',
54
- opacity: presentation.opacity,
55
- }}
56
- >
57
- {item.icon ? (
58
- <View style={{ marginRight: theme.spacing.s }}>
59
- <Icon {...item.icon} color={presentation.contentColor} size={compact ? 's' : 'm'} />
60
- </View>
61
- ) : null}
62
- <Box flex={1}>
63
- <Text
64
- color={active && !disabled ? 'primary' : undefined}
65
- emphasis={disabled ? 'muted' : 'default'}
66
- numberOfLines={1}
67
- variant={compact ? 'bodySmall' : 'body'}
68
- weight="medium"
69
- >
70
- {item.label}
71
- </Text>
72
- </Box>
73
- {item.badge ? <View style={{ marginLeft: theme.spacing.s }}>{item.badge}</View> : null}
74
- </Box>
75
- );
76
- }}
77
- </ButtonBase>
78
- );
79
- }
@@ -1,31 +0,0 @@
1
- import React from 'react';
2
-
3
- import { Stack } from '../../layout';
4
- import { NavigationItem } from './NavigationItem';
5
- import type { NavigationListProps } from './types';
6
-
7
- export function NavigationList({
8
- items,
9
- orientation = 'vertical',
10
- compact = false,
11
- testID,
12
- interactionPolicy,
13
- }: NavigationListProps) {
14
- return (
15
- <Stack
16
- direction={orientation === 'horizontal' ? 'row' : 'column'}
17
- gap={compact ? 'xs' : 's'}
18
- testID={testID}
19
- >
20
- {items.map((item) => (
21
- <NavigationItem
22
- compact={compact}
23
- interactionPolicy={interactionPolicy}
24
- item={item}
25
- key={item.id}
26
- testID={testID}
27
- />
28
- ))}
29
- </Stack>
30
- );
31
- }
@@ -1,31 +0,0 @@
1
- import React from 'react';
2
-
3
- import { Box } from '../../layout';
4
- import { useTheme } from '../../theme/ThemeContext';
5
- import { TabBarItem } from './TabBarItem';
6
- import type { TabBarProps } from './types';
7
-
8
- export function TabBar({ items, compact = false, testID, interactionPolicy }: TabBarProps) {
9
- const { theme } = useTheme();
10
-
11
- return (
12
- <Box
13
- style={{
14
- flexDirection: 'row',
15
- borderTopColor: theme.semantics.border.default,
16
- borderTopWidth: 1,
17
- }}
18
- testID={testID}
19
- >
20
- {items.map((item) => (
21
- <TabBarItem
22
- compact={compact}
23
- interactionPolicy={interactionPolicy}
24
- item={item}
25
- key={item.id}
26
- testID={testID}
27
- />
28
- ))}
29
- </Box>
30
- );
31
- }
@@ -1,79 +0,0 @@
1
- import React from 'react';
2
- import { View } from 'react-native';
3
-
4
- import { Box } from '../../layout';
5
- import { ButtonBase } from '../../primitives/button-base';
6
- import { Icon } from '../../primitives/icon';
7
- import { Text } from '../../primitives/text';
8
- import { useTheme } from '../../theme/ThemeContext';
9
- import { resolveNavigationAccessibilityState, resolveNavigationItemPresentation } from './helpers';
10
- import type { TabBarItemProps } from './types';
11
-
12
- export function TabBarItem({ item, compact = false, testID, interactionPolicy }: TabBarItemProps) {
13
- const { theme } = useTheme();
14
- const active = Boolean(item.active);
15
- const disabled = Boolean(item.disabled);
16
- const resolvedTestID = item.testID ?? (testID ? `${testID}-item-${item.id}` : undefined);
17
- const resolvedAccessibilityState = resolveNavigationAccessibilityState(
18
- active,
19
- disabled,
20
- item.accessibilityState,
21
- );
22
-
23
- return (
24
- <ButtonBase
25
- accessibilityLabel={item.accessibilityLabel}
26
- accessibilityRole={item.accessibilityRole ?? 'tab'}
27
- accessibilityState={resolvedAccessibilityState}
28
- disabled={disabled}
29
- interactionPolicy={interactionPolicy}
30
- onPress={item.onPress}
31
- style={{ flex: 1 }}
32
- testID={resolvedTestID}
33
- >
34
- {(state) => {
35
- const presentation = resolveNavigationItemPresentation(theme, {
36
- active,
37
- disabled,
38
- state,
39
- });
40
- const contentColor = disabled
41
- ? theme.semantics.content.muted
42
- : active
43
- ? theme.semantics.action.primary.base
44
- : theme.semantics.content.muted;
45
-
46
- return (
47
- <Box
48
- px="m"
49
- py={compact ? 's' : 'm'}
50
- style={{
51
- flex: 1,
52
- alignItems: 'center',
53
- justifyContent: 'center',
54
- backgroundColor: presentation.backgroundColor,
55
- opacity: presentation.opacity,
56
- }}
57
- >
58
- {item.icon ? (
59
- <View style={{ marginBottom: item.label ? theme.spacing.xs : 0 }}>
60
- <Icon {...item.icon} color={contentColor} size={compact ? 's' : 'm'} />
61
- </View>
62
- ) : null}
63
- {item.label ? (
64
- <Text
65
- color={active && !disabled ? 'primary' : undefined}
66
- emphasis={active && !disabled ? 'default' : 'muted'}
67
- numberOfLines={1}
68
- variant={compact ? 'bodySmall' : 'label'}
69
- weight="medium"
70
- >
71
- {item.label}
72
- </Text>
73
- ) : null}
74
- </Box>
75
- );
76
- }}
77
- </ButtonBase>
78
- );
79
- }
@@ -1,74 +0,0 @@
1
- import { describe, expect, it } from 'bun:test';
2
-
3
- import { createTheme } from '../../theme/createTheme';
4
- import { resolveNavigationAccessibilityState, resolveNavigationItemPresentation } from './helpers';
5
-
6
- describe('navigation helpers', () => {
7
- it('forces selected and disabled when active/disabled are true', () => {
8
- expect(
9
- resolveNavigationAccessibilityState(true, true, {
10
- selected: false,
11
- disabled: false,
12
- }),
13
- ).toEqual({
14
- selected: true,
15
- disabled: true,
16
- });
17
- });
18
-
19
- it('preserves user-provided state when not active/disabled', () => {
20
- expect(
21
- resolveNavigationAccessibilityState(false, false, {
22
- disabled: false,
23
- selected: false,
24
- expanded: true,
25
- }),
26
- ).toEqual({
27
- disabled: false,
28
- selected: false,
29
- expanded: true,
30
- });
31
- });
32
-
33
- it('resolves active presentation via primary soft semantics', () => {
34
- const theme = createTheme();
35
- const state = { pressed: false, hovered: true, focused: false, disabled: false };
36
- const resolved = resolveNavigationItemPresentation(theme, {
37
- active: true,
38
- disabled: false,
39
- state,
40
- });
41
-
42
- expect(resolved.backgroundColor).toBe(theme.semantics.action.primary.softHover);
43
- expect(resolved.contentColor).toBe(theme.semantics.action.primary.onSoftHoverText);
44
- expect(resolved.opacity).toBe(1);
45
- });
46
-
47
- it('resolves inactive presentation via neutral hover/active semantics', () => {
48
- const theme = createTheme();
49
- const state = { pressed: true, hovered: true, focused: false, disabled: false };
50
- const resolved = resolveNavigationItemPresentation(theme, {
51
- active: false,
52
- disabled: false,
53
- state,
54
- });
55
-
56
- expect(resolved.backgroundColor).toBe(theme.semantics.neutral.surfaceActive);
57
- expect(resolved.contentColor).toBe(theme.semantics.content.default);
58
- expect(resolved.opacity).toBe(1);
59
- });
60
-
61
- it('ignores hover/pressed presentation when disabled', () => {
62
- const theme = createTheme();
63
- const state = { pressed: true, hovered: true, focused: false, disabled: true };
64
- const resolved = resolveNavigationItemPresentation(theme, {
65
- active: true,
66
- disabled: true,
67
- state,
68
- });
69
-
70
- expect(resolved.backgroundColor).toBe(theme.semantics.surface.disabled);
71
- expect(resolved.contentColor).toBe(theme.semantics.content.disabled);
72
- expect(resolved.opacity).toBe(1);
73
- });
74
- });
@@ -1,81 +0,0 @@
1
- import type { AccessibilityState } from 'react-native';
2
-
3
- import type { InteractionState } from '../../internal/resolvers/resolveInteractiveState';
4
- import type { SurfaceTheme } from '../../theme/types';
5
-
6
- export function resolveNavigationAccessibilityState(
7
- active: boolean,
8
- disabled: boolean,
9
- accessibilityState?: AccessibilityState,
10
- ): AccessibilityState {
11
- const resolved: AccessibilityState = { ...(accessibilityState ?? {}) };
12
-
13
- if (active) {
14
- resolved.selected = true;
15
- }
16
-
17
- if (disabled) {
18
- resolved.disabled = true;
19
- }
20
-
21
- return resolved;
22
- }
23
-
24
- export interface ResolvedNavigationItemPresentation {
25
- backgroundColor: string;
26
- contentColor: string;
27
- opacity: number;
28
- }
29
-
30
- export function resolveNavigationItemPresentation(
31
- theme: SurfaceTheme,
32
- {
33
- active,
34
- disabled,
35
- state,
36
- }: {
37
- active: boolean;
38
- disabled: boolean;
39
- state: InteractionState;
40
- },
41
- ): ResolvedNavigationItemPresentation {
42
- const interactionState = disabled ? { ...state, hovered: false, pressed: false } : state;
43
-
44
- if (disabled) {
45
- return {
46
- backgroundColor: theme.semantics.surface.disabled,
47
- contentColor: theme.semantics.content.disabled,
48
- opacity: 1,
49
- };
50
- }
51
-
52
- const contentColor = active
53
- ? interactionState.pressed
54
- ? theme.semantics.action.primary.onSoftActiveText
55
- : interactionState.hovered
56
- ? theme.semantics.action.primary.onSoftHoverText
57
- : theme.semantics.action.primary.onSoftText
58
- : theme.semantics.content.default;
59
-
60
- if (active) {
61
- return {
62
- backgroundColor: interactionState.pressed
63
- ? theme.semantics.action.primary.softActive
64
- : interactionState.hovered
65
- ? theme.semantics.action.primary.softHover
66
- : theme.semantics.action.primary.softBg,
67
- contentColor,
68
- opacity: 1,
69
- };
70
- }
71
-
72
- return {
73
- backgroundColor: interactionState.pressed
74
- ? theme.semantics.neutral.surfaceActive
75
- : interactionState.hovered
76
- ? theme.semantics.neutral.surfaceHover
77
- : 'transparent',
78
- contentColor,
79
- opacity: 1,
80
- };
81
- }
@@ -1,16 +0,0 @@
1
- export { DrawerNavigation } from './DrawerNavigation';
2
- export { DrawerNavigationItem } from './DrawerNavigationItem';
3
- export { NavigationItem } from './NavigationItem';
4
- export { NavigationList } from './NavigationList';
5
- export { TabBar } from './TabBar';
6
- export { TabBarItem } from './TabBarItem';
7
- export type {
8
- DrawerNavigationItemProps,
9
- DrawerNavigationProps,
10
- NavigationItemIcon,
11
- NavigationItemProps,
12
- NavigationItemSpec,
13
- NavigationListProps,
14
- TabBarItemProps,
15
- TabBarProps,
16
- } from './types';