@ankhorage/zora 1.5.0 → 1.5.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/dist/layout/screen/Screen.d.ts.map +1 -1
- package/dist/layout/screen/Screen.js +7 -3
- package/dist/layout/screen/Screen.js.map +1 -1
- package/dist/patterns/zora-tab-bar/ZoraTabBar.d.ts.map +1 -1
- package/dist/patterns/zora-tab-bar/ZoraTabBar.js +64 -15
- package/dist/patterns/zora-tab-bar/ZoraTabBar.js.map +1 -1
- package/package.json +1 -1
- package/src/layout/screen/Screen.tsx +11 -3
- package/src/patterns/zora-tab-bar/ZoraTabBar.tsx +104 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.5.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 07e9d96: Improve realistic example app chrome by adding compact AppBars with dark-mode toggles, applying semantic Screen backgrounds, and fixing native ZoraTabBar icon/label rendering.
|
|
8
|
+
|
|
3
9
|
## 1.5.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Screen.d.ts","sourceRoot":"","sources":["../../../src/layout/screen/Screen.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"Screen.d.ts","sourceRoot":"","sources":["../../../src/layout/screen/Screen.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAmC3C,eAAO,MAAM,MAAM,mDAAkC,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ScrollArea } from '@ankhorage/surface';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { Container, Stack } from '../../foundation';
|
|
3
|
+
import { Box, Container, Stack } from '../../foundation';
|
|
4
4
|
import { resolvePageMaxWidth } from '../../internal/recipes';
|
|
5
5
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
6
6
|
function ScreenInner({ themeId: _themeId, mode: _mode, children, footer, scroll = true, width = 'default', testID, }) {
|
|
@@ -11,9 +11,13 @@ function ScreenInner({ themeId: _themeId, mode: _mode, children, footer, scroll
|
|
|
11
11
|
</Stack>
|
|
12
12
|
</Container>);
|
|
13
13
|
if (!scroll) {
|
|
14
|
-
return
|
|
14
|
+
return (<Box bg="background" flex={1}>
|
|
15
|
+
{content}
|
|
16
|
+
</Box>);
|
|
15
17
|
}
|
|
16
|
-
return <ScrollArea
|
|
18
|
+
return (<ScrollArea bg="background" style={{ flex: 1 }}>
|
|
19
|
+
{content}
|
|
20
|
+
</ScrollArea>);
|
|
17
21
|
}
|
|
18
22
|
export const Screen = withZoraThemeScope(ScreenInner);
|
|
19
23
|
//# sourceMappingURL=Screen.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Screen.js","sourceRoot":"","sources":["../../../src/layout/screen/Screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"Screen.js","sourceRoot":"","sources":["../../../src/layout/screen/Screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,SAAS,WAAW,CAAC,EACnB,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,KAAK,EACX,QAAQ,EACR,MAAM,EACN,MAAM,GAAG,IAAI,EACb,KAAK,GAAG,SAAS,EACjB,MAAM,GACM;IACZ,MAAM,OAAO,GAAG,CACd,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CACtE;MAAA,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CACZ;QAAA,CAAC,QAAQ,CACT;QAAA,CAAC,MAAM,CACT;MAAA,EAAE,KAAK,CACT;IAAA,EAAE,SAAS,CAAC,CACb,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CACL,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAC3B;QAAA,CAAC,OAAO,CACV;MAAA,EAAE,GAAG,CAAC,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAC7C;MAAA,CAAC,OAAO,CACV;IAAA,EAAE,UAAU,CAAC,CACd,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC","sourcesContent":["import { ScrollArea } from '@ankhorage/surface';\nimport React from 'react';\n\nimport { Box, Container, Stack } from '../../foundation';\nimport { resolvePageMaxWidth } from '../../internal/recipes';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport type { ScreenProps } from './types';\n\nfunction ScreenInner({\n themeId: _themeId,\n mode: _mode,\n children,\n footer,\n scroll = true,\n width = 'default',\n testID,\n}: ScreenProps) {\n const content = (\n <Container maxWidth={resolvePageMaxWidth(width)} py=\"xl\" testID={testID}>\n <Stack gap=\"l\">\n {children}\n {footer}\n </Stack>\n </Container>\n );\n\n if (!scroll) {\n return (\n <Box bg=\"background\" flex={1}>\n {content}\n </Box>\n );\n }\n\n return (\n <ScrollArea bg=\"background\" style={{ flex: 1 }}>\n {content}\n </ScrollArea>\n );\n}\n\nexport const Screen = withZoraThemeScope(ScreenInner);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZoraTabBar.d.ts","sourceRoot":"","sources":["../../../src/patterns/zora-tab-bar/ZoraTabBar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ZoraTabBar.d.ts","sourceRoot":"","sources":["../../../src/patterns/zora-tab-bar/ZoraTabBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAW1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAoI/C,eAAO,MAAM,UAAU,uDAAsC,CAAC"}
|
|
@@ -1,27 +1,76 @@
|
|
|
1
|
-
import { TabBar as SurfaceTabBar } from '@ankhorage/surface';
|
|
2
1
|
import React from 'react';
|
|
3
|
-
import {
|
|
2
|
+
import { Pressable, Text as ReactNativeText } from 'react-native';
|
|
3
|
+
import { Icon } from '../../components/icon';
|
|
4
|
+
import { Box, Surface } from '../../foundation';
|
|
4
5
|
import { createTabBarItemPressHandler, resolveNavigationItems, } from '../../internal/resolveZoraNavigationItems';
|
|
6
|
+
import { useZoraTheme } from '../../theme/useZoraTheme';
|
|
5
7
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
6
|
-
function
|
|
8
|
+
function resolveAccessibilityLabel(label, explicitLabel) {
|
|
9
|
+
if (explicitLabel !== undefined) {
|
|
10
|
+
return explicitLabel;
|
|
11
|
+
}
|
|
12
|
+
if (typeof label === 'string') {
|
|
13
|
+
return label;
|
|
14
|
+
}
|
|
15
|
+
if (typeof label === 'number') {
|
|
16
|
+
return String(label);
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
function ZoraTabBarInner({ themeId: _themeId, mode: _mode, state, navigation, descriptors, insets, routeMap, compact = false, chrome = 'raised', testID, }) {
|
|
21
|
+
const { theme } = useZoraTheme();
|
|
7
22
|
const resolved = resolveNavigationItems({
|
|
8
23
|
state,
|
|
9
24
|
descriptors,
|
|
10
25
|
routeMap,
|
|
11
26
|
kind: 'tab',
|
|
12
27
|
});
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
const bottomInset = insets?.bottom ?? 0;
|
|
29
|
+
const minHeight = compact ? 56 : 64;
|
|
30
|
+
const labelSize = compact ? theme.typography.sizes.xs : theme.typography.sizes.s;
|
|
31
|
+
const labelWeight = theme.typography.weights.medium;
|
|
32
|
+
const content = (<Box bg="surface" style={{
|
|
33
|
+
borderTopColor: theme.semantics.border.default,
|
|
34
|
+
borderTopWidth: 1,
|
|
35
|
+
flexDirection: 'row',
|
|
36
|
+
minHeight: minHeight + bottomInset,
|
|
37
|
+
paddingBottom: bottomInset,
|
|
38
|
+
}} testID={testID}>
|
|
39
|
+
{resolved.map((item) => {
|
|
40
|
+
const { active } = item;
|
|
41
|
+
const { disabled } = item;
|
|
42
|
+
const contentColor = disabled
|
|
43
|
+
? theme.semantics.content.subtle
|
|
44
|
+
: active
|
|
45
|
+
? theme.semantics.action.primary.base
|
|
46
|
+
: theme.semantics.content.muted;
|
|
47
|
+
const backgroundColor = active
|
|
48
|
+
? theme.semantics.action.primary.softBg
|
|
49
|
+
: theme.semantics.surface.default;
|
|
50
|
+
return (<Pressable accessibilityLabel={resolveAccessibilityLabel(item.label, item.metadata?.accessibilityLabel)} accessibilityRole="tab" accessibilityState={{ selected: active, disabled }} disabled={disabled} key={item.route.key} onPress={createTabBarItemPressHandler({ item, navigation })} style={{
|
|
51
|
+
alignItems: 'center',
|
|
52
|
+
backgroundColor,
|
|
53
|
+
flex: 1,
|
|
54
|
+
justifyContent: 'center',
|
|
55
|
+
minHeight,
|
|
56
|
+
opacity: disabled ? 0.48 : 1,
|
|
57
|
+
paddingHorizontal: theme.spacing.s,
|
|
58
|
+
paddingVertical: compact ? theme.spacing.xs : theme.spacing.s,
|
|
59
|
+
}} testID={item.metadata?.testID ?? (testID ? `${testID}-item-${item.route.key}` : undefined)}>
|
|
60
|
+
{item.metadata?.icon ? (<Icon color={contentColor} name={item.metadata.icon.name} provider={item.metadata.icon.provider} size={compact ? theme.spacing.m : theme.spacing.l}/>) : null}
|
|
61
|
+
<ReactNativeText numberOfLines={1} style={{
|
|
62
|
+
color: contentColor,
|
|
63
|
+
fontSize: labelSize,
|
|
64
|
+
fontWeight: labelWeight,
|
|
65
|
+
lineHeight: compact ? 16 : 20,
|
|
66
|
+
marginTop: item.metadata?.icon ? theme.spacing.xs : 0,
|
|
67
|
+
textAlign: 'center',
|
|
68
|
+
}}>
|
|
69
|
+
{item.label}
|
|
70
|
+
</ReactNativeText>
|
|
71
|
+
</Pressable>);
|
|
72
|
+
})}
|
|
73
|
+
</Box>);
|
|
25
74
|
if (chrome === 'none') {
|
|
26
75
|
return content;
|
|
27
76
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZoraTabBar.js","sourceRoot":"","sources":["../../../src/patterns/zora-tab-bar/ZoraTabBar.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"ZoraTabBar.js","sourceRoot":"","sources":["../../../src/patterns/zora-tab-bar/ZoraTabBar.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Pressable, Text as ReactNativeText } from 'react-native';\n\nimport { Icon } from '../../components/icon';\nimport { Box, Surface } from '../../foundation';\nimport {\n createTabBarItemPressHandler,\n resolveNavigationItems,\n} from '../../internal/resolveZoraNavigationItems';\nimport { useZoraTheme } from '../../theme/useZoraTheme';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport type { ZoraTabBarProps } from './types';\n\nfunction resolveAccessibilityLabel(\n label: React.ReactNode,\n explicitLabel?: string,\n): string | undefined {\n if (explicitLabel !== undefined) {\n return explicitLabel;\n }\n\n if (typeof label === 'string') {\n return label;\n }\n\n if (typeof label === 'number') {\n return String(label);\n }\n\n return undefined;\n}\n\nfunction ZoraTabBarInner({\n themeId: _themeId,\n mode: _mode,\n state,\n navigation,\n descriptors,\n insets,\n routeMap,\n compact = false,\n chrome = 'raised',\n testID,\n}: ZoraTabBarProps) {\n const { theme } = useZoraTheme();\n const resolved = resolveNavigationItems({\n state,\n descriptors,\n routeMap,\n kind: 'tab',\n });\n\n const bottomInset = insets?.bottom ?? 0;\n const minHeight = compact ? 56 : 64;\n const labelSize = compact ? theme.typography.sizes.xs : theme.typography.sizes.s;\n const labelWeight = theme.typography.weights.medium;\n const content = (\n <Box\n bg=\"surface\"\n style={{\n borderTopColor: theme.semantics.border.default,\n borderTopWidth: 1,\n flexDirection: 'row',\n minHeight: minHeight + bottomInset,\n paddingBottom: bottomInset,\n }}\n testID={testID}\n >\n {resolved.map((item) => {\n const { active } = item;\n const { disabled } = item;\n const contentColor = disabled\n ? theme.semantics.content.subtle\n : active\n ? theme.semantics.action.primary.base\n : theme.semantics.content.muted;\n const backgroundColor = active\n ? theme.semantics.action.primary.softBg\n : theme.semantics.surface.default;\n\n return (\n <Pressable\n accessibilityLabel={resolveAccessibilityLabel(\n item.label,\n item.metadata?.accessibilityLabel,\n )}\n accessibilityRole=\"tab\"\n accessibilityState={{ selected: active, disabled }}\n disabled={disabled}\n key={item.route.key}\n onPress={createTabBarItemPressHandler({ item, navigation })}\n style={{\n alignItems: 'center',\n backgroundColor,\n flex: 1,\n justifyContent: 'center',\n minHeight,\n opacity: disabled ? 0.48 : 1,\n paddingHorizontal: theme.spacing.s,\n paddingVertical: compact ? theme.spacing.xs : theme.spacing.s,\n }}\n testID={\n item.metadata?.testID ?? (testID ? `${testID}-item-${item.route.key}` : undefined)\n }\n >\n {item.metadata?.icon ? (\n <Icon\n color={contentColor}\n name={item.metadata.icon.name}\n provider={item.metadata.icon.provider}\n size={compact ? theme.spacing.m : theme.spacing.l}\n />\n ) : null}\n <ReactNativeText\n numberOfLines={1}\n style={{\n color: contentColor,\n fontSize: labelSize,\n fontWeight: labelWeight,\n lineHeight: compact ? 16 : 20,\n marginTop: item.metadata?.icon ? theme.spacing.xs : 0,\n textAlign: 'center',\n }}\n >\n {item.label}\n </ReactNativeText>\n </Pressable>\n );\n })}\n </Box>\n );\n\n if (chrome === 'none') {\n return content;\n }\n\n return (\n <Surface variant=\"raised\" testID={testID ? `${testID}-chrome` : undefined}>\n {content}\n </Surface>\n );\n}\n\nexport const ZoraTabBar = withZoraThemeScope(ZoraTabBarInner);\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.1",
|
|
5
5
|
"description": "Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/zora#readme",
|
|
7
7
|
"bugs": {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ScrollArea } from '@ankhorage/surface';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
|
|
4
|
-
import { Container, Stack } from '../../foundation';
|
|
4
|
+
import { Box, Container, Stack } from '../../foundation';
|
|
5
5
|
import { resolvePageMaxWidth } from '../../internal/recipes';
|
|
6
6
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
7
7
|
import type { ScreenProps } from './types';
|
|
@@ -25,10 +25,18 @@ function ScreenInner({
|
|
|
25
25
|
);
|
|
26
26
|
|
|
27
27
|
if (!scroll) {
|
|
28
|
-
return
|
|
28
|
+
return (
|
|
29
|
+
<Box bg="background" flex={1}>
|
|
30
|
+
{content}
|
|
31
|
+
</Box>
|
|
32
|
+
);
|
|
29
33
|
}
|
|
30
34
|
|
|
31
|
-
return
|
|
35
|
+
return (
|
|
36
|
+
<ScrollArea bg="background" style={{ flex: 1 }}>
|
|
37
|
+
{content}
|
|
38
|
+
</ScrollArea>
|
|
39
|
+
);
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
export const Screen = withZoraThemeScope(ScreenInner);
|
|
@@ -1,25 +1,48 @@
|
|
|
1
|
-
import { TabBar as SurfaceTabBar } from '@ankhorage/surface';
|
|
2
1
|
import React from 'react';
|
|
2
|
+
import { Pressable, Text as ReactNativeText } from 'react-native';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { Icon } from '../../components/icon';
|
|
5
|
+
import { Box, Surface } from '../../foundation';
|
|
5
6
|
import {
|
|
6
7
|
createTabBarItemPressHandler,
|
|
7
8
|
resolveNavigationItems,
|
|
8
9
|
} from '../../internal/resolveZoraNavigationItems';
|
|
10
|
+
import { useZoraTheme } from '../../theme/useZoraTheme';
|
|
9
11
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
10
12
|
import type { ZoraTabBarProps } from './types';
|
|
11
13
|
|
|
14
|
+
function resolveAccessibilityLabel(
|
|
15
|
+
label: React.ReactNode,
|
|
16
|
+
explicitLabel?: string,
|
|
17
|
+
): string | undefined {
|
|
18
|
+
if (explicitLabel !== undefined) {
|
|
19
|
+
return explicitLabel;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (typeof label === 'string') {
|
|
23
|
+
return label;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (typeof label === 'number') {
|
|
27
|
+
return String(label);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
12
33
|
function ZoraTabBarInner({
|
|
13
34
|
themeId: _themeId,
|
|
14
35
|
mode: _mode,
|
|
15
36
|
state,
|
|
16
37
|
navigation,
|
|
17
38
|
descriptors,
|
|
39
|
+
insets,
|
|
18
40
|
routeMap,
|
|
19
41
|
compact = false,
|
|
20
42
|
chrome = 'raised',
|
|
21
43
|
testID,
|
|
22
44
|
}: ZoraTabBarProps) {
|
|
45
|
+
const { theme } = useZoraTheme();
|
|
23
46
|
const resolved = resolveNavigationItems({
|
|
24
47
|
state,
|
|
25
48
|
descriptors,
|
|
@@ -27,19 +50,85 @@ function ZoraTabBarInner({
|
|
|
27
50
|
kind: 'tab',
|
|
28
51
|
});
|
|
29
52
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
53
|
+
const bottomInset = insets?.bottom ?? 0;
|
|
54
|
+
const minHeight = compact ? 56 : 64;
|
|
55
|
+
const labelSize = compact ? theme.typography.sizes.xs : theme.typography.sizes.s;
|
|
56
|
+
const labelWeight = theme.typography.weights.medium;
|
|
57
|
+
const content = (
|
|
58
|
+
<Box
|
|
59
|
+
bg="surface"
|
|
60
|
+
style={{
|
|
61
|
+
borderTopColor: theme.semantics.border.default,
|
|
62
|
+
borderTopWidth: 1,
|
|
63
|
+
flexDirection: 'row',
|
|
64
|
+
minHeight: minHeight + bottomInset,
|
|
65
|
+
paddingBottom: bottomInset,
|
|
66
|
+
}}
|
|
67
|
+
testID={testID}
|
|
68
|
+
>
|
|
69
|
+
{resolved.map((item) => {
|
|
70
|
+
const { active } = item;
|
|
71
|
+
const { disabled } = item;
|
|
72
|
+
const contentColor = disabled
|
|
73
|
+
? theme.semantics.content.subtle
|
|
74
|
+
: active
|
|
75
|
+
? theme.semantics.action.primary.base
|
|
76
|
+
: theme.semantics.content.muted;
|
|
77
|
+
const backgroundColor = active
|
|
78
|
+
? theme.semantics.action.primary.softBg
|
|
79
|
+
: theme.semantics.surface.default;
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<Pressable
|
|
83
|
+
accessibilityLabel={resolveAccessibilityLabel(
|
|
84
|
+
item.label,
|
|
85
|
+
item.metadata?.accessibilityLabel,
|
|
86
|
+
)}
|
|
87
|
+
accessibilityRole="tab"
|
|
88
|
+
accessibilityState={{ selected: active, disabled }}
|
|
89
|
+
disabled={disabled}
|
|
90
|
+
key={item.route.key}
|
|
91
|
+
onPress={createTabBarItemPressHandler({ item, navigation })}
|
|
92
|
+
style={{
|
|
93
|
+
alignItems: 'center',
|
|
94
|
+
backgroundColor,
|
|
95
|
+
flex: 1,
|
|
96
|
+
justifyContent: 'center',
|
|
97
|
+
minHeight,
|
|
98
|
+
opacity: disabled ? 0.48 : 1,
|
|
99
|
+
paddingHorizontal: theme.spacing.s,
|
|
100
|
+
paddingVertical: compact ? theme.spacing.xs : theme.spacing.s,
|
|
101
|
+
}}
|
|
102
|
+
testID={
|
|
103
|
+
item.metadata?.testID ?? (testID ? `${testID}-item-${item.route.key}` : undefined)
|
|
104
|
+
}
|
|
105
|
+
>
|
|
106
|
+
{item.metadata?.icon ? (
|
|
107
|
+
<Icon
|
|
108
|
+
color={contentColor}
|
|
109
|
+
name={item.metadata.icon.name}
|
|
110
|
+
provider={item.metadata.icon.provider}
|
|
111
|
+
size={compact ? theme.spacing.m : theme.spacing.l}
|
|
112
|
+
/>
|
|
113
|
+
) : null}
|
|
114
|
+
<ReactNativeText
|
|
115
|
+
numberOfLines={1}
|
|
116
|
+
style={{
|
|
117
|
+
color: contentColor,
|
|
118
|
+
fontSize: labelSize,
|
|
119
|
+
fontWeight: labelWeight,
|
|
120
|
+
lineHeight: compact ? 16 : 20,
|
|
121
|
+
marginTop: item.metadata?.icon ? theme.spacing.xs : 0,
|
|
122
|
+
textAlign: 'center',
|
|
123
|
+
}}
|
|
124
|
+
>
|
|
125
|
+
{item.label}
|
|
126
|
+
</ReactNativeText>
|
|
127
|
+
</Pressable>
|
|
128
|
+
);
|
|
129
|
+
})}
|
|
130
|
+
</Box>
|
|
131
|
+
);
|
|
43
132
|
|
|
44
133
|
if (chrome === 'none') {
|
|
45
134
|
return content;
|