@ankhorage/zora 25.8.15 → 25.8.17

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 -14
  81. package/src/expo57Migration.test.ts +50 -0
  82. package/src/features/date-picker/composition/DatePickerContent.tsx +1 -22
  83. package/src/features/date-picker/composition/DatePickerField.tsx +2 -31
  84. package/src/features/matrix-grid/application/getMatrixGridNextFocusId.ts +11 -22
  85. package/src/features/picker/composition/PickerField.tsx +61 -0
  86. package/src/features/picker/composition/PickerHeader.tsx +25 -0
  87. package/src/features/tabletop/meta.ts +34 -58
  88. package/src/features/time-picker/composition/TimePickerContent.tsx +1 -23
  89. package/src/features/time-picker/composition/TimePickerField.tsx +2 -31
  90. package/src/features/typography/utils/headingThemeRecipeMeta.ts +2 -19
  91. package/src/features/typography/utils/resolveHeadingRecipe.ts +12 -88
  92. package/src/features/typography/utils/resolveHeadingThemeRecipe.ts +3 -39
  93. package/src/features/typography/utils/resolveTextStyle.ts +10 -98
  94. package/src/features/typography/utils/resolveTextThemeRecipe.ts +3 -39
  95. package/src/features/typography/utils/resolveTypographyStyleTokens.ts +113 -0
  96. package/src/features/typography/utils/resolveTypographyThemeRecipeFields.ts +27 -0
  97. package/src/features/typography/utils/textThemeRecipeMeta.ts +2 -19
  98. package/src/features/typography/utils/typographyThemeRecipeFields.ts +23 -0
  99. package/src/features/uploader/adapters/inbound/Uploader.tsx +1 -20
  100. package/src/features/uploader/application/use-cases/validateUploadAsset.test.ts +2 -2
  101. package/src/features/uploader/application/use-cases/validateUploadAsset.ts +2 -20
  102. package/src/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.ts +3 -6
  103. package/src/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.ts +18 -0
  104. package/src/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.ts +4 -8
  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
@@ -0,0 +1,113 @@
1
+ import type { FontWeight, RoleSemantics, SurfaceTheme } from '@ankhorage/surface';
2
+
3
+ import type { ZoraColor, ZoraEmphasis } from '../../../types/theme';
4
+
5
+ /*** Resolves the Surface-derived style tokens shared by Heading and Text. */
6
+ export function resolveTypographyStyleTokens({
7
+ theme,
8
+ color,
9
+ emphasis,
10
+ weight,
11
+ italic,
12
+ }: ResolveTypographyStyleTokensInput): ResolveTypographyStyleTokensOutput {
13
+ const role = color ? resolveRoleSemantics(theme, color) : undefined;
14
+ const fontWeight = resolveWeight(theme, weight);
15
+
16
+ return {
17
+ color: role
18
+ ? emphasis === 'inverse'
19
+ ? role.onSolidText
20
+ : role.base
21
+ : resolveEmphasisColor(theme, emphasis),
22
+ fontFamily: resolveFontFamily(theme, fontWeight, italic),
23
+ fontWeight,
24
+ };
25
+ }
26
+
27
+ interface ResolveTypographyStyleTokensInput {
28
+ readonly theme: SurfaceTheme;
29
+ readonly color: TypographyColor | undefined;
30
+ readonly emphasis: TypographyEmphasis;
31
+ readonly weight: TypographyWeight;
32
+ readonly italic: boolean;
33
+ }
34
+
35
+ interface ResolveTypographyStyleTokensOutput {
36
+ readonly color: string;
37
+ readonly fontFamily: string | undefined;
38
+ readonly fontWeight: FontWeight;
39
+ }
40
+
41
+ type TypographyColor = ZoraColor;
42
+ type TypographyEmphasis = ZoraEmphasis;
43
+ type TypographyWeight = 'regular' | 'medium' | 'semiBold' | 'bold';
44
+
45
+ function resolveRoleSemantics(theme: SurfaceTheme, color: TypographyColor): RoleSemantics {
46
+ switch (color) {
47
+ case 'secondary':
48
+ return theme.semantics.secondary;
49
+ case 'tertiary':
50
+ return theme.semantics.accent;
51
+ case 'quaternary':
52
+ return theme.semantics.highlight;
53
+ case 'neutral':
54
+ return theme.semantics.action.neutral;
55
+ case 'error':
56
+ return theme.semantics.error;
57
+ case 'info':
58
+ return theme.semantics.info;
59
+ case 'danger':
60
+ return theme.semantics.action.danger;
61
+ case 'success':
62
+ return theme.semantics.success;
63
+ case 'warning':
64
+ return theme.semantics.warning;
65
+ case 'primary':
66
+ default:
67
+ return theme.semantics.action.primary;
68
+ }
69
+ }
70
+
71
+ function resolveEmphasisColor(theme: SurfaceTheme, emphasis: TypographyEmphasis): string {
72
+ switch (emphasis) {
73
+ case 'muted':
74
+ return theme.semantics.content.muted;
75
+ case 'subtle':
76
+ return theme.semantics.content.subtle;
77
+ case 'inverse':
78
+ return theme.semantics.content.inverse;
79
+ case 'default':
80
+ default:
81
+ return theme.semantics.content.default;
82
+ }
83
+ }
84
+
85
+ function resolveWeight(theme: SurfaceTheme, weight: TypographyWeight): FontWeight {
86
+ switch (weight) {
87
+ case 'medium':
88
+ return theme.typography.weights.medium;
89
+ case 'semiBold':
90
+ return theme.typography.weights.semiBold;
91
+ case 'bold':
92
+ return theme.typography.weights.bold;
93
+ case 'regular':
94
+ default:
95
+ return theme.typography.weights.regular;
96
+ }
97
+ }
98
+
99
+ function resolveFontFamily(
100
+ theme: SurfaceTheme,
101
+ weight: FontWeight,
102
+ italic: boolean,
103
+ ): string | undefined {
104
+ const fonts = italic ? theme.typography.fonts.italic : theme.typography.fonts.normal;
105
+
106
+ for (const [fontWeight, fontFamily] of Object.entries(fonts)) {
107
+ if (fontWeight === weight) {
108
+ return fontFamily;
109
+ }
110
+ }
111
+
112
+ return undefined;
113
+ }
@@ -0,0 +1,27 @@
1
+ import type { ThemeRecipeOverrideValue } from '@ankhorage/contracts';
2
+
3
+ import { ZORA_COLORS, ZORA_EMPHASES } from '../../theme/colorModel';
4
+
5
+ const ALIGNMENTS = ['auto', 'left', 'right', 'center', 'justify'] as const;
6
+ const WEIGHTS = ['regular', 'medium', 'semiBold', 'bold'] as const;
7
+
8
+ /*** Resolves the common scalar presentation fields in Typography theme recipes. */
9
+ export function resolveTypographyThemeRecipeFields(
10
+ fields: Readonly<Record<string, ThemeRecipeOverrideValue>>,
11
+ ) {
12
+ return {
13
+ color: readChoice(fields.color, ZORA_COLORS),
14
+ emphasis: readChoice(fields.emphasis, ZORA_EMPHASES),
15
+ align: readChoice(fields.align, ALIGNMENTS),
16
+ weight: readChoice(fields.weight, WEIGHTS),
17
+ italic: typeof fields.italic === 'boolean' ? fields.italic : undefined,
18
+ };
19
+ }
20
+
21
+ function readChoice<T extends string>(
22
+ value: ThemeRecipeOverrideValue | undefined,
23
+ choices: readonly T[],
24
+ ): T | undefined {
25
+ if (typeof value !== 'string') return undefined;
26
+ return choices.find((choice) => choice === value);
27
+ }
@@ -1,5 +1,5 @@
1
1
  import type { ZoraThemeRecipeMeta } from '../../../types/theme-recipe';
2
- import { ZORA_COLORS, ZORA_EMPHASES } from '../../theme/colorModel';
2
+ import { typographyThemeRecipeFields } from './typographyThemeRecipeFields';
3
3
 
4
4
  export const textThemeRecipeMeta = {
5
5
  name: 'Text',
@@ -12,23 +12,6 @@ export const textThemeRecipeMeta = {
12
12
  options: ['body', 'lead', 'bodySmall', 'caption', 'label', 'eyebrow', 'code'],
13
13
  default: 'body',
14
14
  },
15
- color: { type: 'choice', label: 'Color', options: ZORA_COLORS },
16
- emphasis: {
17
- type: 'choice',
18
- label: 'Emphasis',
19
- options: ZORA_EMPHASES,
20
- default: 'default',
21
- },
22
- align: {
23
- type: 'choice',
24
- label: 'Align',
25
- options: ['auto', 'left', 'right', 'center', 'justify'],
26
- },
27
- weight: {
28
- type: 'choice',
29
- label: 'Weight',
30
- options: ['regular', 'medium', 'semiBold', 'bold'],
31
- },
32
- italic: { type: 'boolean', label: 'Italic', default: false },
15
+ ...typographyThemeRecipeFields,
33
16
  },
34
17
  } as const satisfies ZoraThemeRecipeMeta;
@@ -0,0 +1,23 @@
1
+ import { ZORA_COLORS, ZORA_EMPHASES } from '../../theme/colorModel';
2
+
3
+ /*** Defines the common presentation fields used by Typography theme recipes. */
4
+ export const typographyThemeRecipeFields = {
5
+ color: { type: 'choice', label: 'Color', options: ZORA_COLORS },
6
+ emphasis: {
7
+ type: 'choice',
8
+ label: 'Emphasis',
9
+ options: ZORA_EMPHASES,
10
+ default: 'default',
11
+ },
12
+ align: {
13
+ type: 'choice',
14
+ label: 'Align',
15
+ options: ['auto', 'left', 'right', 'center', 'justify'],
16
+ },
17
+ weight: {
18
+ type: 'choice',
19
+ label: 'Weight',
20
+ options: ['regular', 'medium', 'semiBold', 'bold'],
21
+ },
22
+ italic: { type: 'boolean', label: 'Italic', default: false },
23
+ } as const;
@@ -1,3 +1,4 @@
1
+ import { formatBytes } from '@ankhorage/utility/number';
1
2
  import React from 'react';
2
3
 
3
4
  import type { UploadAsset, UploaderProps, UploadType } from '../../../../types/upload';
@@ -445,23 +446,3 @@ function formatUnknownError(error: unknown): string {
445
446
 
446
447
  return 'Something went wrong.';
447
448
  }
448
-
449
- /*** Formats an upload byte limit for concise helper text. */
450
- function formatBytes(value: number): string {
451
- if (!Number.isFinite(value) || value <= 0) {
452
- return '0 B';
453
- }
454
-
455
- const units = ['B', 'KB', 'MB', 'GB'] as const;
456
- let size = value;
457
- let unitIndex = 0;
458
-
459
- while (size >= 1024 && unitIndex < units.length - 1) {
460
- size /= 1024;
461
- unitIndex += 1;
462
- }
463
-
464
- const unit = units.at(unitIndex) ?? 'B';
465
- const rounded = unitIndex === 0 ? Math.round(size) : Math.round(size * 10) / 10;
466
- return `${rounded} ${unit}`;
467
- }
@@ -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
  }
@@ -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 };