@ankhorage/zora 25.8.16 → 25.8.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/dist/capabilities/index.js +34 -59
  4. package/dist/capabilities/index.js.map +3 -3
  5. package/dist/features/date-picker/composition/DatePickerContent.d.ts.map +1 -1
  6. package/dist/features/date-picker/composition/DatePickerContent.js +1 -11
  7. package/dist/features/date-picker/composition/DatePickerContent.js.map +1 -1
  8. package/dist/features/date-picker/composition/DatePickerField.d.ts.map +1 -1
  9. package/dist/features/date-picker/composition/DatePickerField.js +2 -17
  10. package/dist/features/date-picker/composition/DatePickerField.js.map +1 -1
  11. package/dist/features/matrix-grid/application/getMatrixGridNextFocusId.js +7 -19
  12. package/dist/features/matrix-grid/application/getMatrixGridNextFocusId.js.map +1 -1
  13. package/dist/features/picker/composition/PickerField.d.ts +14 -0
  14. package/dist/features/picker/composition/PickerField.d.ts.map +1 -0
  15. package/dist/features/picker/composition/PickerField.js +21 -0
  16. package/dist/features/picker/composition/PickerField.js.map +1 -0
  17. package/dist/features/picker/composition/PickerHeader.d.ts +9 -0
  18. package/dist/features/picker/composition/PickerHeader.d.ts.map +1 -0
  19. package/dist/features/picker/composition/PickerHeader.js +14 -0
  20. package/dist/features/picker/composition/PickerHeader.js.map +1 -0
  21. package/dist/features/tabletop/meta.d.ts +46 -46
  22. package/dist/features/tabletop/meta.d.ts.map +1 -1
  23. package/dist/features/tabletop/meta.js +33 -58
  24. package/dist/features/tabletop/meta.js.map +1 -1
  25. package/dist/features/time-picker/composition/TimePickerContent.js +1 -12
  26. package/dist/features/time-picker/composition/TimePickerContent.js.map +1 -1
  27. package/dist/features/time-picker/composition/TimePickerField.d.ts.map +1 -1
  28. package/dist/features/time-picker/composition/TimePickerField.js +2 -17
  29. package/dist/features/time-picker/composition/TimePickerField.js.map +1 -1
  30. package/dist/features/typography/utils/headingThemeRecipeMeta.d.ts +5 -5
  31. package/dist/features/typography/utils/headingThemeRecipeMeta.d.ts.map +1 -1
  32. package/dist/features/typography/utils/headingThemeRecipeMeta.js +2 -19
  33. package/dist/features/typography/utils/headingThemeRecipeMeta.js.map +1 -1
  34. package/dist/features/typography/utils/resolveHeadingRecipe.d.ts.map +1 -1
  35. package/dist/features/typography/utils/resolveHeadingRecipe.js +11 -68
  36. package/dist/features/typography/utils/resolveHeadingRecipe.js.map +1 -1
  37. package/dist/features/typography/utils/resolveHeadingThemeRecipe.d.ts +4 -4
  38. package/dist/features/typography/utils/resolveHeadingThemeRecipe.d.ts.map +1 -1
  39. package/dist/features/typography/utils/resolveHeadingThemeRecipe.js +2 -33
  40. package/dist/features/typography/utils/resolveHeadingThemeRecipe.js.map +1 -1
  41. package/dist/features/typography/utils/resolveTextStyle.d.ts.map +1 -1
  42. package/dist/features/typography/utils/resolveTextStyle.js +11 -76
  43. package/dist/features/typography/utils/resolveTextStyle.js.map +1 -1
  44. package/dist/features/typography/utils/resolveTextThemeRecipe.d.ts +4 -4
  45. package/dist/features/typography/utils/resolveTextThemeRecipe.d.ts.map +1 -1
  46. package/dist/features/typography/utils/resolveTextThemeRecipe.js +2 -33
  47. package/dist/features/typography/utils/resolveTextThemeRecipe.js.map +1 -1
  48. package/dist/features/typography/utils/resolveTypographyStyleTokens.d.ts +21 -0
  49. package/dist/features/typography/utils/resolveTypographyStyleTokens.d.ts.map +1 -0
  50. package/dist/features/typography/utils/resolveTypographyStyleTokens.js +75 -0
  51. package/dist/features/typography/utils/resolveTypographyStyleTokens.js.map +1 -0
  52. package/dist/features/typography/utils/resolveTypographyThemeRecipeFields.d.ts +10 -0
  53. package/dist/features/typography/utils/resolveTypographyThemeRecipeFields.d.ts.map +1 -0
  54. package/dist/features/typography/utils/resolveTypographyThemeRecipeFields.js +19 -0
  55. package/dist/features/typography/utils/resolveTypographyThemeRecipeFields.js.map +1 -0
  56. package/dist/features/typography/utils/textThemeRecipeMeta.d.ts +6 -6
  57. package/dist/features/typography/utils/textThemeRecipeMeta.d.ts.map +1 -1
  58. package/dist/features/typography/utils/textThemeRecipeMeta.js +2 -19
  59. package/dist/features/typography/utils/textThemeRecipeMeta.js.map +1 -1
  60. package/dist/features/typography/utils/typographyThemeRecipeFields.d.ts +30 -0
  61. package/dist/features/typography/utils/typographyThemeRecipeFields.d.ts.map +1 -0
  62. package/dist/features/typography/utils/typographyThemeRecipeFields.js +23 -0
  63. package/dist/features/typography/utils/typographyThemeRecipeFields.js.map +1 -0
  64. package/dist/features/uploader/adapters/inbound/Uploader.d.ts.map +1 -1
  65. package/dist/features/uploader/adapters/inbound/Uploader.js +1 -16
  66. package/dist/features/uploader/adapters/inbound/Uploader.js.map +1 -1
  67. package/dist/features/uploader/application/use-cases/validateUploadAsset.d.ts.map +1 -1
  68. package/dist/features/uploader/application/use-cases/validateUploadAsset.js +1 -16
  69. package/dist/features/uploader/application/use-cases/validateUploadAsset.js.map +1 -1
  70. package/dist/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.d.ts.map +1 -1
  71. package/dist/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.js +3 -4
  72. package/dist/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.js.map +1 -1
  73. package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.d.ts +8 -0
  74. package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.d.ts.map +1 -0
  75. package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.js +10 -0
  76. package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.js.map +1 -0
  77. package/dist/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.d.ts.map +1 -1
  78. package/dist/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.js +4 -6
  79. package/dist/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.js.map +1 -1
  80. package/package.json +14 -4
  81. package/src/features/date-picker/composition/DatePickerContent.tsx +1 -22
  82. package/src/features/date-picker/composition/DatePickerField.tsx +2 -31
  83. package/src/features/matrix-grid/application/getMatrixGridNextFocusId.ts +11 -22
  84. package/src/features/picker/composition/PickerField.tsx +61 -0
  85. package/src/features/picker/composition/PickerHeader.tsx +25 -0
  86. package/src/features/tabletop/meta.ts +34 -58
  87. package/src/features/time-picker/composition/TimePickerContent.tsx +1 -23
  88. package/src/features/time-picker/composition/TimePickerField.tsx +2 -31
  89. package/src/features/typography/utils/headingThemeRecipeMeta.ts +2 -19
  90. package/src/features/typography/utils/resolveHeadingRecipe.ts +12 -88
  91. package/src/features/typography/utils/resolveHeadingThemeRecipe.ts +3 -39
  92. package/src/features/typography/utils/resolveTextStyle.ts +10 -98
  93. package/src/features/typography/utils/resolveTextThemeRecipe.ts +3 -39
  94. package/src/features/typography/utils/resolveTypographyStyleTokens.ts +113 -0
  95. package/src/features/typography/utils/resolveTypographyThemeRecipeFields.ts +27 -0
  96. package/src/features/typography/utils/textThemeRecipeMeta.ts +2 -19
  97. package/src/features/typography/utils/typographyThemeRecipeFields.ts +23 -0
  98. package/src/features/uploader/adapters/inbound/Uploader.tsx +1 -20
  99. package/src/features/uploader/application/use-cases/validateUploadAsset.test.ts +2 -2
  100. package/src/features/uploader/application/use-cases/validateUploadAsset.ts +2 -20
  101. package/src/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.ts +3 -6
  102. package/src/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.ts +18 -0
  103. package/src/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.ts +4 -8
  104. package/src/webPackageExports.test.ts +101 -0
  105. package/web-dist/chunks/{Accordion-rqr10gn4.js → Accordion-1495be5z.js} +2 -2
  106. package/web-dist/chunks/{Accordion-m2hcc8g4.js → Accordion-3qphhsb4.js} +1 -1
  107. package/web-dist/chunks/{Accordion-gn8ptzwb.js → Accordion-4x8gdqqs.js} +1 -1
  108. package/web-dist/chunks/{Accordion-9aczb0k2.js → Accordion-58bpmzdj.js} +2 -2
  109. package/web-dist/chunks/{Accordion-2jy53kzk.js → Accordion-69c4pfz2.js} +2 -2
  110. package/web-dist/chunks/{Accordion-rqhh2m5b.js → Accordion-7n93d7fa.js} +1 -1
  111. package/web-dist/chunks/{Accordion-m6mp8aea.js → Accordion-a42brn0p.js} +1 -1
  112. package/web-dist/chunks/{Accordion-g08740h4.js → Accordion-c912kzs0.js} +1 -1
  113. package/web-dist/chunks/{Accordion-tyh8jj9d.js → Accordion-cbbafww1.js} +1 -1
  114. package/web-dist/chunks/{Accordion-11ej93t5.js → Accordion-cjjg81ry.js} +2 -2
  115. package/web-dist/chunks/{Accordion-vkd002gw.js → Accordion-d0bebw9j.js} +3 -3
  116. package/web-dist/chunks/{Accordion-vjcd5kxc.js → Accordion-gntmfcmz.js} +1 -1
  117. package/web-dist/chunks/{Accordion-wqyrrptg.js → Accordion-jyemxzat.js} +1 -1
  118. package/web-dist/chunks/{Accordion-p7d5svfq.js → Accordion-kmwhjw1k.js} +1 -1
  119. package/web-dist/chunks/{Accordion-26prtnm7.js → Accordion-ptxa6trg.js} +1 -1
  120. package/web-dist/chunks/{Accordion-4yq92mxp.js → Accordion-ve81xazy.js} +1 -1
  121. package/web-dist/chunks/Accordion-vnb3vntm.js +79 -0
  122. package/web-dist/chunks/{Accordion-9rnsg9pk.js → Accordion-vqx3exsq.js} +129 -243
  123. package/web-dist/chunks/{Accordion-1hbt9k69.js → Accordion-w95t2pr3.js} +1 -1
  124. package/web-dist/chunks/{Accordion-g2aqhct0.js → Accordion-z5dpzw3g.js} +2 -2
  125. package/web-dist/chunks/{Accordion-a4pz3vjj.js → Accordion-zf1g5422.js} +1 -1
  126. package/web-dist/components/accordion/Accordion.js +2 -2
  127. package/web-dist/components/accordion-item/AccordionItem.js +2 -2
  128. package/web-dist/components/app-bar/AppBar.js +2 -2
  129. package/web-dist/components/app-header/AppHeader.js +2 -2
  130. package/web-dist/components/auth-screen/AuthScreen.js +4 -4
  131. package/web-dist/components/avatar/Avatar.js +2 -2
  132. package/web-dist/components/avatar-group/AvatarGroup.js +2 -2
  133. package/web-dist/components/barcode-scanner-view/BarcodeScannerView.js +4 -4
  134. package/web-dist/components/breadcrumbs/Breadcrumbs.js +1 -1
  135. package/web-dist/components/camera-permission-view/CameraPermissionView.js +4 -4
  136. package/web-dist/components/card/Card.js +3 -3
  137. package/web-dist/components/chat-list-item/ChatListItem.js +3 -3
  138. package/web-dist/components/checkbox/Checkbox.js +2 -2
  139. package/web-dist/components/checkbox-group/CheckboxGroup.js +2 -2
  140. package/web-dist/components/chip/Chip.js +2 -2
  141. package/web-dist/components/chip-group/ChipGroup.js +2 -2
  142. package/web-dist/components/collection-editor/CollectionEditor.js +3 -3
  143. package/web-dist/components/content-rail/ContentRail.js +1 -1
  144. package/web-dist/components/data-table/DataTable.js +7 -7
  145. package/web-dist/components/date-picker/DatePicker.js +12 -49
  146. package/web-dist/components/dialog/Dialog.js +2 -2
  147. package/web-dist/components/empty-state/EmptyState.js +4 -4
  148. package/web-dist/components/explorer/Explorer.js +2 -2
  149. package/web-dist/components/field/Field.js +2 -2
  150. package/web-dist/components/file-explorer/FileExplorer.js +2 -2
  151. package/web-dist/components/flat-list/FlatList.js +3 -3
  152. package/web-dist/components/forgot-password-form/ForgotPasswordForm.js +4 -4
  153. package/web-dist/components/form/Form.js +3 -3
  154. package/web-dist/components/form-actions/FormActions.js +3 -3
  155. package/web-dist/components/form-error/FormError.js +3 -3
  156. package/web-dist/components/heading/Heading.js +1 -1
  157. package/web-dist/components/hero/Hero.js +3 -3
  158. package/web-dist/components/list/List.js +3 -3
  159. package/web-dist/components/list-item/ListItem.js +3 -3
  160. package/web-dist/components/list-section/ListSection.js +3 -3
  161. package/web-dist/components/matrix-grid/MatrixGrid.js +5 -17
  162. package/web-dist/components/media-card/MediaCard.js +3 -3
  163. package/web-dist/components/media-explorer/MediaExplorer.js +2 -2
  164. package/web-dist/components/message-bubble/MessageBubble.js +3 -3
  165. package/web-dist/components/metric-card/MetricCard.js +3 -3
  166. package/web-dist/components/missing-element/MissingElement.js +1 -1
  167. package/web-dist/components/o-auth-provider-button/OAuthProviderButton.js +4 -4
  168. package/web-dist/components/o-auth-provider-list/OAuthProviderList.js +4 -4
  169. package/web-dist/components/otp-form/OtpForm.js +4 -4
  170. package/web-dist/components/pagination/Pagination.js +1 -1
  171. package/web-dist/components/palette-item/PaletteItem.js +3 -3
  172. package/web-dist/components/post-card/PostCard.js +3 -3
  173. package/web-dist/components/product-card/ProductCard.js +3 -3
  174. package/web-dist/components/progress/Progress.js +2 -2
  175. package/web-dist/components/progress-ring/ProgressRing.js +2 -2
  176. package/web-dist/components/radio/Radio.js +2 -2
  177. package/web-dist/components/radio-group/RadioGroup.js +2 -2
  178. package/web-dist/components/reader/Reader.js +4 -4
  179. package/web-dist/components/scan-overlay/ScanOverlay.js +4 -4
  180. package/web-dist/components/screen-section/ScreenSection.js +2 -2
  181. package/web-dist/components/section-header/SectionHeader.js +2 -2
  182. package/web-dist/components/section-list/SectionList.js +3 -3
  183. package/web-dist/components/sign-in-form/SignInForm.js +4 -4
  184. package/web-dist/components/sign-up-form/SignUpForm.js +4 -4
  185. package/web-dist/components/skeleton/Skeleton.js +6 -6
  186. package/web-dist/components/skeleton-card/SkeletonCard.js +6 -6
  187. package/web-dist/components/skeleton-list/SkeletonList.js +6 -6
  188. package/web-dist/components/skeleton-text/SkeletonText.js +6 -6
  189. package/web-dist/components/text/Text.js +1 -1
  190. package/web-dist/components/time-picker/TimePicker.js +12 -51
  191. package/web-dist/components/timeline/Timeline.js +1 -1
  192. package/web-dist/components/toolbar/Toolbar.js +3 -3
  193. package/web-dist/components/tree-item/TreeItem.js +3 -3
  194. package/web-dist/components/uploader/Uploader.js +21 -37
  195. package/web-dist/manifest.json +204 -202
@@ -35,8 +35,8 @@ describe('validateUploadAsset', () => {
35
35
  });
36
36
 
37
37
  test('rejects assets above the configured size', () => {
38
- expect(validateUploadAsset({ asset: IMAGE_ASSET, maxSizeBytes: 1_000 })).toContain(
39
- 'File is too large',
38
+ expect(validateUploadAsset({ asset: IMAGE_ASSET, maxSizeBytes: 1_000 })).toBe(
39
+ 'File is too large (2 KB). Max 1000 B.',
40
40
  );
41
41
  });
42
42
 
@@ -1,3 +1,5 @@
1
+ import { formatBytes } from '@ankhorage/utility/number';
2
+
1
3
  import type { ValidateUploadAssetInput } from '../../../../types/upload';
2
4
 
3
5
  /*** Validates a picked upload asset against MIME, extension, size, and caller rules. */
@@ -89,23 +91,3 @@ function parseAccept(accept: string | undefined): readonly string[] {
89
91
  .map((token) => token.trim())
90
92
  .filter((token) => token.length > 0);
91
93
  }
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
- }
@@ -1,9 +1,9 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { readFile, rename, rm, writeFile } from 'node:fs/promises';
3
3
  import { dirname, join, resolve } from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
4
 
6
5
  import { readWebDesiredStateWithNodeAsync } from '../adapters/outbound/node/readWebDesiredStateWithNodeAsync';
6
+ import { readWebComponentPackageMetadataAsync } from './readWebComponentPackageMetadataAsync';
7
7
  import { synchronizeWebComponentArtifactsWithNodeAsync } from './synchronizeWebComponentArtifactsWithNodeAsync';
8
8
 
9
9
  /*** Add one requested web component and regenerate the complete declared set. */
@@ -13,10 +13,7 @@ export async function createWebDesiredStateWithNodeAsync(input: {
13
13
  }) {
14
14
  const desired = await readWebDesiredStateWithNodeAsync(input.projectRoot, true);
15
15
  const components = [...new Set([...desired.components, input.component])].sort();
16
- const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../../..');
17
- const packageJson = JSON.parse(await readFile(resolve(packageRoot, 'package.json'), 'utf8')) as {
18
- readonly version: string;
19
- };
16
+ const { packageRoot, packageVersion } = await readWebComponentPackageMetadataAsync();
20
17
  const desiredPath = resolve(input.projectRoot, 'zora.web.json');
21
18
  const previous = await readFile(desiredPath, 'utf8').catch((error: unknown) => {
22
19
  if (isMissingFile(error)) return undefined;
@@ -29,7 +26,7 @@ export async function createWebDesiredStateWithNodeAsync(input: {
29
26
  components,
30
27
  outputDirectory: resolve(input.projectRoot, '.ankh', 'zora', 'web'),
31
28
  packageRoot,
32
- packageVersion: packageJson.version,
29
+ packageVersion,
33
30
  });
34
31
  } catch (error) {
35
32
  if (next !== previous) {
@@ -0,0 +1,18 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+
5
+ /*** Reads the active ZORA package location and version for generated web artifacts. */
6
+ export async function readWebComponentPackageMetadataAsync(): Promise<WebComponentPackageMetadata> {
7
+ const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../../..');
8
+ const packageJson = JSON.parse(await readFile(resolve(packageRoot, 'package.json'), 'utf8')) as {
9
+ readonly version: string;
10
+ };
11
+
12
+ return { packageRoot, packageVersion: packageJson.version };
13
+ }
14
+
15
+ interface WebComponentPackageMetadata {
16
+ readonly packageRoot: string;
17
+ readonly packageVersion: string;
18
+ }
@@ -1,21 +1,17 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { dirname, resolve } from 'node:path';
3
- import { fileURLToPath } from 'node:url';
1
+ import { resolve } from 'node:path';
4
2
 
5
3
  import { readWebDesiredStateWithNodeAsync } from '../adapters/outbound/node/readWebDesiredStateWithNodeAsync';
4
+ import { readWebComponentPackageMetadataAsync } from './readWebComponentPackageMetadataAsync';
6
5
  import { synchronizeWebComponentArtifactsWithNodeAsync } from './synchronizeWebComponentArtifactsWithNodeAsync';
7
6
 
8
7
  /*** Load project desired state and sync it from the active ZORA package release. */
9
8
  export async function synchronizeDeclaredWebComponentsWithNodeAsync(projectRoot: string) {
10
9
  const desired = await readWebDesiredStateWithNodeAsync(projectRoot, false);
11
- const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../../..');
12
- const packageJson = JSON.parse(await readFile(resolve(packageRoot, 'package.json'), 'utf8')) as {
13
- readonly version: string;
14
- };
10
+ const { packageRoot, packageVersion } = await readWebComponentPackageMetadataAsync();
15
11
  return await synchronizeWebComponentArtifactsWithNodeAsync({
16
12
  components: desired.components,
17
13
  outputDirectory: resolve(projectRoot, '.ankh', 'zora', 'web'),
18
14
  packageRoot,
19
- packageVersion: packageJson.version,
15
+ packageVersion,
20
16
  });
21
17
  }
@@ -0,0 +1,101 @@
1
+ import { mkdtemp, rm, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+
4
+ import { expect, test } from 'bun:test';
5
+ import React from 'react';
6
+ import { renderToStaticMarkup } from 'react-dom/server';
7
+
8
+ const forbiddenWebDependencies = [
9
+ 'expo-document-picker',
10
+ 'expo-image-picker',
11
+ '@gorhom/bottom-sheet',
12
+ 'react-native-gesture-handler',
13
+ ] as const;
14
+
15
+ /** Verifies that stable package web subpaths resolve only their requested UI graph. */
16
+ test('publishes SSR-safe ordinary UI through canonical web subpaths', async () => {
17
+ const packageJson = (await Bun.file('package.json').json()) as {
18
+ readonly exports: Record<string, unknown>;
19
+ };
20
+ expect(packageJson.exports['./web/runtime']).toEqual({
21
+ types: './web-dist/runtime/ZoraProvider.d.ts',
22
+ import: './web-dist/runtime/ZoraProvider.js',
23
+ default: './web-dist/runtime/ZoraProvider.js',
24
+ });
25
+ expect(packageJson.exports['./web/*']).toEqual({
26
+ types: './web-dist/components/*/index.d.ts',
27
+ import: './web-dist/components/*/index.js',
28
+ default: './web-dist/components/*/index.js',
29
+ });
30
+
31
+ const temporaryDirectory = await mkdtemp(join(process.cwd(), '.cache-zora-web-entrypoints-'));
32
+ try {
33
+ const entrypoint = join(temporaryDirectory, 'dashboard.tsx');
34
+ await writeFile(
35
+ entrypoint,
36
+ [
37
+ "export { ZoraProvider } from '@ankhorage/zora/web/runtime';",
38
+ "export { AppBar } from '@ankhorage/zora/web/app-bar';",
39
+ "export { AppShell } from '@ankhorage/zora/web/app-shell';",
40
+ "export { Badge } from '@ankhorage/zora/web/badge';",
41
+ "export { Button } from '@ankhorage/zora/web/button';",
42
+ "export { Card } from '@ankhorage/zora/web/card';",
43
+ "export { DataTable } from '@ankhorage/zora/web/data-table';",
44
+ "export { Dialog } from '@ankhorage/zora/web/dialog';",
45
+ "export { MetricCard } from '@ankhorage/zora/web/metric-card';",
46
+ "export { PopoverMenu } from '@ankhorage/zora/web/popover-menu';",
47
+ "export { Select } from '@ankhorage/zora/web/select';",
48
+ "export { TextInput } from '@ankhorage/zora/web/text-input';",
49
+ "export { Text } from '@ankhorage/zora/web/text';",
50
+ "export { Heading } from '@ankhorage/zora/web/heading';",
51
+ "export { View } from '@ankhorage/zora/web/view';",
52
+ '',
53
+ ].join('\n'),
54
+ 'utf8',
55
+ );
56
+
57
+ const build = await Bun.build({
58
+ entrypoints: [entrypoint],
59
+ target: 'browser',
60
+ format: 'esm',
61
+ external: ['react', 'react/*', 'react-dom', 'react-dom/*'],
62
+ });
63
+ expect(build.success).toBe(true);
64
+ const graph = (await Promise.all(build.outputs.map((output) => output.text()))).join('\n');
65
+ for (const dependency of forbiddenWebDependencies) {
66
+ expect(graph).not.toContain(dependency);
67
+ }
68
+ } finally {
69
+ await rm(temporaryDirectory, { force: true, recursive: true });
70
+ }
71
+ });
72
+
73
+ /** Renders the generated public web entrypoints without a native runtime host. */
74
+ test('SSR-renders ordinary UI from its public web subpaths', async () => {
75
+ const [{ ZoraProvider }, { AppShell }, { Button }, { Screen }, { Text }] = await Promise.all([
76
+ import('@ankhorage/zora/web/runtime'),
77
+ import('@ankhorage/zora/web/app-shell'),
78
+ import('@ankhorage/zora/web/button'),
79
+ import('@ankhorage/zora/web/screen'),
80
+ import('@ankhorage/zora/web/text'),
81
+ ]);
82
+ const markup = renderToStaticMarkup(
83
+ React.createElement(
84
+ ZoraProvider,
85
+ { mode: 'light' },
86
+ React.createElement(
87
+ AppShell,
88
+ undefined,
89
+ React.createElement(
90
+ Screen,
91
+ undefined,
92
+ React.createElement(Text, undefined, 'Web entrypoint'),
93
+ React.createElement(Button, undefined, 'Continue'),
94
+ ),
95
+ ),
96
+ ),
97
+ );
98
+
99
+ expect(markup).toContain('Web entrypoint');
100
+ expect(markup).toContain('Continue');
101
+ });
@@ -18,7 +18,7 @@ import {
18
18
  import {
19
19
  Heading2,
20
20
  Text3
21
- } from "./Accordion-9rnsg9pk.js";
21
+ } from "./Accordion-vqx3exsq.js";
22
22
  import {
23
23
  resolveBadgeRecipe,
24
24
  Badge2
@@ -28,7 +28,7 @@ import {
28
28
  } from "./Accordion-1fsrnq73.js";
29
29
  import {
30
30
  Avatar2
31
- } from "./Accordion-tyh8jj9d.js";
31
+ } from "./Accordion-cbbafww1.js";
32
32
  import {
33
33
  Button2
34
34
  } from "./Accordion-czcaf5x2.js";
@@ -13,7 +13,7 @@ import {
13
13
  } from "./Accordion-799z2zf6.js";
14
14
  import {
15
15
  Text3
16
- } from "./Accordion-9rnsg9pk.js";
16
+ } from "./Accordion-vqx3exsq.js";
17
17
  import {
18
18
  applySelectionIntent
19
19
  } from "./Accordion-n4et7etk.js";
@@ -10,7 +10,7 @@ import {
10
10
  } from "./Accordion-ep35792s.js";
11
11
  import {
12
12
  Text3
13
- } from "./Accordion-9rnsg9pk.js";
13
+ } from "./Accordion-vqx3exsq.js";
14
14
 
15
15
  // src/features/form/field/adapters/inbound/Field.tsx
16
16
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -10,10 +10,10 @@ import {
10
10
  } from "./Accordion-ep35792s.js";
11
11
  import {
12
12
  Text3
13
- } from "./Accordion-9rnsg9pk.js";
13
+ } from "./Accordion-vqx3exsq.js";
14
14
  import {
15
15
  Avatar2
16
- } from "./Accordion-tyh8jj9d.js";
16
+ } from "./Accordion-cbbafww1.js";
17
17
  import {
18
18
  Badge2
19
19
  } from "./Accordion-xgxxg1hz.js";
@@ -7,7 +7,7 @@ import {
7
7
  } from "./Accordion-vj1m2wck.js";
8
8
  import {
9
9
  Text3
10
- } from "./Accordion-9rnsg9pk.js";
10
+ } from "./Accordion-vqx3exsq.js";
11
11
  import {
12
12
  View3
13
13
  } from "./Accordion-z5a0tx18.js";
@@ -23,7 +23,7 @@ import {
23
23
  } from "./Accordion-wyxmd0n0.js";
24
24
  import {
25
25
  SectionHeader2
26
- } from "./Accordion-g08740h4.js";
26
+ } from "./Accordion-c912kzs0.js";
27
27
  import {
28
28
  useZoraTheme2
29
29
  } from "./Accordion-srjya6dz.js";
@@ -21,7 +21,7 @@ import {
21
21
  import {
22
22
  Heading2,
23
23
  Text3
24
- } from "./Accordion-9rnsg9pk.js";
24
+ } from "./Accordion-vqx3exsq.js";
25
25
  import {
26
26
  useZoraTheme2
27
27
  } from "./Accordion-srjya6dz.js";
@@ -10,7 +10,7 @@ import {
10
10
  } from "./Accordion-ep35792s.js";
11
11
  import {
12
12
  Card2
13
- } from "./Accordion-rqr10gn4.js";
13
+ } from "./Accordion-1495be5z.js";
14
14
 
15
15
  // src/features/empty-state/adapters/inbound/EmptyState.tsx
16
16
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -8,7 +8,7 @@ import {
8
8
  import {
9
9
  Heading2,
10
10
  Text3
11
- } from "./Accordion-9rnsg9pk.js";
11
+ } from "./Accordion-vqx3exsq.js";
12
12
 
13
13
  // src/features/section/adapters/inbound/SectionHeader.tsx
14
14
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -10,7 +10,7 @@ import {
10
10
  } from "./Accordion-ep35792s.js";
11
11
  import {
12
12
  Text3
13
- } from "./Accordion-9rnsg9pk.js";
13
+ } from "./Accordion-vqx3exsq.js";
14
14
  import {
15
15
  useZoraTheme2
16
16
  } from "./Accordion-srjya6dz.js";
@@ -10,10 +10,10 @@ import {
10
10
  } from "./Accordion-ep35792s.js";
11
11
  import {
12
12
  Card2
13
- } from "./Accordion-rqr10gn4.js";
13
+ } from "./Accordion-1495be5z.js";
14
14
  import {
15
15
  Text3
16
- } from "./Accordion-9rnsg9pk.js";
16
+ } from "./Accordion-vqx3exsq.js";
17
17
  import {
18
18
  Badge2
19
19
  } from "./Accordion-xgxxg1hz.js";
@@ -15,13 +15,13 @@ import {
15
15
  FormError2,
16
16
  hasRequiredRule,
17
17
  useFormController
18
- } from "./Accordion-wqyrrptg.js";
18
+ } from "./Accordion-jyemxzat.js";
19
19
  import {
20
20
  Text3
21
- } from "./Accordion-9rnsg9pk.js";
21
+ } from "./Accordion-vqx3exsq.js";
22
22
  import {
23
23
  Field2
24
- } from "./Accordion-gn8ptzwb.js";
24
+ } from "./Accordion-4x8gdqqs.js";
25
25
  import {
26
26
  TextInput2
27
27
  } from "./Accordion-y2pss5p0.js";
@@ -24,7 +24,7 @@ import {
24
24
  import {
25
25
  Heading2,
26
26
  Text3
27
- } from "./Accordion-9rnsg9pk.js";
27
+ } from "./Accordion-vqx3exsq.js";
28
28
  import {
29
29
  resolveOverlayAnimation
30
30
  } from "./Accordion-n7y08rz5.js";
@@ -10,7 +10,7 @@ import {
10
10
  } from "./Accordion-ep35792s.js";
11
11
  import {
12
12
  Text3
13
- } from "./Accordion-9rnsg9pk.js";
13
+ } from "./Accordion-vqx3exsq.js";
14
14
  import {
15
15
  useZoraTheme2
16
16
  } from "./Accordion-srjya6dz.js";
@@ -22,7 +22,7 @@ import {
22
22
  } from "./Accordion-ep35792s.js";
23
23
  import {
24
24
  Text3
25
- } from "./Accordion-9rnsg9pk.js";
25
+ } from "./Accordion-vqx3exsq.js";
26
26
  import {
27
27
  Icon2
28
28
  } from "./Accordion-1fsrnq73.js";
@@ -22,7 +22,7 @@ import {
22
22
  } from "./Accordion-ep35792s.js";
23
23
  import {
24
24
  Text3
25
- } from "./Accordion-9rnsg9pk.js";
25
+ } from "./Accordion-vqx3exsq.js";
26
26
  import {
27
27
  resolveFieldState,
28
28
  resolveIndicatorSize,
@@ -13,7 +13,7 @@ import {
13
13
  } from "./Accordion-ep35792s.js";
14
14
  import {
15
15
  Text3
16
- } from "./Accordion-9rnsg9pk.js";
16
+ } from "./Accordion-vqx3exsq.js";
17
17
  import {
18
18
  resolveIconSize
19
19
  } from "./Accordion-961ncx4e.js";
@@ -0,0 +1,79 @@
1
+ 'use client';
2
+ import {
3
+ View2
4
+ } from "./Accordion-ep35792s.js";
5
+ import {
6
+ Text3
7
+ } from "./Accordion-vqx3exsq.js";
8
+ import {
9
+ Field3
10
+ } from "./Accordion-45nc4bte.js";
11
+
12
+ // src/features/picker/composition/PickerHeader.tsx
13
+ import { jsx, jsxs } from "react/jsx-runtime";
14
+ function PickerHeader({ description, title }) {
15
+ return /* @__PURE__ */ jsxs(View2, {
16
+ gap: "xxs",
17
+ children: [
18
+ /* @__PURE__ */ jsx(Text3, {
19
+ align: "center",
20
+ variant: "label",
21
+ weight: "semiBold",
22
+ children: title
23
+ }),
24
+ description ? /* @__PURE__ */ jsx(Text3, {
25
+ align: "center",
26
+ emphasis: "muted",
27
+ variant: "bodySmall",
28
+ children: description
29
+ }) : null
30
+ ]
31
+ });
32
+ }
33
+
34
+ // src/features/picker/composition/PickerField.tsx
35
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
36
+ function PickerField({
37
+ children,
38
+ description,
39
+ disabled,
40
+ error,
41
+ label,
42
+ required,
43
+ testID
44
+ }) {
45
+ return /* @__PURE__ */ jsx2(Field3, {
46
+ disabled,
47
+ errorText: error,
48
+ invalid: Boolean(error),
49
+ label: label ? /* @__PURE__ */ jsx2(PickerFieldLabel, {
50
+ description,
51
+ label
52
+ }) : undefined,
53
+ required,
54
+ testID,
55
+ children
56
+ });
57
+ }
58
+ function PickerFieldLabel({
59
+ description,
60
+ label
61
+ }) {
62
+ return /* @__PURE__ */ jsxs2(View2, {
63
+ gap: "xs",
64
+ children: [
65
+ /* @__PURE__ */ jsx2(Text3, {
66
+ variant: "label",
67
+ weight: "semiBold",
68
+ children: label
69
+ }),
70
+ description ? /* @__PURE__ */ jsx2(Text3, {
71
+ emphasis: "muted",
72
+ variant: "bodySmall",
73
+ children: description
74
+ }) : null
75
+ ]
76
+ });
77
+ }
78
+
79
+ export { PickerHeader, PickerField };