@ankhorage/zora 6.0.0 → 7.0.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 +6 -0
- package/README.md +2 -1
- package/dist/components/image/Image.d.ts +1 -5
- package/dist/components/image/Image.d.ts.map +1 -1
- package/dist/components/image/Image.js +79 -8
- package/dist/components/image/Image.js.map +1 -1
- package/dist/components/image/types.d.ts +4 -2
- package/dist/components/image/types.d.ts.map +1 -1
- package/dist/components/image/types.js.map +1 -1
- package/dist/features/uploader/adapters/inbound/Uploader.d.ts +5 -0
- package/dist/features/uploader/adapters/inbound/Uploader.d.ts.map +1 -0
- package/dist/features/uploader/adapters/inbound/Uploader.js +274 -0
- package/dist/features/uploader/adapters/inbound/Uploader.js.map +1 -0
- package/dist/features/uploader/adapters/outbound/pickDocumentOrFileAsync.d.ts +5 -0
- package/dist/features/uploader/adapters/outbound/pickDocumentOrFileAsync.d.ts.map +1 -0
- package/dist/features/uploader/adapters/outbound/pickDocumentOrFileAsync.js +38 -0
- package/dist/features/uploader/adapters/outbound/pickDocumentOrFileAsync.js.map +1 -0
- package/dist/features/uploader/adapters/outbound/pickImageOrVideoAsync.d.ts +5 -0
- package/dist/features/uploader/adapters/outbound/pickImageOrVideoAsync.d.ts.map +1 -0
- package/dist/features/uploader/adapters/outbound/pickImageOrVideoAsync.js +24 -0
- package/dist/features/uploader/adapters/outbound/pickImageOrVideoAsync.js.map +1 -0
- package/dist/features/uploader/application/ports/outbound/UploadPickerPort.d.ts +9 -0
- package/dist/features/uploader/application/ports/outbound/UploadPickerPort.d.ts.map +1 -0
- package/dist/features/uploader/application/ports/outbound/UploadPickerPort.js +2 -0
- package/dist/features/uploader/application/ports/outbound/UploadPickerPort.js.map +1 -0
- package/dist/features/uploader/application/use-cases/pickUploadAssetAsync.d.ts +5 -0
- package/dist/features/uploader/application/use-cases/pickUploadAssetAsync.d.ts.map +1 -0
- package/dist/features/uploader/application/use-cases/pickUploadAssetAsync.js +6 -0
- package/dist/features/uploader/application/use-cases/pickUploadAssetAsync.js.map +1 -0
- package/dist/features/uploader/application/use-cases/validateUploadAsset.d.ts +4 -0
- package/dist/features/uploader/application/use-cases/validateUploadAsset.d.ts.map +1 -0
- package/dist/features/uploader/application/use-cases/validateUploadAsset.js +77 -0
- package/dist/features/uploader/application/use-cases/validateUploadAsset.js.map +1 -0
- package/dist/features/uploader/composition/createUploadPicker.d.ts +4 -0
- package/dist/features/uploader/composition/createUploadPicker.d.ts.map +1 -0
- package/dist/features/uploader/composition/createUploadPicker.js +12 -0
- package/dist/features/uploader/composition/createUploadPicker.js.map +1 -0
- package/dist/features/uploader/meta.d.ts +10 -0
- package/dist/features/uploader/meta.d.ts.map +1 -0
- package/dist/features/uploader/meta.js +10 -0
- package/dist/features/uploader/meta.js.map +1 -0
- package/dist/features/uploader/public.d.ts +4 -0
- package/dist/features/uploader/public.d.ts.map +1 -0
- package/dist/features/uploader/public.js +3 -0
- package/dist/features/uploader/public.js.map +1 -0
- package/dist/index.d.ts +2 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/metadata/componentMeta.d.ts.map +1 -1
- package/dist/metadata/componentMeta.js +2 -4
- package/dist/metadata/componentMeta.js.map +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +2 -4
- package/dist/registry.js.map +1 -1
- package/dist/types/upload.d.ts +53 -0
- package/dist/types/upload.d.ts.map +1 -0
- package/dist/types/upload.js +2 -0
- package/dist/types/upload.js.map +1 -0
- package/package.json +11 -2
- package/src/components/image/Image.tsx +136 -8
- package/src/components/image/types.ts +6 -2
- package/src/features/uploader/adapters/inbound/Uploader.tsx +403 -0
- package/src/features/uploader/adapters/outbound/pickDocumentOrFileAsync.ts +50 -0
- package/src/features/uploader/adapters/outbound/pickImageOrVideoAsync.ts +30 -0
- package/src/features/uploader/application/ports/outbound/UploadPickerPort.ts +10 -0
- package/src/features/uploader/application/use-cases/pickUploadAssetAsync.test.ts +48 -0
- package/src/features/uploader/application/use-cases/pickUploadAssetAsync.ts +14 -0
- package/src/features/uploader/application/use-cases/validateUploadAsset.test.ts +51 -0
- package/src/features/uploader/application/use-cases/validateUploadAsset.ts +111 -0
- package/src/features/uploader/composition/createUploadPicker.ts +14 -0
- package/src/features/uploader/meta.ts +11 -0
- package/src/features/uploader/public.test.ts +34 -0
- package/src/features/uploader/public.ts +10 -0
- package/src/index.ts +9 -12
- package/src/metadata/componentMeta.ts +2 -4
- package/src/registry.test.ts +1 -1
- package/src/registry.ts +2 -4
- package/src/showcaseCoverage.test.ts +1 -2
- package/src/types/upload.ts +62 -0
- package/dist/patterns/image-preview/ImagePreview.d.ts +0 -9
- package/dist/patterns/image-preview/ImagePreview.d.ts.map +0 -1
- package/dist/patterns/image-preview/ImagePreview.js +0 -46
- package/dist/patterns/image-preview/ImagePreview.js.map +0 -1
- package/dist/patterns/image-preview/index.d.ts +0 -3
- package/dist/patterns/image-preview/index.d.ts.map +0 -1
- package/dist/patterns/image-preview/index.js +0 -2
- package/dist/patterns/image-preview/index.js.map +0 -1
- package/dist/patterns/image-preview/meta.d.ts +0 -9
- package/dist/patterns/image-preview/meta.d.ts.map +0 -1
- package/dist/patterns/image-preview/meta.js +0 -9
- package/dist/patterns/image-preview/meta.js.map +0 -1
- package/dist/patterns/image-preview/types.d.ts +0 -36
- package/dist/patterns/image-preview/types.d.ts.map +0 -1
- package/dist/patterns/image-preview/types.js +0 -2
- package/dist/patterns/image-preview/types.js.map +0 -1
- package/dist/patterns/image-upload-field/ImageUploadField.d.ts +0 -9
- package/dist/patterns/image-upload-field/ImageUploadField.d.ts.map +0 -1
- package/dist/patterns/image-upload-field/ImageUploadField.js +0 -222
- package/dist/patterns/image-upload-field/ImageUploadField.js.map +0 -1
- package/dist/patterns/image-upload-field/index.d.ts +0 -3
- package/dist/patterns/image-upload-field/index.d.ts.map +0 -1
- package/dist/patterns/image-upload-field/index.js +0 -2
- package/dist/patterns/image-upload-field/index.js.map +0 -1
- package/dist/patterns/image-upload-field/meta.d.ts +0 -9
- package/dist/patterns/image-upload-field/meta.d.ts.map +0 -1
- package/dist/patterns/image-upload-field/meta.js +0 -9
- package/dist/patterns/image-upload-field/meta.js.map +0 -1
- package/dist/patterns/image-upload-field/types.d.ts +0 -35
- package/dist/patterns/image-upload-field/types.d.ts.map +0 -1
- package/dist/patterns/image-upload-field/types.js +0 -2
- package/dist/patterns/image-upload-field/types.js.map +0 -1
- package/dist/patterns/image-upload-field/uploadFlow.d.ts +0 -18
- package/dist/patterns/image-upload-field/uploadFlow.d.ts.map +0 -1
- package/dist/patterns/image-upload-field/uploadFlow.js +0 -106
- package/dist/patterns/image-upload-field/uploadFlow.js.map +0 -1
- package/src/patterns/image-preview/ImagePreview.tsx +0 -82
- package/src/patterns/image-preview/index.ts +0 -2
- package/src/patterns/image-preview/meta.ts +0 -10
- package/src/patterns/image-preview/types.ts +0 -41
- package/src/patterns/image-upload-field/ImageUploadField.tsx +0 -319
- package/src/patterns/image-upload-field/index.ts +0 -2
- package/src/patterns/image-upload-field/meta.ts +0 -10
- package/src/patterns/image-upload-field/types.ts +0 -41
- package/src/patterns/image-upload-field/uploadFlow.test.ts +0 -117
- package/src/patterns/image-upload-field/uploadFlow.ts +0 -145
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { ValidateUploadAssetInput } from '../../../../types/upload';
|
|
2
|
+
|
|
3
|
+
/*** Validates a picked upload asset against MIME, extension, size, and caller rules. */
|
|
4
|
+
export function validateUploadAsset({
|
|
5
|
+
asset,
|
|
6
|
+
accept,
|
|
7
|
+
maxSizeBytes,
|
|
8
|
+
validate,
|
|
9
|
+
}: ValidateUploadAssetInput): string | undefined {
|
|
10
|
+
if (!isAccepted(asset.contentType, asset.fileName, accept)) {
|
|
11
|
+
return accept ? `File type not accepted. Expected ${accept}.` : 'File type not accepted.';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (
|
|
15
|
+
maxSizeBytes !== undefined &&
|
|
16
|
+
Number.isFinite(maxSizeBytes) &&
|
|
17
|
+
maxSizeBytes > 0 &&
|
|
18
|
+
asset.sizeBytes !== undefined &&
|
|
19
|
+
Number.isFinite(asset.sizeBytes) &&
|
|
20
|
+
asset.sizeBytes > maxSizeBytes
|
|
21
|
+
) {
|
|
22
|
+
return `File is too large (${formatBytes(asset.sizeBytes)}). Max ${formatBytes(maxSizeBytes)}.`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return validate?.(asset);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/*** Returns whether available file metadata satisfies at least one accept token. */
|
|
29
|
+
function isAccepted(
|
|
30
|
+
contentType: string | undefined,
|
|
31
|
+
fileName: string | undefined,
|
|
32
|
+
accept: string | undefined,
|
|
33
|
+
): boolean {
|
|
34
|
+
const tokens = parseAccept(accept);
|
|
35
|
+
if (tokens.length === 0) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let hadSignal = false;
|
|
40
|
+
|
|
41
|
+
for (const token of tokens) {
|
|
42
|
+
const matches = matchesAcceptToken(token, contentType, fileName);
|
|
43
|
+
if (matches === null) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
hadSignal = true;
|
|
48
|
+
if (matches) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return !hadSignal;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/*** Matches one MIME or extension accept token against available file metadata. */
|
|
57
|
+
function matchesAcceptToken(
|
|
58
|
+
token: string,
|
|
59
|
+
contentType: string | undefined,
|
|
60
|
+
fileName: string | undefined,
|
|
61
|
+
): boolean | null {
|
|
62
|
+
const normalizedToken = token.toLowerCase();
|
|
63
|
+
const normalizedContentType = contentType?.toLowerCase();
|
|
64
|
+
const normalizedFileName = fileName?.toLowerCase();
|
|
65
|
+
|
|
66
|
+
if (normalizedToken.startsWith('.')) {
|
|
67
|
+
return normalizedFileName ? normalizedFileName.endsWith(normalizedToken) : null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (normalizedToken.endsWith('/*')) {
|
|
71
|
+
if (!normalizedContentType) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return normalizedContentType.startsWith(normalizedToken.slice(0, -1));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return normalizedContentType ? normalizedContentType === normalizedToken : null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/*** Parses a browser-style accept string into normalized non-empty tokens. */
|
|
82
|
+
function parseAccept(accept: string | undefined): readonly string[] {
|
|
83
|
+
if (!accept) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return accept
|
|
88
|
+
.split(',')
|
|
89
|
+
.map((token) => token.trim())
|
|
90
|
+
.filter((token) => token.length > 0);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/*** Formats a byte count for concise upload validation feedback. */
|
|
94
|
+
function formatBytes(value: number): string {
|
|
95
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
96
|
+
return '0 B';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const units = ['B', 'KB', 'MB', 'GB'] as const;
|
|
100
|
+
let size = value;
|
|
101
|
+
let unitIndex = 0;
|
|
102
|
+
|
|
103
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
104
|
+
size /= 1024;
|
|
105
|
+
unitIndex += 1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const unit = units.at(unitIndex) ?? 'B';
|
|
109
|
+
const rounded = unitIndex === 0 ? Math.round(size) : Math.round(size * 10) / 10;
|
|
110
|
+
return `${rounded} ${unit}`;
|
|
111
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { pickDocumentOrFileAsync } from '../adapters/outbound/pickDocumentOrFileAsync';
|
|
2
|
+
import { pickImageOrVideoAsync } from '../adapters/outbound/pickImageOrVideoAsync';
|
|
3
|
+
import type { UploadPickerPort } from '../application/ports/outbound/UploadPickerPort';
|
|
4
|
+
import { pickUploadAssetAsync } from '../application/use-cases/pickUploadAssetAsync';
|
|
5
|
+
|
|
6
|
+
/*** Wires the Expo picker adapters into the generic upload picker use case. */
|
|
7
|
+
export function createUploadPicker(): UploadPickerPort {
|
|
8
|
+
const imageOrVideoPicker: UploadPickerPort = { pickAsync: pickImageOrVideoAsync };
|
|
9
|
+
const documentOrFilePicker: UploadPickerPort = { pickAsync: pickDocumentOrFileAsync };
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
pickAsync: (input) => pickUploadAssetAsync(input, imageOrVideoPicker, documentOrFilePicker),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ZoraComponentMeta } from '../../metadata';
|
|
2
|
+
|
|
3
|
+
export const uploaderMeta = {
|
|
4
|
+
name: 'Uploader',
|
|
5
|
+
category: 'pattern',
|
|
6
|
+
description: 'Picks and manages one image, video, document, or generic file upload.',
|
|
7
|
+
directManifestNode: false,
|
|
8
|
+
allowedChildren: [],
|
|
9
|
+
note: 'Upload transport callbacks remain runtime-owned and are not serialized into AppManifest.',
|
|
10
|
+
props: {},
|
|
11
|
+
} as const satisfies ZoraComponentMeta;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
describe('ZORA Uploader public contract', () => {
|
|
4
|
+
test('publishes the generic uploader through root and explicit subpath APIs', async () => {
|
|
5
|
+
const packageJson = (await Bun.file('package.json').json()) as {
|
|
6
|
+
dependencies: Readonly<Record<string, string>>;
|
|
7
|
+
exports: Readonly<Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
const [rootSource, publicSource] = await Promise.all([
|
|
10
|
+
Bun.file('src/index.ts').text(),
|
|
11
|
+
Bun.file('src/features/uploader/public.ts').text(),
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
expect(packageJson.exports['./uploader']).toBeDefined();
|
|
15
|
+
expect(packageJson.dependencies['expo-image-picker']).toMatch(/^~57\./u);
|
|
16
|
+
expect(packageJson.dependencies['expo-document-picker']).toMatch(/^~57\./u);
|
|
17
|
+
expect(rootSource).toContain("from './features/uploader/public'");
|
|
18
|
+
expect(publicSource).toContain('export { Uploader }');
|
|
19
|
+
expect(publicSource).toContain('export { validateUploadAsset }');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('removes the superseded image preview and upload field APIs', async () => {
|
|
23
|
+
const [rootSource, registrySource, metadataSource] = await Promise.all([
|
|
24
|
+
Bun.file('src/index.ts').text(),
|
|
25
|
+
Bun.file('src/registry.ts').text(),
|
|
26
|
+
Bun.file('src/metadata/componentMeta.ts').text(),
|
|
27
|
+
]);
|
|
28
|
+
const publicSurface = `${rootSource}\n${registrySource}\n${metadataSource}`;
|
|
29
|
+
|
|
30
|
+
expect(publicSurface).not.toContain('ImagePreview');
|
|
31
|
+
expect(publicSurface).not.toContain('ImageUploadField');
|
|
32
|
+
expect(publicSurface).toContain('Uploader');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
UploadAsset,
|
|
3
|
+
UploadAssetBase,
|
|
4
|
+
UploaderProps,
|
|
5
|
+
UploadProgressContext,
|
|
6
|
+
UploadType,
|
|
7
|
+
ValidateUploadAssetInput,
|
|
8
|
+
} from '../../types/upload';
|
|
9
|
+
export { Uploader } from './adapters/inbound/Uploader';
|
|
10
|
+
export { validateUploadAsset } from './application/use-cases/validateUploadAsset';
|
package/src/index.ts
CHANGED
|
@@ -146,6 +146,15 @@ export type { ToolbarActionProps, ToolbarPosition, ToolbarProps } from './compon
|
|
|
146
146
|
export { Toolbar, ToolbarAction } from './components/toolbar';
|
|
147
147
|
export { ZORA_CORE_PLUGIN } from './corePlugin';
|
|
148
148
|
export { ZORA_CORE_PLUGIN_METADATA } from './corePluginMetadata';
|
|
149
|
+
export type {
|
|
150
|
+
UploadAsset,
|
|
151
|
+
UploadAssetBase,
|
|
152
|
+
UploaderProps,
|
|
153
|
+
UploadProgressContext,
|
|
154
|
+
UploadType,
|
|
155
|
+
ValidateUploadAssetInput,
|
|
156
|
+
} from './features/uploader/public';
|
|
157
|
+
export { Uploader, validateUploadAsset } from './features/uploader/public';
|
|
149
158
|
export type {
|
|
150
159
|
BoxProps,
|
|
151
160
|
CenterProps,
|
|
@@ -284,18 +293,6 @@ export type { FilterBarProps } from './patterns/filter-bar';
|
|
|
284
293
|
export { FilterBar } from './patterns/filter-bar';
|
|
285
294
|
export type { HeroAction, HeroAlign, HeroLayout, HeroProps, HeroTone } from './patterns/hero';
|
|
286
295
|
export { Hero } from './patterns/hero';
|
|
287
|
-
export type {
|
|
288
|
-
ImagePreviewProps,
|
|
289
|
-
ZoraImageAsset,
|
|
290
|
-
ZoraImageMetadata,
|
|
291
|
-
} from './patterns/image-preview';
|
|
292
|
-
export { ImagePreview } from './patterns/image-preview';
|
|
293
|
-
export type {
|
|
294
|
-
ImageUploadFieldProps,
|
|
295
|
-
ImageUploadProgressContext,
|
|
296
|
-
ZoraPickedImage,
|
|
297
|
-
} from './patterns/image-upload-field';
|
|
298
|
-
export { ImageUploadField } from './patterns/image-upload-field';
|
|
299
296
|
export type { InspectorFieldProps } from './patterns/inspector-field';
|
|
300
297
|
export { InspectorField } from './patterns/inspector-field';
|
|
301
298
|
export type {
|
|
@@ -41,6 +41,7 @@ import { textareaMeta } from '../components/textarea/meta';
|
|
|
41
41
|
import { timePickerMeta } from '../components/time-picker/meta';
|
|
42
42
|
import { toastMeta, toastProviderMeta } from '../components/toast/meta';
|
|
43
43
|
import { toolbarActionMeta, toolbarMeta } from '../components/toolbar/meta';
|
|
44
|
+
import { uploaderMeta } from '../features/uploader/meta';
|
|
44
45
|
import { foundationMetas } from '../foundation/meta';
|
|
45
46
|
import { appShellMeta } from '../layout/app-shell/meta';
|
|
46
47
|
import { screenMeta } from '../layout/screen/meta';
|
|
@@ -64,8 +65,6 @@ import { disclosureSectionMeta } from '../patterns/disclosure-section/meta';
|
|
|
64
65
|
import { emptyStateMeta } from '../patterns/empty-state/meta';
|
|
65
66
|
import { filterBarMeta } from '../patterns/filter-bar/meta';
|
|
66
67
|
import { heroMeta } from '../patterns/hero/meta';
|
|
67
|
-
import { imagePreviewMeta } from '../patterns/image-preview/meta';
|
|
68
|
-
import { imageUploadFieldMeta } from '../patterns/image-upload-field/meta';
|
|
69
68
|
import { inspectorFieldMeta } from '../patterns/inspector-field/meta';
|
|
70
69
|
import { listMeta, listRowMeta, listSectionMeta } from '../patterns/list/meta';
|
|
71
70
|
import { messageBubbleMeta } from '../patterns/message-bubble/meta';
|
|
@@ -143,6 +142,7 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = {
|
|
|
143
142
|
ToastProvider: toastProviderMeta,
|
|
144
143
|
Toolbar: toolbarMeta,
|
|
145
144
|
ToolbarAction: toolbarActionMeta,
|
|
145
|
+
Uploader: uploaderMeta,
|
|
146
146
|
ThemeModeToggle: themeModeToggleMeta,
|
|
147
147
|
AppShell: appShellMeta,
|
|
148
148
|
Screen: screenMeta,
|
|
@@ -164,8 +164,6 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = {
|
|
|
164
164
|
EmptyState: emptyStateMeta,
|
|
165
165
|
FilterBar: filterBarMeta,
|
|
166
166
|
Hero: heroMeta,
|
|
167
|
-
ImagePreview: imagePreviewMeta,
|
|
168
|
-
ImageUploadField: imageUploadFieldMeta,
|
|
169
167
|
InspectorField: inspectorFieldMeta,
|
|
170
168
|
List: listMeta,
|
|
171
169
|
ListRow: listRowMeta,
|
package/src/registry.test.ts
CHANGED
|
@@ -55,7 +55,7 @@ async function listPublicConcreteComponentExports(): Promise<readonly string[]>
|
|
|
55
55
|
const source = await Bun.file('src/index.ts').text();
|
|
56
56
|
const componentExports = Array.from(
|
|
57
57
|
source.matchAll(
|
|
58
|
-
/export\s+\{([^}]+)\}\s+from '\.\/(components\/[^']+|foundation|layout\/[^']+|patterns\/[^']+)';/g,
|
|
58
|
+
/export\s+\{([^}]+)\}\s+from '\.\/(components\/[^']+|features\/[^']+|foundation|layout\/[^']+|patterns\/[^']+)';/g,
|
|
59
59
|
),
|
|
60
60
|
)
|
|
61
61
|
.flatMap((match) => match[1].split(',').map((item) => item.trim()))
|
package/src/registry.ts
CHANGED
|
@@ -39,6 +39,7 @@ import { Textarea } from './components/textarea';
|
|
|
39
39
|
import { TimePicker } from './components/time-picker';
|
|
40
40
|
import { Toast } from './components/toast';
|
|
41
41
|
import { Toolbar, ToolbarAction } from './components/toolbar';
|
|
42
|
+
import { Uploader } from './features/uploader/public';
|
|
42
43
|
import {
|
|
43
44
|
Box,
|
|
44
45
|
Center,
|
|
@@ -73,8 +74,6 @@ import { DisclosureSection } from './patterns/disclosure-section';
|
|
|
73
74
|
import { EmptyState } from './patterns/empty-state';
|
|
74
75
|
import { FilterBar } from './patterns/filter-bar';
|
|
75
76
|
import { Hero } from './patterns/hero';
|
|
76
|
-
import { ImagePreview } from './patterns/image-preview';
|
|
77
|
-
import { ImageUploadField } from './patterns/image-upload-field';
|
|
78
77
|
import { InspectorField } from './patterns/inspector-field';
|
|
79
78
|
import { List, ListRow, ListSection } from './patterns/list';
|
|
80
79
|
import { MessageBubble } from './patterns/message-bubble';
|
|
@@ -170,6 +169,7 @@ const _ZORA_COMPONENT_REGISTRY = {
|
|
|
170
169
|
Toast,
|
|
171
170
|
Toolbar,
|
|
172
171
|
ToolbarAction,
|
|
172
|
+
Uploader,
|
|
173
173
|
ThemeModeToggle,
|
|
174
174
|
Box,
|
|
175
175
|
Center,
|
|
@@ -201,8 +201,6 @@ const _ZORA_COMPONENT_REGISTRY = {
|
|
|
201
201
|
EmptyState,
|
|
202
202
|
FilterBar,
|
|
203
203
|
Hero,
|
|
204
|
-
ImagePreview,
|
|
205
|
-
ImageUploadField,
|
|
206
204
|
InspectorField,
|
|
207
205
|
List,
|
|
208
206
|
ListRow,
|
|
@@ -65,6 +65,7 @@ const REQUIRED_SHOWCASE_COVERAGE = {
|
|
|
65
65
|
'Stack',
|
|
66
66
|
'Surface',
|
|
67
67
|
],
|
|
68
|
+
features: ['Uploader'],
|
|
68
69
|
layouts: [
|
|
69
70
|
'AppShell',
|
|
70
71
|
'Screen',
|
|
@@ -90,8 +91,6 @@ const REQUIRED_SHOWCASE_COVERAGE = {
|
|
|
90
91
|
'ListRow',
|
|
91
92
|
'ListSection',
|
|
92
93
|
'InspectorField',
|
|
93
|
-
'ImagePreview',
|
|
94
|
-
'ImageUploadField',
|
|
95
94
|
'Notice',
|
|
96
95
|
'Panel',
|
|
97
96
|
'ReaderSurface',
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { ZoraBaseProps } from '../theme/ZoraBaseProps';
|
|
4
|
+
|
|
5
|
+
export type UploadType = 'image' | 'video' | 'document' | 'file';
|
|
6
|
+
|
|
7
|
+
export interface UploadAssetBase {
|
|
8
|
+
fileName?: string;
|
|
9
|
+
sizeBytes?: number;
|
|
10
|
+
contentType?: string;
|
|
11
|
+
width?: number;
|
|
12
|
+
height?: number;
|
|
13
|
+
alt?: string;
|
|
14
|
+
createdAt?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type UploadAsset =
|
|
18
|
+
| (UploadAssetBase & {
|
|
19
|
+
kind: 'local';
|
|
20
|
+
uri: string;
|
|
21
|
+
})
|
|
22
|
+
| (UploadAssetBase & {
|
|
23
|
+
kind: 'url';
|
|
24
|
+
url: string;
|
|
25
|
+
})
|
|
26
|
+
| (UploadAssetBase & {
|
|
27
|
+
kind: 'storage';
|
|
28
|
+
storageId?: string;
|
|
29
|
+
bucket: string;
|
|
30
|
+
path: string;
|
|
31
|
+
publicUrl?: string;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export interface UploadProgressContext {
|
|
35
|
+
setProgress: (progress: number | null) => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ValidateUploadAssetInput {
|
|
39
|
+
asset: UploadAsset;
|
|
40
|
+
accept?: string;
|
|
41
|
+
maxSizeBytes?: number;
|
|
42
|
+
validate?: (asset: UploadAsset) => string | undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface UploaderProps extends ZoraBaseProps {
|
|
46
|
+
value: UploadAsset | null;
|
|
47
|
+
onChange: (next: UploadAsset | null) => void;
|
|
48
|
+
label: React.ReactNode;
|
|
49
|
+
description?: React.ReactNode;
|
|
50
|
+
helperText?: React.ReactNode;
|
|
51
|
+
errorText?: React.ReactNode;
|
|
52
|
+
type?: UploadType;
|
|
53
|
+
accept?: string;
|
|
54
|
+
maxSizeBytes?: number;
|
|
55
|
+
required?: boolean;
|
|
56
|
+
disabled?: boolean;
|
|
57
|
+
readOnly?: boolean;
|
|
58
|
+
validatePicked?: (asset: UploadAsset) => string | undefined;
|
|
59
|
+
onUpload?: (asset: UploadAsset, context: UploadProgressContext) => Promise<UploadAsset>;
|
|
60
|
+
onRemove?: (current: UploadAsset) => void | Promise<void>;
|
|
61
|
+
aspectRatio?: number;
|
|
62
|
+
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { ImagePreviewProps } from './types';
|
|
3
|
-
/***
|
|
4
|
-
* Preview pattern for showing an image with optional metadata and actions.
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
*/
|
|
8
|
-
export declare const ImagePreview: (props: ImagePreviewProps) => React.ReactElement | null;
|
|
9
|
-
//# sourceMappingURL=ImagePreview.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ImagePreview.d.ts","sourceRoot":"","sources":["../../../src/patterns/image-preview/ImagePreview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,KAAK,EAAE,iBAAiB,EAAkB,MAAM,SAAS,CAAC;AAqEjE;;;;GAIG;AACH,eAAO,MAAM,YAAY,yDAAwC,CAAC"}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Image } from '../../components/image';
|
|
3
|
-
import { Text } from '../../components/text';
|
|
4
|
-
import { Box, Stack } from '../../foundation';
|
|
5
|
-
import { useZoraTheme } from '../../theme/useZoraTheme';
|
|
6
|
-
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
7
|
-
function resolveRenderableUrl(asset) {
|
|
8
|
-
if (!asset)
|
|
9
|
-
return null;
|
|
10
|
-
if (asset.kind === 'url') {
|
|
11
|
-
return asset.url;
|
|
12
|
-
}
|
|
13
|
-
return asset.publicUrl ?? null;
|
|
14
|
-
}
|
|
15
|
-
function resolveSafeAspectRatio(value) {
|
|
16
|
-
if (!value || !Number.isFinite(value) || value <= 0) {
|
|
17
|
-
return 1;
|
|
18
|
-
}
|
|
19
|
-
return value;
|
|
20
|
-
}
|
|
21
|
-
function ImagePreviewInner({ themeId: _themeId, mode: _mode, testID, asset, aspectRatio, fit = 'cover', emptyTitle = 'No image', emptyDescription = 'Select an image to preview it here.', interactionPolicy: _interactionPolicy, }) {
|
|
22
|
-
const { theme } = useZoraTheme();
|
|
23
|
-
const renderableUrl = resolveRenderableUrl(asset);
|
|
24
|
-
const resolvedAspectRatio = resolveSafeAspectRatio(aspectRatio);
|
|
25
|
-
return (<Box bg={theme.semantics.neutral.surface} borderColor={theme.semantics.neutral.divider} borderWidth={1} radius="l" testID={testID} style={{ overflow: 'hidden' }}>
|
|
26
|
-
{renderableUrl ? (<Box style={{ aspectRatio: resolvedAspectRatio, width: '100%' }}>
|
|
27
|
-
<Image alt={asset?.alt} fit={fit} source={renderableUrl} style={{ height: '100%', width: '100%' }}/>
|
|
28
|
-
</Box>) : (<Box p="l">
|
|
29
|
-
<Stack gap="xs">
|
|
30
|
-
<Text variant="label" weight="semiBold">
|
|
31
|
-
{emptyTitle}
|
|
32
|
-
</Text>
|
|
33
|
-
<Text emphasis="muted" variant="bodySmall">
|
|
34
|
-
{emptyDescription}
|
|
35
|
-
</Text>
|
|
36
|
-
</Stack>
|
|
37
|
-
</Box>)}
|
|
38
|
-
</Box>);
|
|
39
|
-
}
|
|
40
|
-
/***
|
|
41
|
-
* Preview pattern for showing an image with optional metadata and actions.
|
|
42
|
-
*
|
|
43
|
-
|
|
44
|
-
*/
|
|
45
|
-
export const ImagePreview = withZoraThemeScope(ImagePreviewInner);
|
|
46
|
-
//# sourceMappingURL=ImagePreview.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ImagePreview.js","sourceRoot":"","sources":["../../../src/patterns/image-preview/ImagePreview.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\n\nimport { Image } from '../../components/image';\nimport { Text } from '../../components/text';\nimport { Box, Stack } from '../../foundation';\nimport { useZoraTheme } from '../../theme/useZoraTheme';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport type { ImagePreviewProps, ZoraImageAsset } from './types';\n\nfunction resolveRenderableUrl(asset: ZoraImageAsset | null | undefined): string | null {\n if (!asset) return null;\n\n if (asset.kind === 'url') {\n return asset.url;\n }\n\n return asset.publicUrl ?? null;\n}\n\nfunction resolveSafeAspectRatio(value: number | undefined): number {\n if (!value || !Number.isFinite(value) || value <= 0) {\n return 1;\n }\n\n return value;\n}\n\nfunction ImagePreviewInner({\n themeId: _themeId,\n mode: _mode,\n testID,\n asset,\n aspectRatio,\n fit = 'cover',\n emptyTitle = 'No image',\n emptyDescription = 'Select an image to preview it here.',\n interactionPolicy: _interactionPolicy,\n}: ImagePreviewProps) {\n const { theme } = useZoraTheme();\n const renderableUrl = resolveRenderableUrl(asset);\n const resolvedAspectRatio = resolveSafeAspectRatio(aspectRatio);\n\n return (\n <Box\n bg={theme.semantics.neutral.surface}\n borderColor={theme.semantics.neutral.divider}\n borderWidth={1}\n radius=\"l\"\n testID={testID}\n style={{ overflow: 'hidden' }}\n >\n {renderableUrl ? (\n <Box style={{ aspectRatio: resolvedAspectRatio, width: '100%' }}>\n <Image\n alt={asset?.alt}\n fit={fit}\n source={renderableUrl}\n style={{ height: '100%', width: '100%' }}\n />\n </Box>\n ) : (\n <Box p=\"l\">\n <Stack gap=\"xs\">\n <Text variant=\"label\" weight=\"semiBold\">\n {emptyTitle}\n </Text>\n <Text emphasis=\"muted\" variant=\"bodySmall\">\n {emptyDescription}\n </Text>\n </Stack>\n </Box>\n )}\n </Box>\n );\n}\n\n/***\n * Preview pattern for showing an image with optional metadata and actions.\n *\n \n */\nexport const ImagePreview = withZoraThemeScope(ImagePreviewInner);\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/patterns/image-preview/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/patterns/image-preview/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC","sourcesContent":["export { ImagePreview } from './ImagePreview';\nexport type { ImagePreviewProps, ZoraImageAsset, ZoraImageMetadata } from './types';\n"]}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export declare const imagePreviewMeta: {
|
|
2
|
-
readonly name: "ImagePreview";
|
|
3
|
-
readonly category: "pattern";
|
|
4
|
-
readonly directManifestNode: false;
|
|
5
|
-
readonly allowedChildren: readonly [];
|
|
6
|
-
readonly note: "Media pattern; not represented as a manifest node in v1.";
|
|
7
|
-
readonly props: {};
|
|
8
|
-
};
|
|
9
|
-
//# sourceMappingURL=meta.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../../src/patterns/image-preview/meta.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gBAAgB;;;;;;;CAOS,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../src/patterns/image-preview/meta.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,IAAI,EAAE,cAAc;IACpB,QAAQ,EAAE,SAAS;IACnB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,EAAE;IACnB,IAAI,EAAE,0DAA0D;IAChE,KAAK,EAAE,EAAE;CAC2B,CAAC","sourcesContent":["import type { ZoraComponentMeta } from '../../metadata';\n\nexport const imagePreviewMeta = {\n name: 'ImagePreview',\n category: 'pattern',\n directManifestNode: false,\n allowedChildren: [],\n note: 'Media pattern; not represented as a manifest node in v1.',\n props: {},\n} as const satisfies ZoraComponentMeta;\n"]}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type React from 'react';
|
|
2
|
-
import type { ImageFit } from '../../components/image';
|
|
3
|
-
import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
|
|
4
|
-
export interface ZoraImageMetadata {
|
|
5
|
-
fileName?: string;
|
|
6
|
-
sizeBytes?: number;
|
|
7
|
-
createdAt?: string;
|
|
8
|
-
}
|
|
9
|
-
export type ZoraImageAsset = {
|
|
10
|
-
kind: 'url';
|
|
11
|
-
url: string;
|
|
12
|
-
alt?: string;
|
|
13
|
-
width?: number;
|
|
14
|
-
height?: number;
|
|
15
|
-
contentType?: string;
|
|
16
|
-
metadata?: ZoraImageMetadata;
|
|
17
|
-
} | {
|
|
18
|
-
kind: 'storage';
|
|
19
|
-
storageId?: string;
|
|
20
|
-
bucket: string;
|
|
21
|
-
path: string;
|
|
22
|
-
publicUrl?: string;
|
|
23
|
-
alt?: string;
|
|
24
|
-
width?: number;
|
|
25
|
-
height?: number;
|
|
26
|
-
contentType?: string;
|
|
27
|
-
metadata?: ZoraImageMetadata;
|
|
28
|
-
};
|
|
29
|
-
export interface ImagePreviewProps extends ZoraBaseProps {
|
|
30
|
-
asset?: ZoraImageAsset | null;
|
|
31
|
-
aspectRatio?: number;
|
|
32
|
-
fit?: ImageFit;
|
|
33
|
-
emptyTitle?: React.ReactNode;
|
|
34
|
-
emptyDescription?: React.ReactNode;
|
|
35
|
-
}
|
|
36
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/patterns/image-preview/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,cAAc,GACtB;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B,CAAC;AAEN,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,KAAK,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACpC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/patterns/image-preview/types.ts"],"names":[],"mappings":"","sourcesContent":["import type React from 'react';\n\nimport type { ImageFit } from '../../components/image';\nimport type { ZoraBaseProps } from '../../theme/ZoraBaseProps';\n\nexport interface ZoraImageMetadata {\n fileName?: string;\n sizeBytes?: number;\n createdAt?: string;\n}\n\nexport type ZoraImageAsset =\n | {\n kind: 'url';\n url: string;\n alt?: string;\n width?: number;\n height?: number;\n contentType?: string;\n metadata?: ZoraImageMetadata;\n }\n | {\n kind: 'storage';\n storageId?: string;\n bucket: string;\n path: string;\n publicUrl?: string;\n alt?: string;\n width?: number;\n height?: number;\n contentType?: string;\n metadata?: ZoraImageMetadata;\n };\n\nexport interface ImagePreviewProps extends ZoraBaseProps {\n asset?: ZoraImageAsset | null;\n aspectRatio?: number;\n fit?: ImageFit;\n emptyTitle?: React.ReactNode;\n emptyDescription?: React.ReactNode;\n}\n"]}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { ImageUploadFieldProps } from './types';
|
|
3
|
-
/***
|
|
4
|
-
* Form field pattern for picking, previewing, and uploading an image.
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
*/
|
|
8
|
-
export declare const ImageUploadField: (props: ImageUploadFieldProps) => React.ReactElement | null;
|
|
9
|
-
//# sourceMappingURL=ImageUploadField.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ImageUploadField.d.ts","sourceRoot":"","sources":["../../../src/patterns/image-upload-field/ImageUploadField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AA+SrD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,6DAA4C,CAAC"}
|