@ankhorage/zora 1.0.9 → 1.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.
- package/CHANGELOG.md +12 -0
- package/README.md +148 -0
- package/dist/components/image/Image.d.ts +4 -0
- package/dist/components/image/Image.d.ts.map +1 -0
- package/dist/components/image/Image.js +8 -0
- package/dist/components/image/Image.js.map +1 -0
- package/dist/components/image/index.d.ts +3 -0
- package/dist/components/image/index.d.ts.map +1 -0
- package/dist/components/image/index.js +2 -0
- package/dist/components/image/index.js.map +1 -0
- package/dist/components/image/types.d.ts +6 -0
- package/dist/components/image/types.d.ts.map +1 -0
- package/dist/components/image/types.js +2 -0
- package/dist/components/image/types.js.map +1 -0
- package/dist/components/navigation-item/NavigationItem.d.ts +4 -0
- package/dist/components/navigation-item/NavigationItem.d.ts.map +1 -0
- package/dist/components/navigation-item/NavigationItem.js +18 -0
- package/dist/components/navigation-item/NavigationItem.js.map +1 -0
- package/dist/components/navigation-item/index.d.ts +3 -0
- package/dist/components/navigation-item/index.d.ts.map +1 -0
- package/dist/components/navigation-item/index.js +2 -0
- package/dist/components/navigation-item/index.js.map +1 -0
- package/dist/components/navigation-item/types.d.ts +23 -0
- package/dist/components/navigation-item/types.d.ts.map +1 -0
- package/dist/components/navigation-item/types.js +2 -0
- package/dist/components/navigation-item/types.js.map +1 -0
- package/dist/components/navigation-list/NavigationList.d.ts +4 -0
- package/dist/components/navigation-list/NavigationList.d.ts.map +1 -0
- package/dist/components/navigation-list/NavigationList.js +26 -0
- package/dist/components/navigation-list/NavigationList.js.map +1 -0
- package/dist/components/navigation-list/index.d.ts +3 -0
- package/dist/components/navigation-list/index.d.ts.map +1 -0
- package/dist/components/navigation-list/index.js +2 -0
- package/dist/components/navigation-list/index.js.map +1 -0
- package/dist/components/navigation-list/types.d.ts +15 -0
- package/dist/components/navigation-list/types.d.ts.map +1 -0
- package/dist/components/navigation-list/types.js +2 -0
- package/dist/components/navigation-list/types.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/resolveZoraNavigationItems.d.ts +64 -0
- package/dist/internal/resolveZoraNavigationItems.d.ts.map +1 -0
- package/dist/internal/resolveZoraNavigationItems.js +55 -0
- package/dist/internal/resolveZoraNavigationItems.js.map +1 -0
- package/dist/patterns/image-preview/ImagePreview.d.ts +4 -0
- package/dist/patterns/image-preview/ImagePreview.d.ts.map +1 -0
- package/dist/patterns/image-preview/ImagePreview.js +41 -0
- package/dist/patterns/image-preview/ImagePreview.js.map +1 -0
- package/dist/patterns/image-preview/index.d.ts +3 -0
- package/dist/patterns/image-preview/index.d.ts.map +1 -0
- package/dist/patterns/image-preview/index.js +2 -0
- package/dist/patterns/image-preview/index.js.map +1 -0
- package/dist/patterns/image-preview/types.d.ts +36 -0
- package/dist/patterns/image-preview/types.d.ts.map +1 -0
- package/dist/patterns/image-preview/types.js +2 -0
- package/dist/patterns/image-preview/types.js.map +1 -0
- package/dist/patterns/image-upload-field/ImageUploadField.d.ts +4 -0
- package/dist/patterns/image-upload-field/ImageUploadField.d.ts.map +1 -0
- package/dist/patterns/image-upload-field/ImageUploadField.js +211 -0
- package/dist/patterns/image-upload-field/ImageUploadField.js.map +1 -0
- package/dist/patterns/image-upload-field/index.d.ts +3 -0
- package/dist/patterns/image-upload-field/index.d.ts.map +1 -0
- package/dist/patterns/image-upload-field/index.js +2 -0
- package/dist/patterns/image-upload-field/index.js.map +1 -0
- package/dist/patterns/image-upload-field/types.d.ts +35 -0
- package/dist/patterns/image-upload-field/types.d.ts.map +1 -0
- package/dist/patterns/image-upload-field/types.js +2 -0
- package/dist/patterns/image-upload-field/types.js.map +1 -0
- package/dist/patterns/image-upload-field/uploadFlow.d.ts +18 -0
- package/dist/patterns/image-upload-field/uploadFlow.d.ts.map +1 -0
- package/dist/patterns/image-upload-field/uploadFlow.js +106 -0
- package/dist/patterns/image-upload-field/uploadFlow.js.map +1 -0
- package/dist/patterns/zora-drawer-content/ZoraDrawerContent.d.ts +4 -0
- package/dist/patterns/zora-drawer-content/ZoraDrawerContent.d.ts.map +1 -0
- package/dist/patterns/zora-drawer-content/ZoraDrawerContent.js +26 -0
- package/dist/patterns/zora-drawer-content/ZoraDrawerContent.js.map +1 -0
- package/dist/patterns/zora-drawer-content/index.d.ts +3 -0
- package/dist/patterns/zora-drawer-content/index.d.ts.map +1 -0
- package/dist/patterns/zora-drawer-content/index.js +2 -0
- package/dist/patterns/zora-drawer-content/index.js.map +1 -0
- package/dist/patterns/zora-drawer-content/types.d.ts +15 -0
- package/dist/patterns/zora-drawer-content/types.d.ts.map +1 -0
- package/dist/patterns/zora-drawer-content/types.js +2 -0
- package/dist/patterns/zora-drawer-content/types.js.map +1 -0
- package/dist/patterns/zora-tab-bar/ZoraTabBar.d.ts +4 -0
- package/dist/patterns/zora-tab-bar/ZoraTabBar.d.ts.map +1 -0
- package/dist/patterns/zora-tab-bar/ZoraTabBar.js +33 -0
- package/dist/patterns/zora-tab-bar/ZoraTabBar.js.map +1 -0
- package/dist/patterns/zora-tab-bar/index.d.ts +3 -0
- package/dist/patterns/zora-tab-bar/index.d.ts.map +1 -0
- package/dist/patterns/zora-tab-bar/index.js +2 -0
- package/dist/patterns/zora-tab-bar/index.js.map +1 -0
- package/dist/patterns/zora-tab-bar/types.d.ts +19 -0
- package/dist/patterns/zora-tab-bar/types.d.ts.map +1 -0
- package/dist/patterns/zora-tab-bar/types.js +2 -0
- package/dist/patterns/zora-tab-bar/types.js.map +1 -0
- package/package.json +3 -3
- package/src/audit.test.ts +29 -0
- package/src/components/image/Image.tsx +11 -0
- package/src/components/image/index.ts +2 -0
- package/src/components/image/types.ts +7 -0
- package/src/components/navigation-item/NavigationItem.tsx +36 -0
- package/src/components/navigation-item/index.ts +6 -0
- package/src/components/navigation-item/types.ts +26 -0
- package/src/components/navigation-list/NavigationList.tsx +62 -0
- package/src/components/navigation-list/index.ts +2 -0
- package/src/components/navigation-list/types.ts +17 -0
- package/src/index.ts +26 -0
- package/src/internal/resolveZoraNavigationItems.test.ts +163 -0
- package/src/internal/resolveZoraNavigationItems.ts +156 -0
- package/src/navigationExports.test.ts +15 -0
- package/src/patterns/image-preview/ImagePreview.tsx +76 -0
- package/src/patterns/image-preview/index.ts +2 -0
- package/src/patterns/image-preview/types.ts +41 -0
- package/src/patterns/image-upload-field/ImageUploadField.tsx +293 -0
- package/src/patterns/image-upload-field/index.ts +2 -0
- package/src/patterns/image-upload-field/types.ts +41 -0
- package/src/patterns/image-upload-field/uploadFlow.test.ts +117 -0
- package/src/patterns/image-upload-field/uploadFlow.ts +145 -0
- package/src/patterns/zora-drawer-content/ZoraDrawerContent.tsx +53 -0
- package/src/patterns/zora-drawer-content/index.ts +2 -0
- package/src/patterns/zora-drawer-content/types.ts +20 -0
- package/src/patterns/zora-tab-bar/ZoraTabBar.tsx +55 -0
- package/src/patterns/zora-tab-bar/index.ts +2 -0
- package/src/patterns/zora-tab-bar/types.ts +18 -0
- package/src/showcaseCoverage.test.ts +7 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
function parseAccept(accept) {
|
|
2
|
+
if (!accept)
|
|
3
|
+
return [];
|
|
4
|
+
return accept
|
|
5
|
+
.split(',')
|
|
6
|
+
.map((entry) => entry.trim())
|
|
7
|
+
.filter((entry) => entry.length > 0);
|
|
8
|
+
}
|
|
9
|
+
function matchesAcceptToken({ token, contentType, fileName, }) {
|
|
10
|
+
const normalizedToken = token.toLowerCase();
|
|
11
|
+
const normalizedContentType = contentType?.toLowerCase();
|
|
12
|
+
const normalizedFileName = fileName?.toLowerCase();
|
|
13
|
+
if (normalizedToken.startsWith('.')) {
|
|
14
|
+
if (!normalizedFileName)
|
|
15
|
+
return null;
|
|
16
|
+
return normalizedFileName.endsWith(normalizedToken);
|
|
17
|
+
}
|
|
18
|
+
if (normalizedToken.endsWith('/*')) {
|
|
19
|
+
if (!normalizedContentType)
|
|
20
|
+
return null;
|
|
21
|
+
const prefix = normalizedToken.slice(0, Math.max(0, normalizedToken.length - 1));
|
|
22
|
+
return normalizedContentType.startsWith(prefix);
|
|
23
|
+
}
|
|
24
|
+
if (!normalizedContentType)
|
|
25
|
+
return null;
|
|
26
|
+
return normalizedContentType === normalizedToken;
|
|
27
|
+
}
|
|
28
|
+
export function isAccepted({ accept, contentType, fileName, }) {
|
|
29
|
+
const tokens = parseAccept(accept);
|
|
30
|
+
if (tokens.length === 0)
|
|
31
|
+
return true;
|
|
32
|
+
let hadSignal = false;
|
|
33
|
+
for (const token of tokens) {
|
|
34
|
+
const matches = matchesAcceptToken({ token, contentType, fileName });
|
|
35
|
+
if (matches === null) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
hadSignal = true;
|
|
39
|
+
if (matches)
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
// If we cannot validate due to missing metadata, do not block.
|
|
43
|
+
return !hadSignal;
|
|
44
|
+
}
|
|
45
|
+
function formatBytes(value) {
|
|
46
|
+
if (!Number.isFinite(value) || value <= 0)
|
|
47
|
+
return '0 B';
|
|
48
|
+
const units = ['B', 'KB', 'MB', 'GB'];
|
|
49
|
+
let size = value;
|
|
50
|
+
let unitIndex = 0;
|
|
51
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
52
|
+
size /= 1024;
|
|
53
|
+
unitIndex += 1;
|
|
54
|
+
}
|
|
55
|
+
const unit = units[unitIndex] ?? 'B';
|
|
56
|
+
const rounded = unitIndex === 0 ? Math.round(size) : Math.round(size * 10) / 10;
|
|
57
|
+
return `${rounded} ${unit}`;
|
|
58
|
+
}
|
|
59
|
+
export function formatAcceptHint(accept) {
|
|
60
|
+
const tokens = parseAccept(accept);
|
|
61
|
+
if (tokens.length === 0)
|
|
62
|
+
return null;
|
|
63
|
+
return `Accepted: ${tokens.join(', ')}`;
|
|
64
|
+
}
|
|
65
|
+
export function formatMaxSizeHint(maxSizeBytes) {
|
|
66
|
+
if (maxSizeBytes === undefined)
|
|
67
|
+
return null;
|
|
68
|
+
if (!Number.isFinite(maxSizeBytes) || maxSizeBytes <= 0)
|
|
69
|
+
return null;
|
|
70
|
+
return `Max size: ${formatBytes(maxSizeBytes)}`;
|
|
71
|
+
}
|
|
72
|
+
export function createOptimisticAssetFromPicked(picked) {
|
|
73
|
+
return {
|
|
74
|
+
kind: 'url',
|
|
75
|
+
url: picked.uri,
|
|
76
|
+
width: picked.width,
|
|
77
|
+
height: picked.height,
|
|
78
|
+
contentType: picked.contentType,
|
|
79
|
+
metadata: {
|
|
80
|
+
fileName: picked.fileName,
|
|
81
|
+
sizeBytes: picked.sizeBytes,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export function resolveRenderableUrl(asset) {
|
|
86
|
+
if (!asset)
|
|
87
|
+
return null;
|
|
88
|
+
if (asset.kind === 'url')
|
|
89
|
+
return asset.url;
|
|
90
|
+
return asset.publicUrl ?? null;
|
|
91
|
+
}
|
|
92
|
+
export function validatePickedImage({ picked, accept, maxSizeBytes, validatePicked, }) {
|
|
93
|
+
if (!isAccepted({ accept, contentType: picked.contentType, fileName: picked.fileName })) {
|
|
94
|
+
return accept ? `File type not accepted. Expected ${accept}.` : 'File type not accepted.';
|
|
95
|
+
}
|
|
96
|
+
if (maxSizeBytes !== undefined &&
|
|
97
|
+
Number.isFinite(maxSizeBytes) &&
|
|
98
|
+
maxSizeBytes > 0 &&
|
|
99
|
+
picked.sizeBytes !== undefined &&
|
|
100
|
+
Number.isFinite(picked.sizeBytes) &&
|
|
101
|
+
picked.sizeBytes > maxSizeBytes) {
|
|
102
|
+
return `File is too large (${formatBytes(picked.sizeBytes)}). Max ${formatBytes(maxSizeBytes)}.`;
|
|
103
|
+
}
|
|
104
|
+
return validatePicked?.(picked);
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=uploadFlow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploadFlow.js","sourceRoot":"","sources":["../../../src/patterns/image-upload-field/uploadFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ZoraImageAsset } from '../image-preview';\nimport type { ZoraPickedImage } from './types';\n\nfunction parseAccept(accept: string | undefined): readonly string[] {\n if (!accept) return [];\n\n return accept\n .split(',')\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0);\n}\n\nfunction matchesAcceptToken({\n token,\n contentType,\n fileName,\n}: {\n token: string;\n contentType: string | undefined;\n fileName: string | undefined;\n}): boolean | null {\n const normalizedToken = token.toLowerCase();\n const normalizedContentType = contentType?.toLowerCase();\n const normalizedFileName = fileName?.toLowerCase();\n\n if (normalizedToken.startsWith('.')) {\n if (!normalizedFileName) return null;\n return normalizedFileName.endsWith(normalizedToken);\n }\n\n if (normalizedToken.endsWith('/*')) {\n if (!normalizedContentType) return null;\n const prefix = normalizedToken.slice(0, Math.max(0, normalizedToken.length - 1));\n return normalizedContentType.startsWith(prefix);\n }\n\n if (!normalizedContentType) return null;\n return normalizedContentType === normalizedToken;\n}\n\nexport function isAccepted({\n accept,\n contentType,\n fileName,\n}: {\n accept: string | undefined;\n contentType: string | undefined;\n fileName: string | undefined;\n}): boolean {\n const tokens = parseAccept(accept);\n if (tokens.length === 0) return true;\n\n let hadSignal = false;\n\n for (const token of tokens) {\n const matches = matchesAcceptToken({ token, contentType, fileName });\n if (matches === null) {\n continue;\n }\n\n hadSignal = true;\n if (matches) return true;\n }\n\n // If we cannot validate due to missing metadata, do not block.\n return !hadSignal;\n}\n\nfunction formatBytes(value: number): string {\n if (!Number.isFinite(value) || value <= 0) return '0 B';\n\n const units = ['B', 'KB', 'MB', 'GB'] as const;\n let size = value;\n let unitIndex = 0;\n\n while (size >= 1024 && unitIndex < units.length - 1) {\n size /= 1024;\n unitIndex += 1;\n }\n\n const unit = units[unitIndex] ?? 'B';\n const rounded = unitIndex === 0 ? Math.round(size) : Math.round(size * 10) / 10;\n return `${rounded} ${unit}`;\n}\n\nexport function formatAcceptHint(accept: string | undefined): string | null {\n const tokens = parseAccept(accept);\n if (tokens.length === 0) return null;\n return `Accepted: ${tokens.join(', ')}`;\n}\n\nexport function formatMaxSizeHint(maxSizeBytes: number | undefined): string | null {\n if (maxSizeBytes === undefined) return null;\n if (!Number.isFinite(maxSizeBytes) || maxSizeBytes <= 0) return null;\n return `Max size: ${formatBytes(maxSizeBytes)}`;\n}\n\nexport function createOptimisticAssetFromPicked(picked: ZoraPickedImage): ZoraImageAsset {\n return {\n kind: 'url',\n url: picked.uri,\n width: picked.width,\n height: picked.height,\n contentType: picked.contentType,\n metadata: {\n fileName: picked.fileName,\n sizeBytes: picked.sizeBytes,\n },\n };\n}\n\nexport function resolveRenderableUrl(asset: ZoraImageAsset | null): string | null {\n if (!asset) return null;\n if (asset.kind === 'url') return asset.url;\n return asset.publicUrl ?? null;\n}\n\nexport function validatePickedImage({\n picked,\n accept,\n maxSizeBytes,\n validatePicked,\n}: {\n picked: ZoraPickedImage;\n accept: string | undefined;\n maxSizeBytes: number | undefined;\n validatePicked: ((picked: ZoraPickedImage) => string | undefined) | undefined;\n}): string | undefined {\n if (!isAccepted({ accept, contentType: picked.contentType, fileName: picked.fileName })) {\n return accept ? `File type not accepted. Expected ${accept}.` : 'File type not accepted.';\n }\n\n if (\n maxSizeBytes !== undefined &&\n Number.isFinite(maxSizeBytes) &&\n maxSizeBytes > 0 &&\n picked.sizeBytes !== undefined &&\n Number.isFinite(picked.sizeBytes) &&\n picked.sizeBytes > maxSizeBytes\n ) {\n return `File is too large (${formatBytes(picked.sizeBytes)}). Max ${formatBytes(maxSizeBytes)}.`;\n }\n\n return validatePicked?.(picked);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZoraDrawerContent.d.ts","sourceRoot":"","sources":["../../../src/patterns/zora-drawer-content/ZoraDrawerContent.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AA4CtD,eAAO,MAAM,iBAAiB,8DAA6C,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { DrawerNavigation as SurfaceDrawerNavigation } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { createDrawerItemPressHandler, resolveNavigationItems, } from '../../internal/resolveZoraNavigationItems';
|
|
4
|
+
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
5
|
+
function ZoraDrawerContentInner({ themeId: _themeId, mode: _mode, state, navigation, descriptors, routeMap, compact = false, header, footer, testID, }) {
|
|
6
|
+
const resolved = resolveNavigationItems({
|
|
7
|
+
state,
|
|
8
|
+
descriptors,
|
|
9
|
+
routeMap,
|
|
10
|
+
kind: 'drawer',
|
|
11
|
+
});
|
|
12
|
+
const items = resolved.map((item) => ({
|
|
13
|
+
id: item.route.key,
|
|
14
|
+
label: item.label,
|
|
15
|
+
icon: item.metadata?.icon,
|
|
16
|
+
badge: item.metadata?.badge,
|
|
17
|
+
active: item.active,
|
|
18
|
+
disabled: item.disabled,
|
|
19
|
+
onPress: createDrawerItemPressHandler({ item, navigation }),
|
|
20
|
+
accessibilityLabel: item.metadata?.accessibilityLabel,
|
|
21
|
+
testID: item.metadata?.testID,
|
|
22
|
+
}));
|
|
23
|
+
return (<SurfaceDrawerNavigation compact={compact} footer={footer} header={header} items={items} testID={testID}/>);
|
|
24
|
+
}
|
|
25
|
+
export const ZoraDrawerContent = withZoraThemeScope(ZoraDrawerContentInner);
|
|
26
|
+
//# sourceMappingURL=ZoraDrawerContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZoraDrawerContent.js","sourceRoot":"","sources":["../../../src/patterns/zora-drawer-content/ZoraDrawerContent.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,SAAS,sBAAsB,CAAC,EAC9B,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,KAAK,EACX,KAAK,EACL,UAAU,EACV,WAAW,EACX,QAAQ,EACR,OAAO,GAAG,KAAK,EACf,MAAM,EACN,MAAM,EACN,MAAM,GACiB;IACvB,MAAM,QAAQ,GAAG,sBAAsB,CAAC;QACtC,KAAK;QACL,WAAW;QACX,QAAQ;QACR,IAAI,EAAE,QAAQ;KACf,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACpC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG;QAClB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI;QACzB,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK;QAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,OAAO,EAAE,4BAA4B,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QAC3D,kBAAkB,EAAE,IAAI,CAAC,QAAQ,EAAE,kBAAkB;QACrD,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM;KAC9B,CAAC,CAAC,CAAC;IAEJ,OAAO,CACL,CAAC,uBAAuB,CACtB,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,MAAM,CAAC,CAAC,MAAM,CAAC,EACf,CACH,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,sBAAsB,CAAC,CAAC","sourcesContent":["import { DrawerNavigation as SurfaceDrawerNavigation } from '@ankhorage/surface';\nimport React from 'react';\n\nimport {\n createDrawerItemPressHandler,\n resolveNavigationItems,\n} from '../../internal/resolveZoraNavigationItems';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport type { ZoraDrawerContentProps } from './types';\n\nfunction ZoraDrawerContentInner({\n themeId: _themeId,\n mode: _mode,\n state,\n navigation,\n descriptors,\n routeMap,\n compact = false,\n header,\n footer,\n testID,\n}: ZoraDrawerContentProps) {\n const resolved = resolveNavigationItems({\n state,\n descriptors,\n routeMap,\n kind: 'drawer',\n });\n\n const items = resolved.map((item) => ({\n id: item.route.key,\n label: item.label,\n icon: item.metadata?.icon,\n badge: item.metadata?.badge,\n active: item.active,\n disabled: item.disabled,\n onPress: createDrawerItemPressHandler({ item, navigation }),\n accessibilityLabel: item.metadata?.accessibilityLabel,\n testID: item.metadata?.testID,\n }));\n\n return (\n <SurfaceDrawerNavigation\n compact={compact}\n footer={footer}\n header={header}\n items={items}\n testID={testID}\n />\n );\n}\n\nexport const ZoraDrawerContent = withZoraThemeScope(ZoraDrawerContentInner);\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/patterns/zora-drawer-content/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/patterns/zora-drawer-content/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["export type { ZoraDrawerContentProps } from './types';\nexport { ZoraDrawerContent } from './ZoraDrawerContent';\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { ZoraNavigationRouteMap } from '../../components/navigation-list';
|
|
3
|
+
import type { ZoraDrawerNavigation, ZoraNavigationDescriptors, ZoraNavigationState } from '../../internal/resolveZoraNavigationItems';
|
|
4
|
+
import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
|
|
5
|
+
export interface ZoraDrawerContentProps extends ZoraBaseProps {
|
|
6
|
+
state: ZoraNavigationState;
|
|
7
|
+
navigation: ZoraDrawerNavigation;
|
|
8
|
+
descriptors?: ZoraNavigationDescriptors | undefined;
|
|
9
|
+
routeMap?: ZoraNavigationRouteMap | undefined;
|
|
10
|
+
compact?: boolean;
|
|
11
|
+
header?: React.ReactNode;
|
|
12
|
+
footer?: React.ReactNode;
|
|
13
|
+
testID?: string;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/patterns/zora-drawer-content/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,KAAK,EACV,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACpB,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC3D,KAAK,EAAE,mBAAmB,CAAC;IAC3B,UAAU,EAAE,oBAAoB,CAAC;IACjC,WAAW,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/patterns/zora-drawer-content/types.ts"],"names":[],"mappings":"","sourcesContent":["import type React from 'react';\n\nimport type { ZoraNavigationRouteMap } from '../../components/navigation-list';\nimport type {\n ZoraDrawerNavigation,\n ZoraNavigationDescriptors,\n ZoraNavigationState,\n} from '../../internal/resolveZoraNavigationItems';\nimport type { ZoraBaseProps } from '../../theme/ZoraBaseProps';\n\nexport interface ZoraDrawerContentProps extends ZoraBaseProps {\n state: ZoraNavigationState;\n navigation: ZoraDrawerNavigation;\n descriptors?: ZoraNavigationDescriptors | undefined;\n routeMap?: ZoraNavigationRouteMap | undefined;\n compact?: boolean;\n header?: React.ReactNode;\n footer?: React.ReactNode;\n testID?: string;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZoraTabBar.d.ts","sourceRoot":"","sources":["../../../src/patterns/zora-tab-bar/ZoraTabBar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA6C/C,eAAO,MAAM,UAAU,uDAAsC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { TabBar as SurfaceTabBar } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Surface } from '../../foundation';
|
|
4
|
+
import { createTabBarItemPressHandler, resolveNavigationItems, } from '../../internal/resolveZoraNavigationItems';
|
|
5
|
+
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
6
|
+
function ZoraTabBarInner({ themeId: _themeId, mode: _mode, state, navigation, descriptors, routeMap, compact = false, chrome = 'raised', testID, }) {
|
|
7
|
+
const resolved = resolveNavigationItems({
|
|
8
|
+
state,
|
|
9
|
+
descriptors,
|
|
10
|
+
routeMap,
|
|
11
|
+
kind: 'tab',
|
|
12
|
+
});
|
|
13
|
+
const items = resolved.map((item) => ({
|
|
14
|
+
id: item.route.key,
|
|
15
|
+
label: item.label,
|
|
16
|
+
icon: item.metadata?.icon,
|
|
17
|
+
badge: item.metadata?.badge,
|
|
18
|
+
active: item.active,
|
|
19
|
+
disabled: item.disabled,
|
|
20
|
+
onPress: createTabBarItemPressHandler({ item, navigation }),
|
|
21
|
+
accessibilityLabel: item.metadata?.accessibilityLabel,
|
|
22
|
+
testID: item.metadata?.testID,
|
|
23
|
+
}));
|
|
24
|
+
const content = <SurfaceTabBar compact={compact} items={items} testID={testID}/>;
|
|
25
|
+
if (chrome === 'none') {
|
|
26
|
+
return content;
|
|
27
|
+
}
|
|
28
|
+
return (<Surface variant="raised" testID={testID ? `${testID}-chrome` : undefined}>
|
|
29
|
+
{content}
|
|
30
|
+
</Surface>);
|
|
31
|
+
}
|
|
32
|
+
export const ZoraTabBar = withZoraThemeScope(ZoraTabBarInner);
|
|
33
|
+
//# sourceMappingURL=ZoraTabBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZoraTabBar.js","sourceRoot":"","sources":["../../../src/patterns/zora-tab-bar/ZoraTabBar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,SAAS,eAAe,CAAC,EACvB,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,KAAK,EACX,KAAK,EACL,UAAU,EACV,WAAW,EACX,QAAQ,EACR,OAAO,GAAG,KAAK,EACf,MAAM,GAAG,QAAQ,EACjB,MAAM,GACU;IAChB,MAAM,QAAQ,GAAG,sBAAsB,CAAC;QACtC,KAAK;QACL,WAAW;QACX,QAAQ;QACR,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACpC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG;QAClB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI;QACzB,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK;QAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,OAAO,EAAE,4BAA4B,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QAC3D,kBAAkB,EAAE,IAAI,CAAC,QAAQ,EAAE,kBAAkB;QACrD,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM;KAC9B,CAAC,CAAC,CAAC;IAEJ,MAAM,OAAO,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAG,CAAC;IAElF,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,CACL,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CACxE;MAAA,CAAC,OAAO,CACV;IAAA,EAAE,OAAO,CAAC,CACX,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,kBAAkB,CAAC,eAAe,CAAC,CAAC","sourcesContent":["import { TabBar as SurfaceTabBar } from '@ankhorage/surface';\nimport React from 'react';\n\nimport { Surface } from '../../foundation';\nimport {\n createTabBarItemPressHandler,\n resolveNavigationItems,\n} from '../../internal/resolveZoraNavigationItems';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport type { ZoraTabBarProps } from './types';\n\nfunction ZoraTabBarInner({\n themeId: _themeId,\n mode: _mode,\n state,\n navigation,\n descriptors,\n routeMap,\n compact = false,\n chrome = 'raised',\n testID,\n}: ZoraTabBarProps) {\n const resolved = resolveNavigationItems({\n state,\n descriptors,\n routeMap,\n kind: 'tab',\n });\n\n const items = resolved.map((item) => ({\n id: item.route.key,\n label: item.label,\n icon: item.metadata?.icon,\n badge: item.metadata?.badge,\n active: item.active,\n disabled: item.disabled,\n onPress: createTabBarItemPressHandler({ item, navigation }),\n accessibilityLabel: item.metadata?.accessibilityLabel,\n testID: item.metadata?.testID,\n }));\n\n const content = <SurfaceTabBar compact={compact} items={items} testID={testID} />;\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"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/patterns/zora-tab-bar/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/patterns/zora-tab-bar/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC","sourcesContent":["export type { ZoraTabBarProps } from './types';\nexport { ZoraTabBar } from './ZoraTabBar';\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ZoraNavigationRouteMap } from '../../components/navigation-list';
|
|
2
|
+
import type { ZoraNavigationDescriptors, ZoraNavigationState, ZoraTabBarNavigation } from '../../internal/resolveZoraNavigationItems';
|
|
3
|
+
import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
|
|
4
|
+
export interface ZoraTabBarProps extends ZoraBaseProps {
|
|
5
|
+
state: ZoraNavigationState;
|
|
6
|
+
navigation: ZoraTabBarNavigation;
|
|
7
|
+
descriptors?: ZoraNavigationDescriptors | undefined;
|
|
8
|
+
insets?: {
|
|
9
|
+
top?: number;
|
|
10
|
+
bottom?: number;
|
|
11
|
+
left?: number;
|
|
12
|
+
right?: number;
|
|
13
|
+
} | undefined;
|
|
14
|
+
routeMap?: ZoraNavigationRouteMap | undefined;
|
|
15
|
+
compact?: boolean;
|
|
16
|
+
chrome?: 'none' | 'raised';
|
|
17
|
+
testID?: string;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/patterns/zora-tab-bar/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,KAAK,EAAE,mBAAmB,CAAC;IAC3B,UAAU,EAAE,oBAAoB,CAAC;IACjC,WAAW,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;IACpD,MAAM,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACtF,QAAQ,CAAC,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/patterns/zora-tab-bar/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ZoraNavigationRouteMap } from '../../components/navigation-list';\nimport type {\n ZoraNavigationDescriptors,\n ZoraNavigationState,\n ZoraTabBarNavigation,\n} from '../../internal/resolveZoraNavigationItems';\nimport type { ZoraBaseProps } from '../../theme/ZoraBaseProps';\n\nexport interface ZoraTabBarProps extends ZoraBaseProps {\n state: ZoraNavigationState;\n navigation: ZoraTabBarNavigation;\n descriptors?: ZoraNavigationDescriptors | undefined;\n insets?: { top?: number; bottom?: number; left?: number; right?: number } | undefined;\n routeMap?: ZoraNavigationRouteMap | undefined;\n compact?: boolean;\n chrome?: 'none' | 'raised';\n testID?: string;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0
|
|
4
|
+
"version": "1.1.0",
|
|
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": {
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@ankhorage/color-theory": "^0.0.4",
|
|
47
|
-
"@ankhorage/contracts": "^1.
|
|
48
|
-
"@ankhorage/surface": "^1.0
|
|
47
|
+
"@ankhorage/contracts": "^1.2.0",
|
|
48
|
+
"@ankhorage/surface": "^1.2.0"
|
|
49
49
|
},
|
|
50
50
|
"files": [
|
|
51
51
|
"dist",
|
package/src/audit.test.ts
CHANGED
|
@@ -240,3 +240,32 @@ describe('Plan 5 audit — public exports carry no legacy types', () => {
|
|
|
240
240
|
expect(indexSource).not.toContain('AnkhTheme');
|
|
241
241
|
});
|
|
242
242
|
});
|
|
243
|
+
|
|
244
|
+
describe('navigation chrome policy', () => {
|
|
245
|
+
const NAVIGATION_PATHS = [
|
|
246
|
+
join(SRC_ROOT, 'components', 'navigation-item'),
|
|
247
|
+
join(SRC_ROOT, 'components', 'navigation-list'),
|
|
248
|
+
join(SRC_ROOT, 'patterns', 'zora-tab-bar'),
|
|
249
|
+
join(SRC_ROOT, 'patterns', 'zora-drawer-content'),
|
|
250
|
+
join(SRC_ROOT, 'internal', 'resolveZoraNavigationItems.ts'),
|
|
251
|
+
];
|
|
252
|
+
|
|
253
|
+
test('does not import expo-router, react-navigation, or Surface internals', () => {
|
|
254
|
+
const sources = NAVIGATION_PATHS.flatMap((path) => {
|
|
255
|
+
if (path.endsWith('.ts')) {
|
|
256
|
+
return [readFileSync(path, 'utf8')];
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (!path.includes(`${SRC_ROOT}/`)) {
|
|
260
|
+
return [];
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return listFiles(path).map((filePath) => readFileSync(filePath, 'utf8'));
|
|
264
|
+
}).join('\n');
|
|
265
|
+
|
|
266
|
+
expect(sources).not.toMatch(/expo-router/);
|
|
267
|
+
expect(sources).not.toMatch(/@react-navigation\//);
|
|
268
|
+
expect(sources).not.toMatch(/@ankhorage\/surface\/src\//);
|
|
269
|
+
expect(sources).not.toMatch(/@ankhorage\/surface\/dist\//);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Image as SurfaceImage } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
5
|
+
import type { ImageProps } from './types';
|
|
6
|
+
|
|
7
|
+
function ImageInner({ themeId: _themeId, mode: _mode, ...props }: ImageProps) {
|
|
8
|
+
return <SurfaceImage {...props} />;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const Image = withZoraThemeScope(ImageInner);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ImageProps as SurfaceImageProps } from '@ankhorage/surface';
|
|
2
|
+
|
|
3
|
+
import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
|
|
4
|
+
|
|
5
|
+
export type { ImageFit, SurfaceImageSource } from '@ankhorage/surface';
|
|
6
|
+
|
|
7
|
+
export interface ImageProps extends ZoraBaseProps, Omit<SurfaceImageProps, 'mode' | 'themeId'> {}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { NavigationItem as SurfaceNavigationItem } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
5
|
+
import type { NavigationItemProps } from './types';
|
|
6
|
+
|
|
7
|
+
function NavigationItemInner({
|
|
8
|
+
themeId: _themeId,
|
|
9
|
+
mode: _mode,
|
|
10
|
+
route,
|
|
11
|
+
metadata,
|
|
12
|
+
active = false,
|
|
13
|
+
compact = false,
|
|
14
|
+
onPress,
|
|
15
|
+
testID,
|
|
16
|
+
}: NavigationItemProps) {
|
|
17
|
+
return (
|
|
18
|
+
<SurfaceNavigationItem
|
|
19
|
+
compact={compact}
|
|
20
|
+
item={{
|
|
21
|
+
id: route.key,
|
|
22
|
+
label: metadata?.label ?? route.name,
|
|
23
|
+
icon: metadata?.icon,
|
|
24
|
+
badge: metadata?.badge,
|
|
25
|
+
active,
|
|
26
|
+
disabled: metadata?.disabled,
|
|
27
|
+
onPress,
|
|
28
|
+
accessibilityLabel: metadata?.accessibilityLabel,
|
|
29
|
+
testID: metadata?.testID,
|
|
30
|
+
}}
|
|
31
|
+
testID={testID}
|
|
32
|
+
/>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const NavigationItem = withZoraThemeScope(NavigationItemInner);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ButtonIconSpec } from '@ankhorage/surface';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
|
|
4
|
+
import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
|
|
5
|
+
|
|
6
|
+
export interface ZoraNavigationRouteMetadata {
|
|
7
|
+
label?: React.ReactNode;
|
|
8
|
+
icon?: ButtonIconSpec;
|
|
9
|
+
badge?: React.ReactNode;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
testID?: string;
|
|
12
|
+
accessibilityLabel?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ZoraNavigationRouteState {
|
|
16
|
+
key: string;
|
|
17
|
+
name: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface NavigationItemProps extends ZoraBaseProps {
|
|
21
|
+
route: ZoraNavigationRouteState;
|
|
22
|
+
metadata?: ZoraNavigationRouteMetadata;
|
|
23
|
+
active?: boolean;
|
|
24
|
+
compact?: boolean;
|
|
25
|
+
onPress?: () => void;
|
|
26
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DrawerNavigation as SurfaceDrawerNavigation,
|
|
3
|
+
NavigationList as SurfaceNavigationList,
|
|
4
|
+
} from '@ankhorage/surface';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
8
|
+
import type { NavigationListProps } from './types';
|
|
9
|
+
|
|
10
|
+
function NavigationListInner({
|
|
11
|
+
themeId: _themeId,
|
|
12
|
+
mode: _mode,
|
|
13
|
+
routes,
|
|
14
|
+
routeMap,
|
|
15
|
+
activeRouteKey,
|
|
16
|
+
orientation = 'vertical',
|
|
17
|
+
compact = false,
|
|
18
|
+
onRoutePress,
|
|
19
|
+
header,
|
|
20
|
+
footer,
|
|
21
|
+
testID,
|
|
22
|
+
}: NavigationListProps) {
|
|
23
|
+
const items = routes.map((route) => {
|
|
24
|
+
const metadata = routeMap?.[route.name];
|
|
25
|
+
const active = activeRouteKey ? route.key === activeRouteKey : false;
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
id: route.key,
|
|
29
|
+
label: metadata?.label ?? route.name,
|
|
30
|
+
icon: metadata?.icon,
|
|
31
|
+
badge: metadata?.badge,
|
|
32
|
+
active,
|
|
33
|
+
disabled: metadata?.disabled,
|
|
34
|
+
onPress: metadata?.disabled ? undefined : () => onRoutePress?.(route),
|
|
35
|
+
accessibilityLabel: metadata?.accessibilityLabel,
|
|
36
|
+
testID: metadata?.testID,
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (header || footer) {
|
|
41
|
+
return (
|
|
42
|
+
<SurfaceDrawerNavigation
|
|
43
|
+
compact={compact}
|
|
44
|
+
footer={footer}
|
|
45
|
+
header={header}
|
|
46
|
+
items={items}
|
|
47
|
+
testID={testID}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<SurfaceNavigationList
|
|
54
|
+
compact={compact}
|
|
55
|
+
items={items}
|
|
56
|
+
orientation={orientation}
|
|
57
|
+
testID={testID}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const NavigationList = withZoraThemeScope(NavigationListInner);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
|
|
4
|
+
import type { ZoraNavigationRouteMetadata, ZoraNavigationRouteState } from '../navigation-item';
|
|
5
|
+
|
|
6
|
+
export type ZoraNavigationRouteMap = Partial<Record<string, ZoraNavigationRouteMetadata>>;
|
|
7
|
+
|
|
8
|
+
export interface NavigationListProps extends ZoraBaseProps {
|
|
9
|
+
routes: readonly ZoraNavigationRouteState[];
|
|
10
|
+
routeMap?: ZoraNavigationRouteMap;
|
|
11
|
+
activeRouteKey?: string;
|
|
12
|
+
orientation?: 'vertical' | 'horizontal';
|
|
13
|
+
compact?: boolean;
|
|
14
|
+
onRoutePress?: (route: ZoraNavigationRouteState) => void;
|
|
15
|
+
header?: React.ReactNode;
|
|
16
|
+
footer?: React.ReactNode;
|
|
17
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -58,6 +58,8 @@ export type { IconProps } from './components/icon';
|
|
|
58
58
|
export { Icon } from './components/icon';
|
|
59
59
|
export type { IconButtonProps } from './components/icon-button';
|
|
60
60
|
export { IconButton } from './components/icon-button';
|
|
61
|
+
export type { ImageFit, ImageProps, SurfaceImageSource } from './components/image';
|
|
62
|
+
export { Image } from './components/image';
|
|
61
63
|
export type { InputProps, InputTrailingAction } from './components/input';
|
|
62
64
|
export { Input } from './components/input';
|
|
63
65
|
export type { MediaCardImageProps, MediaCardProps } from './components/media-card';
|
|
@@ -66,6 +68,14 @@ export type { MetricCardProps } from './components/metric-card';
|
|
|
66
68
|
export { MetricCard } from './components/metric-card';
|
|
67
69
|
export type { ModalProps } from './components/modal';
|
|
68
70
|
export { Modal } from './components/modal';
|
|
71
|
+
export type {
|
|
72
|
+
NavigationItemProps,
|
|
73
|
+
ZoraNavigationRouteMetadata,
|
|
74
|
+
ZoraNavigationRouteState,
|
|
75
|
+
} from './components/navigation-item';
|
|
76
|
+
export { NavigationItem } from './components/navigation-item';
|
|
77
|
+
export type { NavigationListProps, ZoraNavigationRouteMap } from './components/navigation-list';
|
|
78
|
+
export { NavigationList } from './components/navigation-list';
|
|
69
79
|
export type { ProgressProps } from './components/progress';
|
|
70
80
|
export { Progress } from './components/progress';
|
|
71
81
|
export type { RadioGroupOption, RadioGroupProps, RadioProps } from './components/radio';
|
|
@@ -152,6 +162,18 @@ export type { EmptyStateAction, EmptyStateProps } from './patterns/empty-state';
|
|
|
152
162
|
export { EmptyState } from './patterns/empty-state';
|
|
153
163
|
export type { FilterBarProps } from './patterns/filter-bar';
|
|
154
164
|
export { FilterBar } from './patterns/filter-bar';
|
|
165
|
+
export type {
|
|
166
|
+
ImagePreviewProps,
|
|
167
|
+
ZoraImageAsset,
|
|
168
|
+
ZoraImageMetadata,
|
|
169
|
+
} from './patterns/image-preview';
|
|
170
|
+
export { ImagePreview } from './patterns/image-preview';
|
|
171
|
+
export type {
|
|
172
|
+
ImageUploadFieldProps,
|
|
173
|
+
ImageUploadProgressContext,
|
|
174
|
+
ZoraPickedImage,
|
|
175
|
+
} from './patterns/image-upload-field';
|
|
176
|
+
export { ImageUploadField } from './patterns/image-upload-field';
|
|
155
177
|
export type { InspectorFieldProps } from './patterns/inspector-field';
|
|
156
178
|
export { InspectorField } from './patterns/inspector-field';
|
|
157
179
|
export type {
|
|
@@ -183,4 +205,8 @@ export type { TimelineItem, TimelineProps } from './patterns/timeline';
|
|
|
183
205
|
export { Timeline } from './patterns/timeline';
|
|
184
206
|
export type { TreeItemNode, TreeItemRenderProps, TreeViewProps } from './patterns/tree-view';
|
|
185
207
|
export { TreeItem, TreeView } from './patterns/tree-view';
|
|
208
|
+
export type { ZoraDrawerContentProps } from './patterns/zora-drawer-content';
|
|
209
|
+
export { ZoraDrawerContent } from './patterns/zora-drawer-content';
|
|
210
|
+
export type { ZoraTabBarProps } from './patterns/zora-tab-bar';
|
|
211
|
+
export { ZoraTabBar } from './patterns/zora-tab-bar';
|
|
186
212
|
export * from './theme';
|