@ankhorage/zora 10.0.0 → 12.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.
Files changed (401) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +2 -1
  3. package/dist/constants.d.ts +4 -0
  4. package/dist/constants.d.ts.map +1 -1
  5. package/dist/constants.js +4 -0
  6. package/dist/constants.js.map +1 -1
  7. package/dist/features/bottom-sheet/bottomSheetMeta.d.ts +1 -1
  8. package/dist/features/card/cardMeta.d.ts +1 -1
  9. package/dist/features/card/mediaCardMeta.d.ts +1 -1
  10. package/dist/features/card/postCardMeta.d.ts +1 -1
  11. package/dist/features/data-table/adapters/inbound/DataTable.d.ts.map +1 -1
  12. package/dist/features/data-table/adapters/inbound/DataTable.js +1 -1
  13. package/dist/features/data-table/adapters/inbound/DataTable.js.map +1 -1
  14. package/dist/{components/date-picker → features/date-picker/adapters/inbound}/DatePicker.d.ts +1 -1
  15. package/dist/features/date-picker/adapters/inbound/DatePicker.d.ts.map +1 -0
  16. package/dist/{components/date-picker → features/date-picker/adapters/inbound}/DatePicker.js +23 -26
  17. package/dist/features/date-picker/adapters/inbound/DatePicker.js.map +1 -0
  18. package/dist/features/date-picker/datePickerMeta.d.ts +83 -0
  19. package/dist/features/date-picker/datePickerMeta.d.ts.map +1 -0
  20. package/dist/features/date-picker/datePickerMeta.js +57 -0
  21. package/dist/features/date-picker/datePickerMeta.js.map +1 -0
  22. package/dist/features/date-picker/public.d.ts +3 -0
  23. package/dist/features/date-picker/public.d.ts.map +1 -0
  24. package/dist/features/date-picker/public.js +2 -0
  25. package/dist/features/date-picker/public.js.map +1 -0
  26. package/dist/features/date-picker/utils/localDate.d.ts +5 -0
  27. package/dist/features/date-picker/utils/localDate.d.ts.map +1 -0
  28. package/dist/features/date-picker/utils/localDate.js +27 -0
  29. package/dist/features/date-picker/utils/localDate.js.map +1 -0
  30. package/dist/features/form/adapters/inbound/Form.d.ts +5 -0
  31. package/dist/features/form/adapters/inbound/Form.d.ts.map +1 -0
  32. package/dist/features/form/adapters/inbound/Form.js +18 -0
  33. package/dist/features/form/adapters/inbound/Form.js.map +1 -0
  34. package/dist/{components/form → features/form/adapters/inbound}/FormActions.d.ts +1 -1
  35. package/dist/features/form/adapters/inbound/FormActions.d.ts.map +1 -0
  36. package/dist/{components/form → features/form/adapters/inbound}/FormActions.js +3 -3
  37. package/dist/features/form/adapters/inbound/FormActions.js.map +1 -0
  38. package/dist/features/form/adapters/inbound/FormError.d.ts +5 -0
  39. package/dist/features/form/adapters/inbound/FormError.d.ts.map +1 -0
  40. package/dist/features/form/adapters/inbound/FormError.js +18 -0
  41. package/dist/features/form/adapters/inbound/FormError.js.map +1 -0
  42. package/dist/features/form/adapters/inbound/FormField.d.ts +5 -0
  43. package/dist/features/form/adapters/inbound/FormField.d.ts.map +1 -0
  44. package/dist/{patterns/form-field → features/form/adapters/inbound}/FormField.js +5 -4
  45. package/dist/features/form/adapters/inbound/FormField.js.map +1 -0
  46. package/dist/features/form/formActionsMeta.d.ts +9 -0
  47. package/dist/features/form/formActionsMeta.d.ts.map +1 -0
  48. package/dist/features/form/formActionsMeta.js +9 -0
  49. package/dist/features/form/formActionsMeta.js.map +1 -0
  50. package/dist/features/form/formErrorMeta.d.ts +32 -0
  51. package/dist/features/form/formErrorMeta.d.ts.map +1 -0
  52. package/dist/features/form/formErrorMeta.js +19 -0
  53. package/dist/features/form/formErrorMeta.js.map +1 -0
  54. package/dist/{components/form/meta.d.ts → features/form/formFieldMeta.d.ts} +28 -39
  55. package/dist/features/form/formFieldMeta.d.ts.map +1 -0
  56. package/dist/features/form/formFieldMeta.js +35 -0
  57. package/dist/features/form/formFieldMeta.js.map +1 -0
  58. package/dist/features/form/formMeta.d.ts +61 -0
  59. package/dist/features/form/formMeta.d.ts.map +1 -0
  60. package/dist/features/form/formMeta.js +34 -0
  61. package/dist/features/form/formMeta.js.map +1 -0
  62. package/dist/features/form/public.d.ts +8 -0
  63. package/dist/features/form/public.d.ts.map +1 -0
  64. package/dist/features/form/public.js +7 -0
  65. package/dist/features/form/public.js.map +1 -0
  66. package/dist/{components → features}/form/useFormController.d.ts +1 -1
  67. package/dist/features/form/useFormController.d.ts.map +1 -0
  68. package/dist/{components → features}/form/useFormController.js +1 -1
  69. package/dist/features/form/useFormController.js.map +1 -0
  70. package/dist/{components/form → features/form/utils}/validation.d.ts +1 -1
  71. package/dist/features/form/utils/validation.d.ts.map +1 -0
  72. package/dist/{components/form → features/form/utils}/validation.js +2 -4
  73. package/dist/features/form/utils/validation.js.map +1 -0
  74. package/dist/{patterns/hero → features/hero/adapters/inbound}/Hero.d.ts +1 -1
  75. package/dist/features/hero/adapters/inbound/Hero.d.ts.map +1 -0
  76. package/dist/{patterns/hero → features/hero/adapters/inbound}/Hero.js +5 -6
  77. package/dist/features/hero/adapters/inbound/Hero.js.map +1 -0
  78. package/dist/{patterns/hero/meta.d.ts → features/hero/heroMeta.d.ts} +1 -1
  79. package/dist/features/hero/heroMeta.d.ts.map +1 -0
  80. package/dist/{patterns/hero/meta.js → features/hero/heroMeta.js} +1 -1
  81. package/dist/features/hero/heroMeta.js.map +1 -0
  82. package/dist/features/hero/public.d.ts +3 -0
  83. package/dist/features/hero/public.d.ts.map +1 -0
  84. package/dist/features/hero/public.js +2 -0
  85. package/dist/features/hero/public.js.map +1 -0
  86. package/dist/features/keyboard-avoiding-view/keyboardAvoidingViewMeta.d.ts +1 -1
  87. package/dist/features/layout/boxMeta.d.ts +1 -1
  88. package/dist/features/layout/containerMeta.d.ts +1 -1
  89. package/dist/features/layout/gridMeta.d.ts +1 -1
  90. package/dist/features/layout/stackMeta.d.ts +1 -1
  91. package/dist/features/list/flatListMeta.d.ts +1 -1
  92. package/dist/features/list/sectionListMeta.d.ts +1 -1
  93. package/dist/{patterns/missing-element → features/missing-element/adapters/inbound}/MissingElement.d.ts +1 -1
  94. package/dist/features/missing-element/adapters/inbound/MissingElement.d.ts.map +1 -0
  95. package/dist/{patterns/missing-element → features/missing-element/adapters/inbound}/MissingElement.js +5 -5
  96. package/dist/features/missing-element/adapters/inbound/MissingElement.js.map +1 -0
  97. package/dist/{patterns/missing-element/meta.d.ts → features/missing-element/missingElementMeta.d.ts} +1 -1
  98. package/dist/features/missing-element/missingElementMeta.d.ts.map +1 -0
  99. package/dist/{patterns/missing-element/meta.js → features/missing-element/missingElementMeta.js} +1 -1
  100. package/dist/features/missing-element/missingElementMeta.js.map +1 -0
  101. package/dist/features/missing-element/public.d.ts +3 -0
  102. package/dist/features/missing-element/public.d.ts.map +1 -0
  103. package/dist/features/missing-element/public.js +2 -0
  104. package/dist/features/missing-element/public.js.map +1 -0
  105. package/dist/{components/skeleton → features/skeleton/adapters/inbound}/Skeleton.d.ts +1 -1
  106. package/dist/features/skeleton/adapters/inbound/Skeleton.d.ts.map +1 -0
  107. package/dist/{components/skeleton → features/skeleton/adapters/inbound}/Skeleton.js +3 -3
  108. package/dist/features/skeleton/adapters/inbound/Skeleton.js.map +1 -0
  109. package/dist/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonCard.d.ts +1 -1
  110. package/dist/features/skeleton/adapters/inbound/SkeletonCard.d.ts.map +1 -0
  111. package/dist/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonCard.js +4 -4
  112. package/dist/features/skeleton/adapters/inbound/SkeletonCard.js.map +1 -0
  113. package/dist/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonList.d.ts +1 -1
  114. package/dist/features/skeleton/adapters/inbound/SkeletonList.d.ts.map +1 -0
  115. package/dist/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonList.js +2 -2
  116. package/dist/features/skeleton/adapters/inbound/SkeletonList.js.map +1 -0
  117. package/dist/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonText.d.ts +1 -1
  118. package/dist/features/skeleton/adapters/inbound/SkeletonText.d.ts.map +1 -0
  119. package/dist/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonText.js +2 -2
  120. package/dist/features/skeleton/adapters/inbound/SkeletonText.js.map +1 -0
  121. package/dist/features/skeleton/public.d.ts +6 -0
  122. package/dist/features/skeleton/public.d.ts.map +1 -0
  123. package/dist/features/skeleton/public.js +5 -0
  124. package/dist/features/skeleton/public.js.map +1 -0
  125. package/dist/features/skeleton/skeletonMeta.d.ts +178 -0
  126. package/dist/features/skeleton/skeletonMeta.d.ts.map +1 -0
  127. package/dist/features/skeleton/skeletonMeta.js +84 -0
  128. package/dist/features/skeleton/skeletonMeta.js.map +1 -0
  129. package/dist/features/surface/surfaceMeta.d.ts +1 -1
  130. package/dist/{components/time-picker → features/time-picker/adapters/inbound}/TimePicker.d.ts +1 -1
  131. package/dist/features/time-picker/adapters/inbound/TimePicker.d.ts.map +1 -0
  132. package/dist/{components/time-picker → features/time-picker/adapters/inbound}/TimePicker.js +8 -11
  133. package/dist/features/time-picker/adapters/inbound/TimePicker.js.map +1 -0
  134. package/dist/features/time-picker/public.d.ts +3 -0
  135. package/dist/features/time-picker/public.d.ts.map +1 -0
  136. package/dist/features/time-picker/public.js +2 -0
  137. package/dist/features/time-picker/public.js.map +1 -0
  138. package/dist/features/time-picker/timePickerMeta.d.ts +90 -0
  139. package/dist/features/time-picker/timePickerMeta.d.ts.map +1 -0
  140. package/dist/features/time-picker/timePickerMeta.js +64 -0
  141. package/dist/features/time-picker/timePickerMeta.js.map +1 -0
  142. package/dist/features/uploader/adapters/inbound/Uploader.d.ts.map +1 -1
  143. package/dist/features/uploader/adapters/inbound/Uploader.js +1 -1
  144. package/dist/features/uploader/adapters/inbound/Uploader.js.map +1 -1
  145. package/dist/index.d.ts +7 -12
  146. package/dist/index.d.ts.map +1 -1
  147. package/dist/index.js +6 -6
  148. package/dist/index.js.map +1 -1
  149. package/dist/layout/screen/meta.d.ts +1 -1
  150. package/dist/layout/screen-section/meta.d.ts +1 -1
  151. package/dist/metadata/allowedChildren.d.ts +3 -3
  152. package/dist/metadata/allowedChildren.d.ts.map +1 -1
  153. package/dist/metadata/allowedChildren.js +8 -1
  154. package/dist/metadata/allowedChildren.js.map +1 -1
  155. package/dist/metadata/bindableComponentMeta.d.ts +2 -2
  156. package/dist/metadata/componentMeta.d.ts.map +1 -1
  157. package/dist/metadata/componentMeta.js +9 -6
  158. package/dist/metadata/componentMeta.js.map +1 -1
  159. package/dist/patterns/auth/AuthForm.d.ts +21 -0
  160. package/dist/patterns/auth/AuthForm.d.ts.map +1 -0
  161. package/dist/patterns/auth/AuthForm.js +19 -0
  162. package/dist/patterns/auth/AuthForm.js.map +1 -0
  163. package/dist/patterns/auth/AuthFormField.d.ts +16 -0
  164. package/dist/patterns/auth/AuthFormField.d.ts.map +1 -0
  165. package/dist/patterns/auth/AuthFormField.js +38 -0
  166. package/dist/patterns/auth/AuthFormField.js.map +1 -0
  167. package/dist/patterns/auth/ForgotPasswordForm.d.ts.map +1 -1
  168. package/dist/patterns/auth/ForgotPasswordForm.js +2 -2
  169. package/dist/patterns/auth/ForgotPasswordForm.js.map +1 -1
  170. package/dist/patterns/auth/OtpForm.d.ts.map +1 -1
  171. package/dist/patterns/auth/OtpForm.js +2 -2
  172. package/dist/patterns/auth/OtpForm.js.map +1 -1
  173. package/dist/patterns/auth/SignInForm.d.ts.map +1 -1
  174. package/dist/patterns/auth/SignInForm.js +2 -2
  175. package/dist/patterns/auth/SignInForm.js.map +1 -1
  176. package/dist/patterns/auth/SignUpForm.d.ts.map +1 -1
  177. package/dist/patterns/auth/SignUpForm.js +2 -2
  178. package/dist/patterns/auth/SignUpForm.js.map +1 -1
  179. package/dist/patterns/auth/types.d.ts +1 -1
  180. package/dist/patterns/auth/types.d.ts.map +1 -1
  181. package/dist/patterns/auth/types.js.map +1 -1
  182. package/dist/patterns/auth/utils.d.ts +1 -1
  183. package/dist/patterns/auth/utils.d.ts.map +1 -1
  184. package/dist/patterns/auth/utils.js.map +1 -1
  185. package/dist/patterns/inspector-field/InspectorField.js +1 -1
  186. package/dist/patterns/inspector-field/InspectorField.js.map +1 -1
  187. package/dist/patterns/message-bubble/meta.d.ts +1 -1
  188. package/dist/patterns/notice/meta.d.ts +1 -1
  189. package/dist/patterns/panel/meta.d.ts +1 -1
  190. package/dist/patterns/reader/meta.d.ts +2 -2
  191. package/dist/patterns/scanner/meta.d.ts +2 -2
  192. package/dist/registry.js +6 -6
  193. package/dist/registry.js.map +1 -1
  194. package/dist/{components/date-picker/types.d.ts → types/date-picker.d.ts} +6 -6
  195. package/dist/types/date-picker.d.ts.map +1 -0
  196. package/dist/types/date-picker.js +2 -0
  197. package/dist/types/date-picker.js.map +1 -0
  198. package/dist/{components/form/types.d.ts → types/form.d.ts} +12 -28
  199. package/dist/types/form.d.ts.map +1 -0
  200. package/dist/types/form.js +2 -0
  201. package/dist/types/form.js.map +1 -0
  202. package/dist/{patterns/hero/types.d.ts → types/hero.d.ts} +3 -3
  203. package/dist/types/hero.d.ts.map +1 -0
  204. package/dist/types/hero.js +2 -0
  205. package/dist/types/hero.js.map +1 -0
  206. package/dist/{patterns/missing-element/types.d.ts → types/missing-element.d.ts} +2 -2
  207. package/dist/types/missing-element.d.ts.map +1 -0
  208. package/dist/types/missing-element.js +2 -0
  209. package/dist/types/missing-element.js.map +1 -0
  210. package/dist/{components/skeleton/types.d.ts → types/skeleton.d.ts} +3 -3
  211. package/dist/types/skeleton.d.ts.map +1 -0
  212. package/dist/types/skeleton.js +2 -0
  213. package/dist/types/skeleton.js.map +1 -0
  214. package/dist/{components/time-picker/types.d.ts → types/time-picker.d.ts} +2 -2
  215. package/dist/types/time-picker.d.ts.map +1 -0
  216. package/dist/types/time-picker.js +2 -0
  217. package/dist/types/time-picker.js.map +1 -0
  218. package/package.json +2 -1
  219. package/src/audit.test.ts +2 -4
  220. package/src/constants.ts +4 -0
  221. package/src/featureManifest.test.ts +19 -0
  222. package/src/features/bottom-sheet/public.test.ts +2 -2
  223. package/src/features/data-table/adapters/inbound/DataTable.tsx +1 -1
  224. package/src/{components/date-picker → features/date-picker/adapters/inbound}/DatePicker.tsx +41 -32
  225. package/src/features/date-picker/datePickerMeta.ts +58 -0
  226. package/src/features/date-picker/public.test.ts +15 -0
  227. package/src/features/date-picker/public.ts +2 -0
  228. package/src/features/date-picker/utils/localDate.test.ts +18 -0
  229. package/src/features/date-picker/utils/localDate.ts +29 -0
  230. package/src/features/form/adapters/inbound/Form.tsx +39 -0
  231. package/src/{components/form → features/form/adapters/inbound}/FormActions.tsx +4 -4
  232. package/src/features/form/adapters/inbound/FormError.tsx +22 -0
  233. package/src/{patterns/form-field → features/form/adapters/inbound}/FormField.tsx +6 -4
  234. package/src/{components/date-picker/meta.ts → features/form/formActionsMeta.ts} +3 -4
  235. package/src/features/form/formErrorMeta.ts +19 -0
  236. package/src/features/form/formFieldMeta.ts +35 -0
  237. package/src/features/form/formMeta.ts +34 -0
  238. package/src/{components/form/index.ts → features/form/public.ts} +6 -7
  239. package/src/{components → features}/form/useFormController.ts +2 -2
  240. package/src/{components/form → features/form/utils}/validation.test.ts +4 -1
  241. package/src/{components/form → features/form/utils}/validation.ts +4 -8
  242. package/src/{patterns/hero → features/hero/adapters/inbound}/Hero.tsx +6 -7
  243. package/src/features/hero/public.ts +2 -0
  244. package/src/{patterns → features}/missing-element/MissingElement.test.ts +6 -4
  245. package/src/{patterns/missing-element → features/missing-element/adapters/inbound}/MissingElement.tsx +6 -6
  246. package/src/features/missing-element/public.ts +2 -0
  247. package/src/{components/skeleton → features/skeleton/adapters/inbound}/Skeleton.tsx +4 -4
  248. package/src/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonCard.tsx +5 -5
  249. package/src/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonList.tsx +3 -3
  250. package/src/{components/skeleton → features/skeleton/adapters/inbound}/SkeletonText.tsx +3 -3
  251. package/src/features/skeleton/public.test.ts +24 -0
  252. package/src/features/skeleton/public.ts +13 -0
  253. package/src/features/skeleton/skeletonMeta.ts +88 -0
  254. package/src/{components/time-picker → features/time-picker/adapters/inbound}/TimePicker.tsx +9 -12
  255. package/src/features/time-picker/public.test.ts +14 -0
  256. package/src/features/time-picker/public.ts +2 -0
  257. package/src/features/time-picker/timePickerMeta.ts +65 -0
  258. package/src/features/uploader/adapters/inbound/Uploader.tsx +1 -1
  259. package/src/index.ts +58 -45
  260. package/src/interactionPolicy.test.ts +3 -3
  261. package/src/metadata/allowedChildren.ts +8 -1
  262. package/src/metadata/componentMeta.test.ts +24 -1
  263. package/src/metadata/componentMeta.ts +14 -11
  264. package/src/patterns/auth/AuthForm.tsx +68 -0
  265. package/src/patterns/auth/AuthFormField.tsx +81 -0
  266. package/src/patterns/auth/ForgotPasswordForm.tsx +3 -2
  267. package/src/patterns/auth/OtpForm.tsx +3 -2
  268. package/src/patterns/auth/SignInForm.tsx +3 -2
  269. package/src/patterns/auth/SignUpForm.tsx +3 -2
  270. package/src/patterns/auth/types.ts +1 -1
  271. package/src/patterns/auth/utils.ts +1 -1
  272. package/src/patterns/inspector-field/InspectorField.tsx +1 -1
  273. package/src/registry.ts +6 -6
  274. package/src/theme/themeScopeStructure.test.ts +5 -7
  275. package/src/{components/date-picker/types.ts → types/date-picker.ts} +5 -5
  276. package/src/{components/form/types.ts → types/form.ts} +12 -36
  277. package/src/{patterns/hero/types.ts → types/hero.ts} +2 -2
  278. package/src/{patterns/missing-element/types.ts → types/missing-element.ts} +1 -1
  279. package/src/{components/skeleton/types.ts → types/skeleton.ts} +2 -2
  280. package/src/{components/time-picker/types.ts → types/time-picker.ts} +1 -1
  281. package/dist/components/date-picker/DatePicker.d.ts.map +0 -1
  282. package/dist/components/date-picker/DatePicker.js.map +0 -1
  283. package/dist/components/date-picker/index.d.ts +0 -3
  284. package/dist/components/date-picker/index.d.ts.map +0 -1
  285. package/dist/components/date-picker/index.js +0 -2
  286. package/dist/components/date-picker/index.js.map +0 -1
  287. package/dist/components/date-picker/meta.d.ts +0 -9
  288. package/dist/components/date-picker/meta.d.ts.map +0 -1
  289. package/dist/components/date-picker/meta.js +0 -9
  290. package/dist/components/date-picker/meta.js.map +0 -1
  291. package/dist/components/date-picker/types.d.ts.map +0 -1
  292. package/dist/components/date-picker/types.js +0 -2
  293. package/dist/components/date-picker/types.js.map +0 -1
  294. package/dist/components/form/Form.d.ts +0 -7
  295. package/dist/components/form/Form.d.ts.map +0 -1
  296. package/dist/components/form/Form.js +0 -34
  297. package/dist/components/form/Form.js.map +0 -1
  298. package/dist/components/form/FormActions.d.ts.map +0 -1
  299. package/dist/components/form/FormActions.js.map +0 -1
  300. package/dist/components/form/FormError.d.ts +0 -7
  301. package/dist/components/form/FormError.d.ts.map +0 -1
  302. package/dist/components/form/FormError.js +0 -21
  303. package/dist/components/form/FormError.js.map +0 -1
  304. package/dist/components/form/FormField.d.ts +0 -7
  305. package/dist/components/form/FormField.d.ts.map +0 -1
  306. package/dist/components/form/FormField.js +0 -81
  307. package/dist/components/form/FormField.js.map +0 -1
  308. package/dist/components/form/index.d.ts +0 -8
  309. package/dist/components/form/index.d.ts.map +0 -1
  310. package/dist/components/form/index.js +0 -7
  311. package/dist/components/form/index.js.map +0 -1
  312. package/dist/components/form/meta.d.ts.map +0 -1
  313. package/dist/components/form/meta.js +0 -94
  314. package/dist/components/form/meta.js.map +0 -1
  315. package/dist/components/form/types.d.ts.map +0 -1
  316. package/dist/components/form/types.js +0 -2
  317. package/dist/components/form/types.js.map +0 -1
  318. package/dist/components/form/useFormController.d.ts.map +0 -1
  319. package/dist/components/form/useFormController.js.map +0 -1
  320. package/dist/components/form/validation.d.ts.map +0 -1
  321. package/dist/components/form/validation.js.map +0 -1
  322. package/dist/components/skeleton/Skeleton.d.ts.map +0 -1
  323. package/dist/components/skeleton/Skeleton.js.map +0 -1
  324. package/dist/components/skeleton/SkeletonCard.d.ts.map +0 -1
  325. package/dist/components/skeleton/SkeletonCard.js.map +0 -1
  326. package/dist/components/skeleton/SkeletonList.d.ts.map +0 -1
  327. package/dist/components/skeleton/SkeletonList.js.map +0 -1
  328. package/dist/components/skeleton/SkeletonText.d.ts.map +0 -1
  329. package/dist/components/skeleton/SkeletonText.js.map +0 -1
  330. package/dist/components/skeleton/index.d.ts +0 -6
  331. package/dist/components/skeleton/index.d.ts.map +0 -1
  332. package/dist/components/skeleton/index.js +0 -5
  333. package/dist/components/skeleton/index.js.map +0 -1
  334. package/dist/components/skeleton/meta.d.ts +0 -33
  335. package/dist/components/skeleton/meta.d.ts.map +0 -1
  336. package/dist/components/skeleton/meta.js +0 -33
  337. package/dist/components/skeleton/meta.js.map +0 -1
  338. package/dist/components/skeleton/types.d.ts.map +0 -1
  339. package/dist/components/skeleton/types.js +0 -2
  340. package/dist/components/skeleton/types.js.map +0 -1
  341. package/dist/components/time-picker/TimePicker.d.ts.map +0 -1
  342. package/dist/components/time-picker/TimePicker.js.map +0 -1
  343. package/dist/components/time-picker/index.d.ts +0 -3
  344. package/dist/components/time-picker/index.d.ts.map +0 -1
  345. package/dist/components/time-picker/index.js +0 -2
  346. package/dist/components/time-picker/index.js.map +0 -1
  347. package/dist/components/time-picker/meta.d.ts +0 -9
  348. package/dist/components/time-picker/meta.d.ts.map +0 -1
  349. package/dist/components/time-picker/meta.js +0 -9
  350. package/dist/components/time-picker/meta.js.map +0 -1
  351. package/dist/components/time-picker/types.d.ts.map +0 -1
  352. package/dist/components/time-picker/types.js +0 -2
  353. package/dist/components/time-picker/types.js.map +0 -1
  354. package/dist/patterns/form-field/FormField.d.ts +0 -4
  355. package/dist/patterns/form-field/FormField.d.ts.map +0 -1
  356. package/dist/patterns/form-field/FormField.js.map +0 -1
  357. package/dist/patterns/form-field/index.d.ts +0 -2
  358. package/dist/patterns/form-field/index.d.ts.map +0 -1
  359. package/dist/patterns/form-field/index.js +0 -2
  360. package/dist/patterns/form-field/index.js.map +0 -1
  361. package/dist/patterns/form-field/types.d.ts +0 -9
  362. package/dist/patterns/form-field/types.d.ts.map +0 -1
  363. package/dist/patterns/form-field/types.js +0 -2
  364. package/dist/patterns/form-field/types.js.map +0 -1
  365. package/dist/patterns/hero/Hero.d.ts.map +0 -1
  366. package/dist/patterns/hero/Hero.js.map +0 -1
  367. package/dist/patterns/hero/index.d.ts +0 -3
  368. package/dist/patterns/hero/index.d.ts.map +0 -1
  369. package/dist/patterns/hero/index.js +0 -2
  370. package/dist/patterns/hero/index.js.map +0 -1
  371. package/dist/patterns/hero/meta.d.ts.map +0 -1
  372. package/dist/patterns/hero/meta.js.map +0 -1
  373. package/dist/patterns/hero/types.d.ts.map +0 -1
  374. package/dist/patterns/hero/types.js +0 -2
  375. package/dist/patterns/hero/types.js.map +0 -1
  376. package/dist/patterns/missing-element/MissingElement.d.ts.map +0 -1
  377. package/dist/patterns/missing-element/MissingElement.js.map +0 -1
  378. package/dist/patterns/missing-element/index.d.ts +0 -3
  379. package/dist/patterns/missing-element/index.d.ts.map +0 -1
  380. package/dist/patterns/missing-element/index.js +0 -2
  381. package/dist/patterns/missing-element/index.js.map +0 -1
  382. package/dist/patterns/missing-element/meta.d.ts.map +0 -1
  383. package/dist/patterns/missing-element/meta.js.map +0 -1
  384. package/dist/patterns/missing-element/types.d.ts.map +0 -1
  385. package/dist/patterns/missing-element/types.js +0 -2
  386. package/dist/patterns/missing-element/types.js.map +0 -1
  387. package/src/components/date-picker/index.ts +0 -2
  388. package/src/components/form/Form.tsx +0 -74
  389. package/src/components/form/FormError.tsx +0 -34
  390. package/src/components/form/FormField.tsx +0 -157
  391. package/src/components/form/meta.ts +0 -98
  392. package/src/components/skeleton/index.ts +0 -13
  393. package/src/components/skeleton/meta.ts +0 -37
  394. package/src/components/time-picker/index.ts +0 -2
  395. package/src/components/time-picker/meta.ts +0 -10
  396. package/src/patterns/form-field/index.ts +0 -1
  397. package/src/patterns/form-field/types.ts +0 -16
  398. package/src/patterns/hero/index.ts +0 -2
  399. package/src/patterns/missing-element/index.ts +0 -2
  400. /package/src/{patterns/hero/meta.ts → features/hero/heroMeta.ts} +0 -0
  401. /package/src/{patterns/missing-element/meta.ts → features/missing-element/missingElementMeta.ts} +0 -0
@@ -1,12 +1,13 @@
1
1
  import { Field } from '@ankhorage/surface';
2
2
  import React from 'react';
3
3
 
4
- import { useBottomSheet } from '../../features/bottom-sheet/public';
5
- import { Button } from '../../features/button/public';
6
- import { Box, Stack } from '../../features/layout/public';
7
- import { Text } from '../../features/typography/public';
8
- import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
9
- import type { DatePickerProps } from './types';
4
+ import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
5
+ import type { DatePickerProps } from '../../../../types/date-picker';
6
+ import { useBottomSheet } from '../../../bottom-sheet/public';
7
+ import { Button } from '../../../button/public';
8
+ import { Box, Stack } from '../../../layout/public';
9
+ import { Text } from '../../../typography/public';
10
+ import { formatLocalDate, parseLocalDate } from '../../utils/localDate';
10
11
 
11
12
  const WEEKDAY_LABELS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] as const;
12
13
  const DAY_CELL_WIDTH = 42;
@@ -27,15 +28,14 @@ function renderLabel(label: React.ReactNode, description: React.ReactNode | unde
27
28
  );
28
29
  }
29
30
 
30
- /*** Normalize a date to the start of its local calendar day. */
31
- function startOfLocalDay(value: Date): Date {
32
- return new Date(value.getFullYear(), value.getMonth(), value.getDate());
31
+ /*** Compare two values by local calendar day. */
32
+ function isSameLocalDay(left: string | null, right: Date): boolean {
33
+ return left === formatLocalDate(right);
33
34
  }
34
35
 
35
- /*** Compare two values by local calendar day. */
36
- function isSameLocalDay(left: Date | null, right: Date): boolean {
37
- if (!left) return false;
38
- return startOfLocalDay(left).getTime() === startOfLocalDay(right).getTime();
36
+ /*** Normalize a Date to the start of its local calendar day for range comparisons. */
37
+ function startOfLocalDay(value: Date): Date {
38
+ return new Date(value.getFullYear(), value.getMonth(), value.getDate());
39
39
  }
40
40
 
41
41
  /*** Report whether one local calendar day precedes another. */
@@ -65,28 +65,27 @@ function formatMonthLabel(value: Date): string {
65
65
  }
66
66
 
67
67
  /*** Format a selected date with the platform locale defaults. */
68
- function formatDefaultDate(value: Date): string {
69
- return value.toLocaleDateString();
68
+ function formatDefaultDate(value: string): string {
69
+ return parseLocalDate(value)?.toLocaleDateString() ?? value;
70
70
  }
71
71
 
72
72
  /*** Build the padded calendar grid for one month. */
73
73
  function createMonthDays(month: Date): (Date | null)[] {
74
74
  const firstDay = new Date(month.getFullYear(), month.getMonth(), 1);
75
75
  const dayCount = new Date(month.getFullYear(), month.getMonth() + 1, 0).getDate();
76
- const days: (Date | null)[] = [];
76
+ const populatedLength = firstDay.getDay() + dayCount;
77
+ const paddedLength = Math.ceil(populatedLength / 7) * 7;
77
78
 
78
- for (let offset = 0; offset < firstDay.getDay(); offset += 1) days.push(null);
79
- for (let day = 1; day <= dayCount; day += 1) {
80
- days.push(new Date(month.getFullYear(), month.getMonth(), day));
81
- }
82
- while (days.length % 7 !== 0) days.push(null);
83
-
84
- return days;
79
+ return Array.from({ length: paddedLength }, (_, index) =>
80
+ index < firstDay.getDay()
81
+ ? null
82
+ : new Date(month.getFullYear(), month.getMonth(), index - firstDay.getDay() + 1),
83
+ );
85
84
  }
86
85
 
87
86
  /*** Resolve the month initially shown by the calendar sheet. */
88
- function resolveInitialMonth(value: Date | null, minDate: Date | undefined): Date {
89
- const base = value ?? minDate ?? new Date();
87
+ function resolveInitialMonth(value: string | null, minDate: string | undefined): Date {
88
+ const base = parseLocalDate(value) ?? parseLocalDate(minDate) ?? new Date();
90
89
  return new Date(base.getFullYear(), base.getMonth(), 1);
91
90
  }
92
91
 
@@ -142,7 +141,7 @@ function DatePickerInner({
142
141
  minDate={minDate}
143
142
  onDismiss={dismiss}
144
143
  onSelect={(date) => {
145
- onValueChange?.(startOfLocalDay(date));
144
+ onValueChange?.(formatLocalDate(date));
146
145
  dismiss();
147
146
  }}
148
147
  testID={testID}
@@ -197,6 +196,8 @@ function DatePickerSheet({
197
196
  }: DatePickerSheetProps) {
198
197
  const [displayMonth, setDisplayMonth] = React.useState(() => resolveInitialMonth(value, minDate));
199
198
  const monthDays = React.useMemo(() => createMonthDays(displayMonth), [displayMonth]);
199
+ const resolvedMaxDate = React.useMemo(() => parseLocalDate(maxDate), [maxDate]);
200
+ const resolvedMinDate = React.useMemo(() => parseLocalDate(minDate), [minDate]);
200
201
 
201
202
  return (
202
203
  <Stack gap="m" p="m" testID={testID ? `${testID}-sheet` : undefined}>
@@ -204,15 +205,15 @@ function DatePickerSheet({
204
205
  <DatePickerMonthNavigation
205
206
  displayMonth={displayMonth}
206
207
  interactionPolicy={interactionPolicy}
207
- maxDate={maxDate}
208
- minDate={minDate}
208
+ maxDate={resolvedMaxDate}
209
+ minDate={resolvedMinDate}
209
210
  onMonthChange={setDisplayMonth}
210
211
  />
211
212
  <DatePickerWeekdays />
212
213
  <DatePickerCalendar
213
214
  interactionPolicy={interactionPolicy}
214
- maxDate={maxDate}
215
- minDate={minDate}
215
+ maxDate={resolvedMaxDate}
216
+ minDate={resolvedMinDate}
216
217
  monthDays={monthDays}
217
218
  onSelect={onSelect}
218
219
  testID={testID}
@@ -254,8 +255,11 @@ function DatePickerMonthNavigation({
254
255
  maxDate,
255
256
  minDate,
256
257
  onMonthChange,
257
- }: Pick<DatePickerSheetProps, 'interactionPolicy' | 'maxDate' | 'minDate'> & {
258
+ }: {
258
259
  displayMonth: Date;
260
+ interactionPolicy: DatePickerProps['interactionPolicy'];
261
+ maxDate: Date | undefined;
262
+ minDate: Date | undefined;
259
263
  onMonthChange: (month: Date) => void;
260
264
  }) {
261
265
  const previousMonth = new Date(displayMonth.getFullYear(), displayMonth.getMonth() - 1, 1);
@@ -312,9 +316,14 @@ function DatePickerCalendar({
312
316
  onSelect,
313
317
  testID,
314
318
  value,
315
- }: Pick<DatePickerSheetProps, 'interactionPolicy' | 'maxDate' | 'minDate' | 'testID' | 'value'> & {
319
+ }: {
320
+ interactionPolicy: DatePickerProps['interactionPolicy'];
321
+ maxDate: Date | undefined;
322
+ minDate: Date | undefined;
316
323
  monthDays: readonly (Date | null)[];
317
324
  onSelect: (value: Date) => void;
325
+ testID: string | undefined;
326
+ value: DatePickerProps['value'];
318
327
  }) {
319
328
  return (
320
329
  <Stack direction="row" gap="xs" wrap="wrap">
@@ -0,0 +1,58 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+
3
+ export const datePickerMeta = {
4
+ name: 'DatePicker',
5
+ category: 'component',
6
+ description: 'Captures a local calendar date through the shared BottomSheet picker host.',
7
+ directManifestNode: true,
8
+ allowedChildren: [],
9
+ blueprint: {
10
+ label: 'Date picker',
11
+ defaultProps: {
12
+ value: null,
13
+ placeholder: 'Choose date',
14
+ disabled: false,
15
+ required: false,
16
+ },
17
+ },
18
+ events: {
19
+ valueChange: {
20
+ label: 'Value change',
21
+ eventType: 'datePicker.valueChange',
22
+ description: 'Emitted when a local calendar date is selected.',
23
+ payloadFields: [{ path: 'value', type: 'string', label: 'Value' }],
24
+ },
25
+ },
26
+ props: {
27
+ value: {
28
+ type: 'string',
29
+ category: 'State',
30
+ label: 'Value',
31
+ default: null,
32
+ authoring: { authority: 'instance' },
33
+ },
34
+ label: { type: 'string', category: 'Content', label: 'Label' },
35
+ description: { type: 'string', category: 'Content', label: 'Description' },
36
+ error: { type: 'string', category: 'Validation', label: 'Error' },
37
+ placeholder: {
38
+ type: 'string',
39
+ category: 'Content',
40
+ label: 'Placeholder',
41
+ default: 'Choose date',
42
+ },
43
+ minDate: { type: 'string', category: 'Validation', label: 'Minimum date' },
44
+ maxDate: { type: 'string', category: 'Validation', label: 'Maximum date' },
45
+ disabled: {
46
+ type: 'boolean',
47
+ category: 'State',
48
+ label: 'Disabled',
49
+ default: false,
50
+ },
51
+ required: {
52
+ type: 'boolean',
53
+ category: 'Validation',
54
+ label: 'Required',
55
+ default: false,
56
+ },
57
+ },
58
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,15 @@
1
+ import { expect, test } from 'bun:test';
2
+
3
+ import { ZORA_COMPONENT_META } from '../../metadata/componentMeta';
4
+
5
+ test('DatePicker exposes a serializable manifest contract through the shared BottomSheet', async () => {
6
+ const source = await Bun.file('src/features/date-picker/adapters/inbound/DatePicker.tsx').text();
7
+ const meta = ZORA_COMPONENT_META.DatePicker;
8
+
9
+ expect(meta.directManifestNode).toBe(true);
10
+ expect(meta.props.value?.type).toBe('string');
11
+ expect(meta.events?.valueChange?.eventType).toBe('datePicker.valueChange');
12
+ expect(meta.bindings?.props?.value?.value.type).toBe('string');
13
+ expect(source).toContain('useBottomSheet()');
14
+ expect(source).toContain('formatLocalDate(date)');
15
+ });
@@ -0,0 +1,2 @@
1
+ export type { DatePickerProps, DatePickerValue } from '../../types/date-picker';
2
+ export { DatePicker } from './adapters/inbound/DatePicker';
@@ -0,0 +1,18 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+
3
+ import { formatLocalDate, parseLocalDate } from './localDate';
4
+
5
+ describe('local date serialization', () => {
6
+ test('round-trips a valid YYYY-MM-DD value without a UTC conversion', () => {
7
+ const parsed = parseLocalDate('2026-09-13');
8
+
9
+ expect(parsed).toBeDefined();
10
+ expect(parsed ? formatLocalDate(parsed) : undefined).toBe('2026-09-13');
11
+ });
12
+
13
+ test('rejects malformed and impossible calendar dates', () => {
14
+ expect(parseLocalDate('2026-2-03')).toBeUndefined();
15
+ expect(parseLocalDate('2026-02-30')).toBeUndefined();
16
+ expect(parseLocalDate(null)).toBeUndefined();
17
+ });
18
+ });
@@ -0,0 +1,29 @@
1
+ const LOCAL_DATE_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/u;
2
+
3
+ /*** Parse a calendar date without applying a UTC offset. */
4
+ export function parseLocalDate(value: string | null | undefined): Date | undefined {
5
+ if (!value) return undefined;
6
+
7
+ const match = LOCAL_DATE_PATTERN.exec(value);
8
+ if (!match) return undefined;
9
+
10
+ const year = Number(match[1]);
11
+ const month = Number(match[2]);
12
+ const day = Number(match[3]);
13
+ const parsed = new Date(year, month - 1, day);
14
+ parsed.setFullYear(year);
15
+
16
+ return parsed.getFullYear() === year &&
17
+ parsed.getMonth() === month - 1 &&
18
+ parsed.getDate() === day
19
+ ? parsed
20
+ : undefined;
21
+ }
22
+
23
+ /*** Serialize a Date as a local calendar date suitable for manifest state. */
24
+ export function formatLocalDate(value: Date): string {
25
+ const year = String(value.getFullYear()).padStart(4, '0');
26
+ const month = String(value.getMonth() + 1).padStart(2, '0');
27
+ const day = String(value.getDate()).padStart(2, '0');
28
+ return `${year}-${month}-${day}`;
29
+ }
@@ -0,0 +1,39 @@
1
+ import React from 'react';
2
+
3
+ import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
4
+ import type { FormProps } from '../../../../types/form';
5
+ import { Stack } from '../../../layout/public';
6
+ import { FormActions } from './FormActions';
7
+
8
+ function FormInner({
9
+ themeId: _themeId,
10
+ mode: _mode,
11
+ children,
12
+ onSubmit,
13
+ loading = false,
14
+ disabled = false,
15
+ submitLabel = 'Submit',
16
+ actions,
17
+ testID,
18
+ interactionPolicy,
19
+ }: FormProps) {
20
+ return (
21
+ <Stack gap="m" testID={testID}>
22
+ {children}
23
+ <FormActions
24
+ disabled={disabled}
25
+ interactionPolicy={interactionPolicy}
26
+ loading={loading}
27
+ onSubmit={() => {
28
+ if (interactionPolicy !== 'passive') void onSubmit?.();
29
+ }}
30
+ submitLabel={submitLabel}
31
+ >
32
+ {actions}
33
+ </FormActions>
34
+ </Stack>
35
+ );
36
+ }
37
+
38
+ /*** Composes explicit form fields, form errors, and submit actions. */
39
+ export const Form = withZoraThemeScope(FormInner);
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
2
 
3
- import { Button } from '../../features/button/public';
4
- import { Box, Stack } from '../../features/layout/public';
5
- import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
6
- import type { FormActionsProps } from './types';
3
+ import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
4
+ import type { FormActionsProps } from '../../../../types/form';
5
+ import { Button } from '../../../button/public';
6
+ import { Box, Stack } from '../../../layout/public';
7
7
 
8
8
  function FormActionsInner({
9
9
  themeId: _themeId,
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+
3
+ import { useZoraTheme } from '../../../../theme/useZoraTheme';
4
+ import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
5
+ import type { FormErrorProps } from '../../../../types/form';
6
+ import { Box } from '../../../layout/public';
7
+ import { Text } from '../../../typography/public';
8
+
9
+ function FormErrorInner({ themeId: _themeId, mode: _mode, error, testID }: FormErrorProps) {
10
+ const { theme } = useZoraTheme();
11
+ if (!error) return null;
12
+ return (
13
+ <Box borderColor={theme.colors.error} borderWidth={1} p="s" radius="m" testID={testID}>
14
+ <Text color="error" variant="bodySmall">
15
+ {error}
16
+ </Text>
17
+ </Box>
18
+ );
19
+ }
20
+
21
+ /*** Displays a form-level validation or submission error. */
22
+ export const FormError = withZoraThemeScope(FormErrorInner);
@@ -1,10 +1,10 @@
1
1
  import { Field } from '@ankhorage/surface';
2
2
  import React from 'react';
3
3
 
4
- import { Stack } from '../../features/layout/public';
5
- import { Text } from '../../features/typography/public';
6
- import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
7
- import type { FormFieldProps } from './types';
4
+ import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
5
+ import type { FormFieldProps } from '../../../../types/form';
6
+ import { Stack } from '../../../layout/public';
7
+ import { Text } from '../../../typography/public';
8
8
 
9
9
  function FormFieldInner({
10
10
  themeId: _themeId,
@@ -13,6 +13,7 @@ function FormFieldInner({
13
13
  description,
14
14
  helperText,
15
15
  children,
16
+ interactionPolicy: _interactionPolicy,
16
17
  ...props
17
18
  }: FormFieldProps) {
18
19
  return (
@@ -37,4 +38,5 @@ function FormFieldInner({
37
38
  );
38
39
  }
39
40
 
41
+ /*** Groups one form control with its label, description, helper text, and field error. */
40
42
  export const FormField = withZoraThemeScope(FormFieldInner);
@@ -1,10 +1,9 @@
1
1
  import type { ZoraComponentMeta } from '../../metadata';
2
-
3
- export const datePickerMeta = {
4
- name: 'DatePicker',
2
+ export const formActionsMeta = {
3
+ name: 'FormActions',
5
4
  category: 'component',
6
5
  directManifestNode: false,
7
6
  allowedChildren: [],
8
- note: 'Code-facing BottomSheet-backed date picker; not represented as a manifest node in v1.',
7
+ note: 'Internal form action helper.',
9
8
  props: {},
10
9
  } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,19 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+ export const formErrorMeta = {
3
+ name: 'FormError',
4
+ category: 'component',
5
+ directManifestNode: true,
6
+ allowedChildren: [],
7
+ blueprint: { label: 'Form error', defaultProps: { error: 'Unable to submit the form.' } },
8
+ bindings: {
9
+ props: {
10
+ error: {
11
+ label: 'Error',
12
+ description: 'Global form or submission error.',
13
+ value: { type: 'unknown' },
14
+ acceptsFallback: true,
15
+ },
16
+ },
17
+ },
18
+ props: { error: { type: 'string', category: 'Content', label: 'Error' } },
19
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,35 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+ export const formFieldMeta = {
3
+ name: 'FormField',
4
+ category: 'component',
5
+ directManifestNode: true,
6
+ allowedChildren: ['Checkbox', 'CheckboxGroup', 'RadioGroup', 'TextInput'],
7
+ blueprint: { label: 'Form field', defaultProps: { label: 'Label' } },
8
+ bindings: {
9
+ props: {
10
+ errorText: {
11
+ label: 'Error text',
12
+ description: 'Field-level validation error.',
13
+ value: { type: 'unknown' },
14
+ acceptsFallback: true,
15
+ },
16
+ disabled: {
17
+ label: 'Disabled',
18
+ description: 'Whether the field is disabled.',
19
+ value: { type: 'boolean' },
20
+ acceptsFallback: true,
21
+ acceptsTransforms: true,
22
+ },
23
+ },
24
+ },
25
+ props: {
26
+ label: { type: 'string', category: 'Content', label: 'Label', default: 'Label' },
27
+ description: { type: 'string', category: 'Content', label: 'Description' },
28
+ helperText: { type: 'string', category: 'Content', label: 'Helper text' },
29
+ errorText: { type: 'string', category: 'Validation', label: 'Error text' },
30
+ required: { type: 'boolean', category: 'Validation', label: 'Required', default: false },
31
+ invalid: { type: 'boolean', category: 'Validation', label: 'Invalid', default: false },
32
+ disabled: { type: 'boolean', category: 'State', label: 'Disabled', default: false },
33
+ readOnly: { type: 'boolean', category: 'State', label: 'Read-only', default: false },
34
+ },
35
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,34 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+ export const formMeta = {
3
+ name: 'Form',
4
+ category: 'component',
5
+ directManifestNode: true,
6
+ allowedChildren: ['FormError', 'FormField'],
7
+ blueprint: {
8
+ label: 'Form',
9
+ defaultProps: { submitLabel: 'Submit', loading: false, disabled: false },
10
+ },
11
+ bindings: {
12
+ events: {
13
+ submit: {
14
+ label: 'Submit',
15
+ description: 'Runs when the form is submitted.',
16
+ payload: { eventType: 'form.submit', fields: [] },
17
+ },
18
+ },
19
+ },
20
+ events: {
21
+ submit: {
22
+ label: 'Submit',
23
+ eventType: 'form.submit',
24
+ description: 'Emitted when the form is submitted.',
25
+ payloadFields: [],
26
+ },
27
+ },
28
+ slots: { actions: { label: 'Actions', allowedChildren: ['Button', 'ButtonGroup'] } },
29
+ props: {
30
+ submitLabel: { type: 'string', category: 'Content', label: 'Submit label', default: 'Submit' },
31
+ loading: { type: 'boolean', category: 'State', label: 'Loading', default: false },
32
+ disabled: { type: 'boolean', category: 'State', label: 'Disabled', default: false },
33
+ },
34
+ } as const satisfies ZoraComponentMeta;
@@ -1,13 +1,8 @@
1
- export { Form } from './Form';
2
- export { FormActions } from './FormActions';
3
- export { FormError } from './FormError';
4
- export { FormField } from './FormField';
5
1
  export type {
6
2
  FormActionsProps,
7
3
  FormErrorProps,
8
4
  FormErrors,
9
5
  FormFieldConfig,
10
- FormFieldControlProps,
11
6
  FormFieldInputType,
12
7
  FormFieldProps,
13
8
  FormProps,
@@ -17,6 +12,10 @@ export type {
17
12
  UseFormControllerOptions,
18
13
  UseFormControllerResult,
19
14
  ValidationRule,
20
- } from './types';
15
+ } from '../../types/form';
16
+ export { Form } from './adapters/inbound/Form';
17
+ export { FormActions } from './adapters/inbound/FormActions';
18
+ export { FormError } from './adapters/inbound/FormError';
19
+ export { FormField } from './adapters/inbound/FormField';
21
20
  export { useFormController } from './useFormController';
22
- export { hasRequiredRule, validateField, validateFields, validateValue } from './validation';
21
+ export { hasRequiredRule, validateField, validateFields, validateValue } from './utils/validation';
@@ -6,8 +6,8 @@ import type {
6
6
  FormValues,
7
7
  UseFormControllerOptions,
8
8
  UseFormControllerResult,
9
- } from './types';
10
- import { validateFields } from './validation';
9
+ } from '../../types/form';
10
+ import { validateFields } from './utils/validation';
11
11
 
12
12
  function createInitialValues<TName extends string>(
13
13
  fields: readonly { name: TName }[],
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, test } from 'bun:test';
2
2
 
3
- import type { FormFieldConfig, FormValues } from './types';
3
+ import type { FormFieldConfig, FormValues } from '../../../types/form';
4
4
  import { validateFields, validateValue } from './validation';
5
5
 
6
6
  describe('form validation', () => {
@@ -12,6 +12,9 @@ describe('form validation', () => {
12
12
 
13
13
  test('validates email fields', () => {
14
14
  expect(validateValue('not-email', [{ kind: 'email' }])).toBe('Enter a valid email address.');
15
+ expect(validateValue('person@exam_ple.com', [{ kind: 'email' }])).toBe(
16
+ 'Enter a valid email address.',
17
+ );
15
18
  expect(validateValue('person@example.com', [{ kind: 'email' }])).toBeUndefined();
16
19
  });
17
20
 
@@ -1,12 +1,12 @@
1
+ import { isEmail } from '@ankhorage/utility/regex';
2
+
1
3
  import type {
2
4
  FormFieldConfig,
3
5
  FormValidationErrors,
4
6
  FormValidationResult,
5
7
  FormValues,
6
8
  ValidationRule,
7
- } from './types';
8
-
9
- const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
9
+ } from '../../../types/form';
10
10
 
11
11
  export function hasRequiredRule(rules: readonly ValidationRule[] | undefined): boolean {
12
12
  return rules?.some((rule) => rule.kind === 'required') ?? false;
@@ -27,11 +27,7 @@ export function validateValue(
27
27
  return rule.message ?? 'This field is required.';
28
28
  }
29
29
 
30
- if (
31
- rule.kind === 'email' &&
32
- normalizedValue.length > 0 &&
33
- !emailPattern.test(normalizedValue)
34
- ) {
30
+ if (rule.kind === 'email' && normalizedValue.length > 0 && !isEmail(normalizedValue)) {
35
31
  return rule.message ?? 'Enter a valid email address.';
36
32
  }
37
33
 
@@ -1,12 +1,11 @@
1
1
  import React from 'react';
2
2
 
3
- import { Button } from '../../features/button/public';
4
- import { Card } from '../../features/card/public';
5
- import { Box, Grid, Stack } from '../../features/layout/public';
6
- import { Heading } from '../../features/typography/public';
7
- import { Text } from '../../features/typography/public';
8
- import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
9
- import type { HeroAction, HeroAlign, HeroProps } from './types';
3
+ import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
4
+ import type { HeroAction, HeroAlign, HeroProps } from '../../../../types/hero';
5
+ import { Button } from '../../../button/public';
6
+ import { Card } from '../../../card/public';
7
+ import { Box, Grid, Stack } from '../../../layout/public';
8
+ import { Heading, Text } from '../../../typography/public';
10
9
 
11
10
  function HeroInner({
12
11
  themeId: _themeId,
@@ -0,0 +1,2 @@
1
+ export type { HeroAction, HeroAlign, HeroLayout, HeroProps, HeroTone } from '../../types/hero';
2
+ export { Hero } from './adapters/inbound/Hero';
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, test } from 'bun:test';
2
2
 
3
3
  import { ZORA_BINDABLE_COMPONENT_META, ZORA_COMPONENT_META } from '../../metadata';
4
- import { missingElementMeta } from './meta';
4
+ import { missingElementMeta } from './missingElementMeta';
5
5
 
6
6
  describe('MissingElement draft contract', () => {
7
7
  test('is a release-blocking manifest leaf distinct from completed states', () => {
@@ -41,7 +41,9 @@ describe('MissingElement draft contract', () => {
41
41
  });
42
42
 
43
43
  test('visibly and accessibly identifies the gap while preserving its minimum dimensions', async () => {
44
- const source = await Bun.file('src/patterns/missing-element/MissingElement.tsx').text();
44
+ const source = await Bun.file(
45
+ 'src/features/missing-element/adapters/inbound/MissingElement.tsx',
46
+ ).text();
45
47
 
46
48
  expect(source).toContain('accessibilityLabel={accessibilityLabel}');
47
49
  expect(source).toContain('accessibilityRole="text"');
@@ -54,8 +56,8 @@ describe('MissingElement draft contract', () => {
54
56
 
55
57
  test('accepts the canonical interaction policy without owning interactive behavior', async () => {
56
58
  const [source, types] = await Promise.all([
57
- Bun.file('src/patterns/missing-element/MissingElement.tsx').text(),
58
- Bun.file('src/patterns/missing-element/types.ts').text(),
59
+ Bun.file('src/features/missing-element/adapters/inbound/MissingElement.tsx').text(),
60
+ Bun.file('src/types/missing-element.ts').text(),
59
61
  ]);
60
62
 
61
63
  expect(types).toContain('MissingElementProps extends ZoraBaseProps');