@ankhorage/zora 14.0.0 → 15.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 (249) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +176 -6
  3. package/dist/features/app-bar/adapters/inbound/AppBar.d.ts +5 -0
  4. package/dist/features/app-bar/adapters/inbound/AppBar.d.ts.map +1 -0
  5. package/dist/features/app-bar/adapters/inbound/AppBar.js +92 -0
  6. package/dist/features/app-bar/adapters/inbound/AppBar.js.map +1 -0
  7. package/dist/{components/app-bar/meta.d.ts → features/app-bar/appBarMeta.d.ts} +1 -1
  8. package/dist/features/app-bar/appBarMeta.d.ts.map +1 -0
  9. package/dist/{components/app-bar/meta.js → features/app-bar/appBarMeta.js} +1 -1
  10. package/dist/features/app-bar/appBarMeta.js.map +1 -0
  11. package/dist/features/app-bar/public.d.ts +3 -0
  12. package/dist/features/app-bar/public.d.ts.map +1 -0
  13. package/dist/features/app-bar/public.js +2 -0
  14. package/dist/features/app-bar/public.js.map +1 -0
  15. package/dist/features/bottom-sheet/public.d.ts +2 -2
  16. package/dist/features/bottom-sheet/public.d.ts.map +1 -1
  17. package/dist/features/bottom-sheet/public.js +1 -1
  18. package/dist/features/bottom-sheet/public.js.map +1 -1
  19. package/dist/features/breadcrumbs/adapters/inbound/Breadcrumbs.d.ts +5 -0
  20. package/dist/features/breadcrumbs/adapters/inbound/Breadcrumbs.d.ts.map +1 -0
  21. package/dist/features/breadcrumbs/adapters/inbound/Breadcrumbs.js +81 -0
  22. package/dist/features/breadcrumbs/adapters/inbound/Breadcrumbs.js.map +1 -0
  23. package/dist/features/breadcrumbs/breadcrumbsMeta.d.ts +119 -0
  24. package/dist/features/breadcrumbs/breadcrumbsMeta.d.ts.map +1 -0
  25. package/dist/features/breadcrumbs/breadcrumbsMeta.js +94 -0
  26. package/dist/features/breadcrumbs/breadcrumbsMeta.js.map +1 -0
  27. package/dist/features/breadcrumbs/public.d.ts +3 -0
  28. package/dist/features/breadcrumbs/public.d.ts.map +1 -0
  29. package/dist/features/breadcrumbs/public.js +2 -0
  30. package/dist/features/breadcrumbs/public.js.map +1 -0
  31. package/dist/features/button/utils/resolveButtonThemeRecipe.d.ts +1 -1
  32. package/dist/features/data-table/adapters/inbound/DataTable.d.ts.map +1 -1
  33. package/dist/features/data-table/adapters/inbound/DataTable.js +4 -2
  34. package/dist/features/data-table/adapters/inbound/DataTable.js.map +1 -1
  35. package/dist/features/form/formFieldMeta.d.ts +1 -1
  36. package/dist/features/form/formFieldMeta.js +1 -1
  37. package/dist/features/form/formFieldMeta.js.map +1 -1
  38. package/dist/features/form/radio/utils/resolveRadioGroupThemeRecipe.d.ts +1 -1
  39. package/dist/features/form/select/adapters/inbound/Select.d.ts +2 -0
  40. package/dist/features/form/select/adapters/inbound/Select.d.ts.map +1 -0
  41. package/dist/features/form/select/adapters/inbound/Select.js +2 -0
  42. package/dist/features/form/select/adapters/inbound/Select.js.map +1 -0
  43. package/dist/features/form/select/adapters/inbound/Select.native.d.ts +5 -0
  44. package/dist/features/form/select/adapters/inbound/Select.native.d.ts.map +1 -0
  45. package/dist/features/form/select/adapters/inbound/Select.native.js +42 -0
  46. package/dist/features/form/select/adapters/inbound/Select.native.js.map +1 -0
  47. package/dist/features/form/select/adapters/inbound/Select.web.d.ts +5 -0
  48. package/dist/features/form/select/adapters/inbound/Select.web.d.ts.map +1 -0
  49. package/dist/features/form/select/adapters/inbound/Select.web.js +31 -0
  50. package/dist/features/form/select/adapters/inbound/Select.web.js.map +1 -0
  51. package/dist/features/form/select/composition/SelectField.d.ts +10 -0
  52. package/dist/features/form/select/composition/SelectField.d.ts.map +1 -0
  53. package/dist/features/form/select/composition/SelectField.js +8 -0
  54. package/dist/features/form/select/composition/SelectField.js.map +1 -0
  55. package/dist/features/form/select/composition/SelectOptionRow.d.ts +12 -0
  56. package/dist/features/form/select/composition/SelectOptionRow.d.ts.map +1 -0
  57. package/dist/features/form/select/composition/SelectOptionRow.js +9 -0
  58. package/dist/features/form/select/composition/SelectOptionRow.js.map +1 -0
  59. package/dist/features/form/select/composition/SelectTrigger.d.ts +10 -0
  60. package/dist/features/form/select/composition/SelectTrigger.d.ts.map +1 -0
  61. package/dist/features/form/select/composition/SelectTrigger.js +9 -0
  62. package/dist/features/form/select/composition/SelectTrigger.js.map +1 -0
  63. package/dist/features/form/select/composition/useSelectController.d.ts +8 -0
  64. package/dist/features/form/select/composition/useSelectController.d.ts.map +1 -0
  65. package/dist/features/form/select/composition/useSelectController.js +15 -0
  66. package/dist/features/form/select/composition/useSelectController.js.map +1 -0
  67. package/dist/features/form/select/public.d.ts +3 -0
  68. package/dist/features/form/select/public.d.ts.map +1 -0
  69. package/dist/features/form/select/public.js +2 -0
  70. package/dist/features/form/select/public.js.map +1 -0
  71. package/dist/features/form/select/selectMeta.d.ts +195 -0
  72. package/dist/features/form/select/selectMeta.d.ts.map +1 -0
  73. package/dist/features/form/select/selectMeta.js +152 -0
  74. package/dist/features/form/select/selectMeta.js.map +1 -0
  75. package/dist/features/popover-menu/adapters/inbound/PopoverMenu.d.ts +5 -0
  76. package/dist/features/popover-menu/adapters/inbound/PopoverMenu.d.ts.map +1 -0
  77. package/dist/features/popover-menu/adapters/inbound/PopoverMenu.js +43 -0
  78. package/dist/features/popover-menu/adapters/inbound/PopoverMenu.js.map +1 -0
  79. package/dist/features/popover-menu/popoverMenuMeta.d.ts +9 -0
  80. package/dist/features/popover-menu/popoverMenuMeta.d.ts.map +1 -0
  81. package/dist/features/popover-menu/popoverMenuMeta.js +9 -0
  82. package/dist/features/popover-menu/popoverMenuMeta.js.map +1 -0
  83. package/dist/features/popover-menu/public.d.ts +3 -0
  84. package/dist/features/popover-menu/public.d.ts.map +1 -0
  85. package/dist/features/popover-menu/public.js +2 -0
  86. package/dist/features/popover-menu/public.js.map +1 -0
  87. package/dist/features/typography/utils/resolveHeadingThemeRecipe.d.ts +1 -1
  88. package/dist/features/typography/utils/resolveTextThemeRecipe.d.ts +1 -1
  89. package/dist/index.d.ts +5 -8
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +4 -4
  92. package/dist/index.js.map +1 -1
  93. package/dist/layout/settings-layout/SettingsLayout.d.ts +0 -2
  94. package/dist/layout/settings-layout/SettingsLayout.d.ts.map +1 -1
  95. package/dist/layout/settings-layout/SettingsLayout.js +1 -3
  96. package/dist/layout/settings-layout/SettingsLayout.js.map +1 -1
  97. package/dist/metadata/bindableComponentMeta.d.ts +1 -2
  98. package/dist/metadata/bindableComponentMeta.d.ts.map +1 -1
  99. package/dist/metadata/bindableComponentMeta.js +1 -2
  100. package/dist/metadata/bindableComponentMeta.js.map +1 -1
  101. package/dist/metadata/componentMeta.d.ts.map +1 -1
  102. package/dist/metadata/componentMeta.js +5 -6
  103. package/dist/metadata/componentMeta.js.map +1 -1
  104. package/dist/patterns/reader/ReaderSurface.js +1 -1
  105. package/dist/patterns/reader/ReaderSurface.js.map +1 -1
  106. package/dist/patterns/theme-composer/ThemeComposer.js +1 -1
  107. package/dist/patterns/theme-composer/ThemeComposer.js.map +1 -1
  108. package/dist/registry.d.ts.map +1 -1
  109. package/dist/registry.js +5 -6
  110. package/dist/registry.js.map +1 -1
  111. package/dist/{components/app-bar/types.d.ts → types/app-bar.d.ts} +8 -5
  112. package/dist/types/app-bar.d.ts.map +1 -0
  113. package/dist/types/app-bar.js +2 -0
  114. package/dist/types/app-bar.js.map +1 -0
  115. package/dist/{components/breadcrumbs/types.d.ts → types/breadcrumbs.d.ts} +8 -6
  116. package/dist/types/breadcrumbs.d.ts.map +1 -0
  117. package/dist/types/breadcrumbs.js +2 -0
  118. package/dist/types/breadcrumbs.js.map +1 -0
  119. package/dist/types/data-table.d.ts +2 -2
  120. package/dist/types/data-table.d.ts.map +1 -1
  121. package/dist/types/data-table.js.map +1 -1
  122. package/dist/types/popover-menu.d.ts +24 -0
  123. package/dist/types/popover-menu.d.ts.map +1 -0
  124. package/dist/types/popover-menu.js +2 -0
  125. package/dist/types/popover-menu.js.map +1 -0
  126. package/dist/types/select.d.ts +22 -0
  127. package/dist/types/select.d.ts.map +1 -0
  128. package/dist/types/select.js +2 -0
  129. package/dist/types/select.js.map +1 -0
  130. package/package.json +2 -4
  131. package/src/features/app-bar/adapters/inbound/AppBar.tsx +184 -0
  132. package/src/features/app-bar/public.ts +2 -0
  133. package/src/features/bottom-sheet/public.test.ts +10 -1
  134. package/src/features/bottom-sheet/public.ts +9 -1
  135. package/src/features/breadcrumbs/adapters/inbound/Breadcrumbs.tsx +179 -0
  136. package/src/features/breadcrumbs/breadcrumbsMeta.ts +95 -0
  137. package/src/features/breadcrumbs/public.test.ts +22 -0
  138. package/src/features/breadcrumbs/public.ts +6 -0
  139. package/src/features/data-table/adapters/inbound/DataTable.tsx +9 -5
  140. package/src/features/form/formFieldMeta.ts +1 -1
  141. package/src/features/form/select/adapters/inbound/Select.native.tsx +78 -0
  142. package/src/features/form/select/adapters/inbound/Select.tsx +1 -0
  143. package/src/features/form/select/adapters/inbound/Select.web.tsx +63 -0
  144. package/src/features/form/select/composition/SelectField.tsx +27 -0
  145. package/src/features/form/select/composition/SelectOptionRow.tsx +36 -0
  146. package/src/features/form/select/composition/SelectTrigger.tsx +32 -0
  147. package/src/features/form/select/composition/useSelectController.ts +21 -0
  148. package/src/features/form/select/public.test.ts +25 -0
  149. package/src/features/form/select/public.ts +2 -0
  150. package/src/features/form/select/selectMeta.ts +154 -0
  151. package/src/features/popover-menu/adapters/inbound/PopoverMenu.tsx +60 -0
  152. package/src/{components/breadcrumbs/meta.ts → features/popover-menu/popoverMenuMeta.ts} +3 -3
  153. package/src/features/popover-menu/public.test.ts +11 -0
  154. package/src/features/popover-menu/public.ts +6 -0
  155. package/src/index.ts +15 -8
  156. package/src/interactionPolicy.test.ts +24 -22
  157. package/src/layout/settings-layout/SettingsLayout.tsx +1 -3
  158. package/src/metadata/bindableComponentMeta.test.ts +8 -0
  159. package/src/metadata/bindableComponentMeta.ts +1 -2
  160. package/src/metadata/componentMeta.test.ts +3 -0
  161. package/src/metadata/componentMeta.ts +5 -6
  162. package/src/nativePeerContract.test.ts +5 -19
  163. package/src/patterns/reader/ReaderSurface.tsx +1 -1
  164. package/src/patterns/theme-composer/ThemeComposer.tsx +1 -1
  165. package/src/platformAcceptance.test.ts +1 -1
  166. package/src/registry.ts +5 -6
  167. package/src/theme/themeScopeStructure.test.ts +10 -5
  168. package/src/{components/app-bar/types.ts → types/app-bar.ts} +7 -4
  169. package/src/{components/breadcrumbs/types.ts → types/breadcrumbs.ts} +8 -5
  170. package/src/types/data-table.ts +2 -2
  171. package/src/types/popover-menu.ts +31 -0
  172. package/src/{components/select/types.ts → types/select.ts} +11 -3
  173. package/dist/components/app-bar/AppBar.d.ts +0 -7
  174. package/dist/components/app-bar/AppBar.d.ts.map +0 -1
  175. package/dist/components/app-bar/AppBar.js +0 -67
  176. package/dist/components/app-bar/AppBar.js.map +0 -1
  177. package/dist/components/app-bar/index.d.ts +0 -3
  178. package/dist/components/app-bar/index.d.ts.map +0 -1
  179. package/dist/components/app-bar/index.js +0 -3
  180. package/dist/components/app-bar/index.js.map +0 -1
  181. package/dist/components/app-bar/meta.d.ts.map +0 -1
  182. package/dist/components/app-bar/meta.js.map +0 -1
  183. package/dist/components/app-bar/types.d.ts.map +0 -1
  184. package/dist/components/app-bar/types.js +0 -2
  185. package/dist/components/app-bar/types.js.map +0 -1
  186. package/dist/components/breadcrumbs/Breadcrumbs.d.ts +0 -7
  187. package/dist/components/breadcrumbs/Breadcrumbs.d.ts.map +0 -1
  188. package/dist/components/breadcrumbs/Breadcrumbs.js +0 -80
  189. package/dist/components/breadcrumbs/Breadcrumbs.js.map +0 -1
  190. package/dist/components/breadcrumbs/index.d.ts +0 -3
  191. package/dist/components/breadcrumbs/index.d.ts.map +0 -1
  192. package/dist/components/breadcrumbs/index.js +0 -2
  193. package/dist/components/breadcrumbs/index.js.map +0 -1
  194. package/dist/components/breadcrumbs/meta.d.ts +0 -9
  195. package/dist/components/breadcrumbs/meta.d.ts.map +0 -1
  196. package/dist/components/breadcrumbs/meta.js +0 -9
  197. package/dist/components/breadcrumbs/meta.js.map +0 -1
  198. package/dist/components/breadcrumbs/types.d.ts.map +0 -1
  199. package/dist/components/breadcrumbs/types.js +0 -2
  200. package/dist/components/breadcrumbs/types.js.map +0 -1
  201. package/dist/components/menu/DropdownMenu.d.ts +0 -7
  202. package/dist/components/menu/DropdownMenu.d.ts.map +0 -1
  203. package/dist/components/menu/DropdownMenu.js +0 -9
  204. package/dist/components/menu/DropdownMenu.js.map +0 -1
  205. package/dist/components/menu/Menu.d.ts +0 -7
  206. package/dist/components/menu/Menu.d.ts.map +0 -1
  207. package/dist/components/menu/Menu.js +0 -46
  208. package/dist/components/menu/Menu.js.map +0 -1
  209. package/dist/components/menu/index.d.ts +0 -4
  210. package/dist/components/menu/index.d.ts.map +0 -1
  211. package/dist/components/menu/index.js +0 -3
  212. package/dist/components/menu/index.js.map +0 -1
  213. package/dist/components/menu/meta.d.ts +0 -17
  214. package/dist/components/menu/meta.d.ts.map +0 -1
  215. package/dist/components/menu/meta.js +0 -17
  216. package/dist/components/menu/meta.js.map +0 -1
  217. package/dist/components/menu/types.d.ts +0 -22
  218. package/dist/components/menu/types.d.ts.map +0 -1
  219. package/dist/components/menu/types.js +0 -2
  220. package/dist/components/menu/types.js.map +0 -1
  221. package/dist/components/select/Select.d.ts +0 -7
  222. package/dist/components/select/Select.d.ts.map +0 -1
  223. package/dist/components/select/Select.js +0 -32
  224. package/dist/components/select/Select.js.map +0 -1
  225. package/dist/components/select/index.d.ts +0 -3
  226. package/dist/components/select/index.d.ts.map +0 -1
  227. package/dist/components/select/index.js +0 -3
  228. package/dist/components/select/index.js.map +0 -1
  229. package/dist/components/select/meta.d.ts +0 -9
  230. package/dist/components/select/meta.d.ts.map +0 -1
  231. package/dist/components/select/meta.js +0 -9
  232. package/dist/components/select/meta.js.map +0 -1
  233. package/dist/components/select/types.d.ts +0 -14
  234. package/dist/components/select/types.d.ts.map +0 -1
  235. package/dist/components/select/types.js +0 -2
  236. package/dist/components/select/types.js.map +0 -1
  237. package/src/components/app-bar/AppBar.tsx +0 -140
  238. package/src/components/app-bar/index.ts +0 -2
  239. package/src/components/breadcrumbs/Breadcrumbs.tsx +0 -147
  240. package/src/components/breadcrumbs/index.ts +0 -2
  241. package/src/components/menu/DropdownMenu.tsx +0 -11
  242. package/src/components/menu/Menu.tsx +0 -59
  243. package/src/components/menu/index.ts +0 -3
  244. package/src/components/menu/meta.ts +0 -19
  245. package/src/components/menu/types.ts +0 -31
  246. package/src/components/select/Select.tsx +0 -67
  247. package/src/components/select/index.ts +0 -2
  248. package/src/components/select/meta.ts +0 -10
  249. /package/src/{components/app-bar/meta.ts → features/app-bar/appBarMeta.ts} +0 -0
@@ -0,0 +1,24 @@
1
+ import type { ButtonIconSpec, PopoverAnchorRenderProps, PopoverMenuActionIntent as SurfacePopoverMenuActionIntent } from '@ankhorage/surface';
2
+ import type React from 'react';
3
+ import type { ZoraBaseProps } from '../theme/ZoraBaseProps';
4
+ export type PopoverMenuActionIntent = SurfacePopoverMenuActionIntent;
5
+ export interface PopoverMenuAction {
6
+ id: string;
7
+ title: React.ReactNode;
8
+ description?: React.ReactNode;
9
+ icon?: ButtonIconSpec;
10
+ leading?: React.ReactNode;
11
+ trailing?: React.ReactNode;
12
+ intent?: PopoverMenuActionIntent;
13
+ disabled?: boolean;
14
+ selected?: boolean;
15
+ onPress?: () => void;
16
+ }
17
+ export interface PopoverMenuProps extends ZoraBaseProps {
18
+ trigger: (controls: PopoverAnchorRenderProps) => React.ReactNode;
19
+ actions: readonly PopoverMenuAction[];
20
+ onDismiss?: () => void;
21
+ closeOnSelect?: boolean;
22
+ testID?: string;
23
+ }
24
+ //# sourceMappingURL=popover-menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popover-menu.d.ts","sourceRoot":"","sources":["../../src/types/popover-menu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,wBAAwB,EACxB,uBAAuB,IAAI,8BAA8B,EAC1D,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,MAAM,uBAAuB,GAAG,8BAA8B,CAAC;AAErE,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,OAAO,EAAE,CAAC,QAAQ,EAAE,wBAAwB,KAAK,KAAK,CAAC,SAAS,CAAC;IACjE,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=popover-menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popover-menu.js","sourceRoot":"","sources":["../../src/types/popover-menu.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ButtonIconSpec,\n PopoverAnchorRenderProps,\n PopoverMenuActionIntent as SurfacePopoverMenuActionIntent,\n} from '@ankhorage/surface';\nimport type React from 'react';\n\nimport type { ZoraBaseProps } from '../theme/ZoraBaseProps';\n\nexport type PopoverMenuActionIntent = SurfacePopoverMenuActionIntent;\n\nexport interface PopoverMenuAction {\n id: string;\n title: React.ReactNode;\n description?: React.ReactNode;\n icon?: ButtonIconSpec;\n leading?: React.ReactNode;\n trailing?: React.ReactNode;\n intent?: PopoverMenuActionIntent;\n disabled?: boolean;\n selected?: boolean;\n onPress?: () => void;\n}\n\nexport interface PopoverMenuProps extends ZoraBaseProps {\n trigger: (controls: PopoverAnchorRenderProps) => React.ReactNode;\n actions: readonly PopoverMenuAction[];\n onDismiss?: () => void;\n closeOnSelect?: boolean;\n testID?: string;\n}\n"]}
@@ -0,0 +1,22 @@
1
+ import type { ZoraBaseProps } from '../theme/ZoraBaseProps';
2
+ export interface SelectOption<TValue extends string = string> {
3
+ value: TValue;
4
+ label: string;
5
+ disabled?: boolean;
6
+ }
7
+ export interface SelectProps<TValue extends string = string> extends ZoraBaseProps {
8
+ value?: TValue;
9
+ defaultValue?: TValue;
10
+ options: readonly SelectOption<TValue>[];
11
+ onValueChange?: (value: TValue) => void;
12
+ label?: string;
13
+ helperText?: string;
14
+ errorText?: string;
15
+ placeholder?: string;
16
+ required?: boolean;
17
+ disabled?: boolean;
18
+ readOnly?: boolean;
19
+ invalid?: boolean;
20
+ testID?: string;
21
+ }
22
+ //# sourceMappingURL=select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/types/select.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,WAAW,YAAY,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,SAAS,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/types/select.ts"],"names":[],"mappings":"","sourcesContent":["import type { ZoraBaseProps } from '../theme/ZoraBaseProps';\n\nexport interface SelectOption<TValue extends string = string> {\n value: TValue;\n label: string;\n disabled?: boolean;\n}\n\nexport interface SelectProps<TValue extends string = string> extends ZoraBaseProps {\n value?: TValue;\n defaultValue?: TValue;\n options: readonly SelectOption<TValue>[];\n onValueChange?: (value: TValue) => void;\n label?: string;\n helperText?: string;\n errorText?: string;\n placeholder?: string;\n required?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n invalid?: boolean;\n testID?: string;\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ankhorage/zora",
3
3
  "type": "module",
4
- "version": "14.0.0",
4
+ "version": "15.0.0",
5
5
  "description": "Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.",
6
6
  "homepage": "https://github.com/ankhorage/zora#readme",
7
7
  "bugs": {
@@ -25,7 +25,6 @@
25
25
  "components"
26
26
  ],
27
27
  "peerDependencies": {
28
- "@react-native-picker/picker": "2.11.4",
29
28
  "@react-native-vector-icons/fontawesome": "^13.1.3",
30
29
  "@react-native-vector-icons/fontawesome5": "^13.1.3",
31
30
  "@react-native-vector-icons/fontawesome6": "^13.1.3",
@@ -42,7 +41,7 @@
42
41
  "dependencies": {
43
42
  "@ankhorage/color-theory": "^0.3.0",
44
43
  "@ankhorage/contracts": "^12.0.1",
45
- "@ankhorage/surface": "^4.4.0",
44
+ "@ankhorage/surface": "^5.0.0",
46
45
  "@ankhorage/utility": "^0.8.0",
47
46
  "expo-document-picker": "~57.0.1",
48
47
  "expo-image-picker": "~57.0.16"
@@ -117,7 +116,6 @@
117
116
  "devDependencies": {
118
117
  "@ankhorage/devtools": "^1.13.0",
119
118
  "@ankhorage/paradox": "^0.1.24",
120
- "@react-native-picker/picker": "2.11.4",
121
119
  "@react-native-vector-icons/fontawesome": "^13.1.3",
122
120
  "@react-native-vector-icons/fontawesome5": "^13.1.3",
123
121
  "@react-native-vector-icons/fontawesome6": "^13.1.3",
@@ -0,0 +1,184 @@
1
+ import { AppBar as SurfaceAppBar, type ButtonIconSpec } from '@ankhorage/surface';
2
+ import React from 'react';
3
+
4
+ import { Inline } from '../../../../foundation';
5
+ import { useZoraTheme } from '../../../../theme/useZoraTheme';
6
+ import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
7
+ import type { AppBarMode, AppBarOverflowMenu, AppBarProps } from '../../../../types/app-bar';
8
+ import { IconButton } from '../../../button/public';
9
+ import { Box, Stack } from '../../../layout/public';
10
+ import { PopoverMenu } from '../../../popover-menu/public';
11
+ import { Heading, Text } from '../../../typography/public';
12
+
13
+ const DEFAULT_CANCEL_ICON = { name: 'close-outline' } satisfies ButtonIconSpec;
14
+ const DEFAULT_OVERFLOW_ICON = { name: 'ellipsis-vertical' } satisfies ButtonIconSpec;
15
+
16
+ /*** Renders a top app bar with title/subtitle and optional leading/trailing actions. */
17
+ export const AppBar = withZoraThemeScope(AppBarInner);
18
+
19
+ /*** Composes the opinionated ZORA AppBar over the Surface layout primitive. */
20
+ function AppBarInner({
21
+ themeId: _themeId,
22
+ mode: _mode,
23
+ title,
24
+ subtitle,
25
+ leading,
26
+ actions,
27
+ overflow,
28
+ appMode,
29
+ children,
30
+ safeAreaTop = true,
31
+ divider = true,
32
+ testID,
33
+ interactionPolicy,
34
+ }: AppBarProps) {
35
+ const { theme } = useZoraTheme();
36
+ const resolvedMode = resolveMode(appMode);
37
+ const isSelectionMode = resolvedMode.type === 'selection';
38
+ const resolvedLeading = leading ?? resolveSelectionLeading(resolvedMode, interactionPolicy);
39
+ const overflowMenu = resolveOverflowMenu(overflow, interactionPolicy, testID);
40
+ const resolvedTrailing = resolveTrailing(actions, overflowMenu);
41
+ const resolvedCenter = resolveCenter({
42
+ children,
43
+ isSelectionMode,
44
+ resolvedMode,
45
+ subtitle,
46
+ title,
47
+ });
48
+
49
+ return (
50
+ <SurfaceAppBar
51
+ bg={isSelectionMode ? theme.semantics.action.primary.softBg : undefined}
52
+ divider={divider}
53
+ leading={resolvedLeading}
54
+ safeAreaTop={safeAreaTop}
55
+ testID={testID}
56
+ trailing={resolvedTrailing}
57
+ >
58
+ {resolvedCenter ? <Box style={{ minWidth: 0 }}>{resolvedCenter}</Box> : null}
59
+ </SurfaceAppBar>
60
+ );
61
+ }
62
+
63
+ /*** Resolves the effective AppBar mode. */
64
+ function resolveMode(mode: AppBarMode | undefined): AppBarMode {
65
+ return mode ?? { type: 'default' };
66
+ }
67
+
68
+ /*** Formats the active selection label with its optional count. */
69
+ function resolveSelectionLabel({ count, label }: { count?: number; label: string }): string {
70
+ if (count === undefined) return label;
71
+ return `${label} (${count})`;
72
+ }
73
+
74
+ /*** Resolves the accessible label for the overflow menu trigger. */
75
+ function resolveOverflowLabel(overflow: AppBarOverflowMenu): string {
76
+ return overflow.label ?? 'More options';
77
+ }
78
+
79
+ /*** Resolves the accessible label for leaving selection mode. */
80
+ function resolveCancelLabel(mode: Extract<AppBarMode, { type: 'selection' }>): string {
81
+ return mode.cancelLabel ?? 'Cancel selection';
82
+ }
83
+
84
+ /*** Resolves the selection action shown at the leading edge. */
85
+ function resolveSelectionLeading(
86
+ mode: AppBarMode,
87
+ interactionPolicy: AppBarProps['interactionPolicy'],
88
+ ): React.ReactNode | undefined {
89
+ if (mode.type !== 'selection') return undefined;
90
+
91
+ return (
92
+ <IconButton
93
+ color="neutral"
94
+ icon={mode.cancelIcon ?? DEFAULT_CANCEL_ICON}
95
+ interactionPolicy={interactionPolicy}
96
+ label={resolveCancelLabel(mode)}
97
+ onPress={mode.onCancel}
98
+ size="m"
99
+ variant="ghost"
100
+ />
101
+ );
102
+ }
103
+
104
+ /*** Resolves the optional AppBar overflow action menu. */
105
+ function resolveOverflowMenu(
106
+ overflow: AppBarOverflowMenu | undefined,
107
+ interactionPolicy: AppBarProps['interactionPolicy'],
108
+ testID: string | undefined,
109
+ ): React.ReactNode {
110
+ if (overflow === undefined || overflow.actions.length === 0) return null;
111
+
112
+ return (
113
+ <PopoverMenu
114
+ actions={overflow.actions}
115
+ closeOnSelect={overflow.closeOnSelect}
116
+ interactionPolicy={interactionPolicy}
117
+ onDismiss={overflow.onDismiss}
118
+ testID={testID ? `${testID}-overflow` : undefined}
119
+ trigger={({ toggle }) => (
120
+ <IconButton
121
+ color="neutral"
122
+ disabled={overflow.disabled}
123
+ icon={overflow.icon ?? DEFAULT_OVERFLOW_ICON}
124
+ interactionPolicy={interactionPolicy}
125
+ label={resolveOverflowLabel(overflow)}
126
+ onPress={toggle}
127
+ size="m"
128
+ variant="ghost"
129
+ />
130
+ )}
131
+ />
132
+ );
133
+ }
134
+
135
+ /*** Composes trailing actions and overflow controls. */
136
+ function resolveTrailing(actions: React.ReactNode, overflowMenu: React.ReactNode): React.ReactNode {
137
+ if (!actions && !overflowMenu) return undefined;
138
+ return (
139
+ <Inline align="center" gap="s" wrap="nowrap">
140
+ {actions}
141
+ {overflowMenu}
142
+ </Inline>
143
+ );
144
+ }
145
+
146
+ /*** Resolves the center content for default and selection modes. */
147
+ function resolveCenter({
148
+ children,
149
+ isSelectionMode,
150
+ resolvedMode,
151
+ subtitle,
152
+ title,
153
+ }: {
154
+ children: React.ReactNode;
155
+ isSelectionMode: boolean;
156
+ resolvedMode: AppBarMode;
157
+ subtitle: React.ReactNode;
158
+ title: React.ReactNode;
159
+ }): React.ReactNode {
160
+ if (children !== undefined) return children;
161
+ if (isSelectionMode && resolvedMode.type === 'selection') {
162
+ return (
163
+ <Text emphasis="default" numberOfLines={1} variant="label" weight="semiBold">
164
+ {resolveSelectionLabel(resolvedMode)}
165
+ </Text>
166
+ );
167
+ }
168
+ if (title == null && subtitle == null) return null;
169
+
170
+ return (
171
+ <Stack gap="xs">
172
+ {title != null ? (
173
+ <Heading ellipsizeMode="tail" level={3} numberOfLines={1} size="h5">
174
+ {title}
175
+ </Heading>
176
+ ) : null}
177
+ {subtitle != null ? (
178
+ <Text ellipsizeMode="tail" emphasis="muted" numberOfLines={1} variant="bodySmall">
179
+ {subtitle}
180
+ </Text>
181
+ ) : null}
182
+ </Stack>
183
+ );
184
+ }
@@ -0,0 +1,2 @@
1
+ export type { AppBarMode, AppBarOverflowMenu, AppBarProps } from '../../types/app-bar';
2
+ export { AppBar } from './adapters/inbound/AppBar';
@@ -10,8 +10,17 @@ describe('ZORA BottomSheet public contract', () => {
10
10
  const source = await Bun.file('src/features/bottom-sheet/public.ts').text();
11
11
 
12
12
  expect(packageJson.exports['./bottom-sheet']).toBeDefined();
13
- expect(packageJson.dependencies['@ankhorage/surface']).toMatch(/^\^4\./u);
13
+ expect(packageJson.dependencies['@ankhorage/surface']).toMatch(/^\^5\./u);
14
14
  expect(source).toContain("from '@ankhorage/surface/bottom-sheet'");
15
+ for (const name of [
16
+ 'BottomSheetFlatList',
17
+ 'BottomSheetScrollView',
18
+ 'BottomSheetSectionList',
19
+ 'BottomSheetView',
20
+ 'BottomSheetVirtualizedList',
21
+ ]) {
22
+ expect(source).toContain(name);
23
+ }
15
24
  const {
16
25
  'react-native-gesture-handler': gestureHandlerPeer,
17
26
  'react-native-reanimated': reanimatedPeer,
@@ -1,7 +1,15 @@
1
1
  export type { BottomSheetProps } from '../../types/manifest-bottom-sheet';
2
2
  export { BottomSheet } from './adapters/inbound/BottomSheet';
3
3
  export type {
4
+ BottomSheetContentMode,
4
5
  BottomSheetController,
5
6
  BottomSheetPresentOptions,
6
7
  } from '@ankhorage/surface/bottom-sheet';
7
- export { useBottomSheet } from '@ankhorage/surface/bottom-sheet';
8
+ export {
9
+ BottomSheetFlatList,
10
+ BottomSheetScrollView,
11
+ BottomSheetSectionList,
12
+ BottomSheetView,
13
+ BottomSheetVirtualizedList,
14
+ useBottomSheet,
15
+ } from '@ankhorage/surface/bottom-sheet';
@@ -0,0 +1,179 @@
1
+ import React from 'react';
2
+
3
+ import { Inline } from '../../../../foundation';
4
+ import { resolveIconSize } from '../../../../internal/recipes';
5
+ import { useZoraTheme } from '../../../../theme/useZoraTheme';
6
+ import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
7
+ import type {
8
+ BreadcrumbItem,
9
+ BreadcrumbPressEvent,
10
+ BreadcrumbsProps,
11
+ } from '../../../../types/breadcrumbs';
12
+ import { Button } from '../../../button/public';
13
+ import { Icon } from '../../../icon/public';
14
+ import { Text } from '../../../typography/public';
15
+
16
+ /*** Renders a breadcrumb trail whose final item represents the current location. */
17
+ export const Breadcrumbs = withZoraThemeScope(BreadcrumbsInner);
18
+
19
+ type BreadcrumbRenderItem =
20
+ | {
21
+ item: BreadcrumbItem;
22
+ type: 'item';
23
+ }
24
+ | {
25
+ type: 'ellipsis';
26
+ };
27
+
28
+ /*** Connects serializable breadcrumb items to the component-level item press event. */
29
+ function BreadcrumbsInner({
30
+ themeId: _themeId,
31
+ mode: _mode,
32
+ interactionPolicy,
33
+ items,
34
+ separator = '/',
35
+ maxItems,
36
+ compact = false,
37
+ disabled = false,
38
+ onItemPress,
39
+ testID,
40
+ }: BreadcrumbsProps) {
41
+ const normalizedMaxItems = normalizeMaxItems(maxItems);
42
+ const renderItems = createRenderItems(items, normalizedMaxItems);
43
+ const currentItemId = items.at(-1)?.id;
44
+
45
+ if (items.length === 0) return null;
46
+
47
+ return (
48
+ <Inline align="center" gap={compact ? 'xs' : 's'} testID={testID} wrap="wrap">
49
+ {renderItems.map((renderItem, index) => {
50
+ const showSeparator = index !== renderItems.length - 1;
51
+
52
+ if (renderItem.type === 'ellipsis') {
53
+ return (
54
+ <React.Fragment key="ellipsis">
55
+ <Text emphasis="muted" variant={compact ? 'caption' : 'bodySmall'}>
56
+ …
57
+ </Text>
58
+ {showSeparator ? renderSeparator(separator) : null}
59
+ </React.Fragment>
60
+ );
61
+ }
62
+
63
+ return (
64
+ <BreadcrumbItemView
65
+ compact={compact}
66
+ current={renderItem.item.id === currentItemId}
67
+ disabled={disabled}
68
+ interactionPolicy={interactionPolicy}
69
+ item={renderItem.item}
70
+ key={renderItem.item.id}
71
+ onItemPress={onItemPress}
72
+ separator={showSeparator ? separator : undefined}
73
+ testID={testID}
74
+ />
75
+ );
76
+ })}
77
+ </Inline>
78
+ );
79
+ }
80
+
81
+ /*** Renders one breadcrumb item and its optional following separator. */
82
+ function BreadcrumbItemView({
83
+ compact,
84
+ current,
85
+ disabled,
86
+ interactionPolicy,
87
+ item,
88
+ onItemPress,
89
+ separator,
90
+ testID,
91
+ }: {
92
+ compact: boolean;
93
+ current: boolean;
94
+ disabled: boolean;
95
+ interactionPolicy: BreadcrumbsProps['interactionPolicy'];
96
+ item: BreadcrumbItem;
97
+ onItemPress: ((event: BreadcrumbPressEvent) => void) | undefined;
98
+ separator: string | undefined;
99
+ testID: string | undefined;
100
+ }) {
101
+ const interactive = !current && !disabled && !item.disabled && onItemPress !== undefined;
102
+
103
+ return (
104
+ <>
105
+ {interactive ? (
106
+ <Button
107
+ color="neutral"
108
+ interactionPolicy={interactionPolicy}
109
+ leadingIcon={item.icon}
110
+ onPress={() => onItemPress({ id: item.id })}
111
+ size={compact ? 's' : 'm'}
112
+ testID={testID ? `${testID}-item-${item.id}` : undefined}
113
+ variant="ghost"
114
+ >
115
+ {item.label}
116
+ </Button>
117
+ ) : (
118
+ <BreadcrumbLabel compact={compact} item={item} />
119
+ )}
120
+ {separator === undefined ? null : renderSeparator(separator)}
121
+ </>
122
+ );
123
+ }
124
+
125
+ /*** Renders one non-interactive breadcrumb label. */
126
+ function BreadcrumbLabel({ item, compact }: { item: BreadcrumbItem; compact: boolean }) {
127
+ const { theme } = useZoraTheme();
128
+
129
+ return (
130
+ <Inline align="center" gap="xs" wrap="nowrap">
131
+ {item.icon ? (
132
+ <Icon
133
+ {...item.icon}
134
+ color={theme.semantics.content.muted}
135
+ size={resolveIconSize(compact ? 's' : 'm')}
136
+ />
137
+ ) : null}
138
+ <Text emphasis="muted" variant={compact ? 'caption' : 'bodySmall'}>
139
+ {item.label}
140
+ </Text>
141
+ </Inline>
142
+ );
143
+ }
144
+
145
+ /*** Renders the configured separator with muted breadcrumb styling. */
146
+ function renderSeparator(separator: string): React.ReactNode {
147
+ return (
148
+ <Text emphasis="muted" variant="bodySmall">
149
+ {separator}
150
+ </Text>
151
+ );
152
+ }
153
+
154
+ /*** Normalizes an optional maximum breadcrumb item count. */
155
+ function normalizeMaxItems(value: number | undefined): number | undefined {
156
+ if (value === undefined || !Number.isFinite(value)) return undefined;
157
+ return Math.max(0, Math.trunc(value));
158
+ }
159
+
160
+ /*** Collapses middle breadcrumb items into one ellipsis when required. */
161
+ function createRenderItems(
162
+ items: readonly BreadcrumbItem[],
163
+ maxItems: number | undefined,
164
+ ): readonly BreadcrumbRenderItem[] {
165
+ if (maxItems === undefined || maxItems === 0 || items.length <= maxItems || maxItems < 3) {
166
+ return items.map((item) => ({ item, type: 'item' }));
167
+ }
168
+
169
+ const firstItem = items.at(0);
170
+ if (firstItem === undefined) return [];
171
+
172
+ const trailingCount = maxItems - 2;
173
+ const trailingItems = items.slice(items.length - trailingCount);
174
+ return [
175
+ { item: firstItem, type: 'item' },
176
+ { type: 'ellipsis' },
177
+ ...trailingItems.map((item) => ({ item, type: 'item' }) satisfies BreadcrumbRenderItem),
178
+ ];
179
+ }
@@ -0,0 +1,95 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+
3
+ export const breadcrumbsMeta = {
4
+ name: 'Breadcrumbs',
5
+ category: 'component',
6
+ description: 'Hierarchical route context where the final item represents the current location.',
7
+ directManifestNode: true,
8
+ allowedChildren: [],
9
+ blueprint: {
10
+ label: 'Breadcrumbs',
11
+ defaultProps: {
12
+ items: [
13
+ { id: 'settings', label: 'Settings' },
14
+ { id: 'general', label: 'General' },
15
+ ],
16
+ separator: '/',
17
+ compact: false,
18
+ disabled: false,
19
+ },
20
+ },
21
+ bindings: {
22
+ events: {
23
+ itemPress: {
24
+ label: 'Item press',
25
+ description: 'Runs when a non-current breadcrumb item is pressed.',
26
+ payload: {
27
+ eventType: 'breadcrumbs.itemPress',
28
+ fields: [{ path: 'id', type: 'string', label: 'Item id' }],
29
+ },
30
+ },
31
+ },
32
+ },
33
+ events: {
34
+ itemPress: {
35
+ label: 'Item press',
36
+ eventType: 'breadcrumbs.itemPress',
37
+ description: 'Emitted when a non-current breadcrumb item is pressed.',
38
+ payloadFields: [{ path: 'id', type: 'string', label: 'Item id' }],
39
+ },
40
+ },
41
+ props: {
42
+ items: {
43
+ type: 'array',
44
+ category: 'Content',
45
+ label: 'Items',
46
+ itemSchema: [
47
+ {
48
+ key: 'id',
49
+ schema: { type: 'string', category: 'Content', label: 'Id' },
50
+ },
51
+ {
52
+ key: 'label',
53
+ schema: { type: 'string', category: 'Content', label: 'Label' },
54
+ },
55
+ {
56
+ key: 'disabled',
57
+ schema: {
58
+ type: 'boolean',
59
+ category: 'State',
60
+ label: 'Disabled',
61
+ default: false,
62
+ },
63
+ },
64
+ ],
65
+ authoring: { authority: 'instance' },
66
+ },
67
+ separator: {
68
+ type: 'string',
69
+ category: 'Content',
70
+ label: 'Separator',
71
+ default: '/',
72
+ authoring: { authority: 'instance' },
73
+ },
74
+ maxItems: {
75
+ type: 'number',
76
+ category: 'Layout',
77
+ label: 'Maximum items',
78
+ authoring: { authority: 'instance' },
79
+ },
80
+ compact: {
81
+ type: 'boolean',
82
+ category: 'Layout',
83
+ label: 'Compact',
84
+ default: false,
85
+ authoring: { authority: 'instance' },
86
+ },
87
+ disabled: {
88
+ type: 'boolean',
89
+ category: 'State',
90
+ label: 'Disabled',
91
+ default: false,
92
+ authoring: { authority: 'instance' },
93
+ },
94
+ },
95
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,22 @@
1
+ import { expect, test } from 'bun:test';
2
+
3
+ import { breadcrumbsMeta } from './breadcrumbsMeta';
4
+
5
+ test('Breadcrumbs is a direct manifest node with serializable item press payload', () => {
6
+ expect(breadcrumbsMeta.directManifestNode).toBe(true);
7
+ expect(breadcrumbsMeta.events.itemPress.eventType).toBe('breadcrumbs.itemPress');
8
+ expect(breadcrumbsMeta.events.itemPress.payloadFields).toEqual([
9
+ { path: 'id', type: 'string', label: 'Item id' },
10
+ ]);
11
+ });
12
+
13
+ test('Breadcrumbs keeps current-location derivation and callbacks outside item data', async () => {
14
+ const [source, types] = await Promise.all([
15
+ Bun.file('src/features/breadcrumbs/adapters/inbound/Breadcrumbs.tsx').text(),
16
+ Bun.file('src/types/breadcrumbs.ts').text(),
17
+ ]);
18
+
19
+ expect(source).toContain('const currentItemId = items.at(-1)?.id;');
20
+ expect(source).toContain('onItemPress({ id: item.id })');
21
+ expect(types).not.toContain('onPress?:');
22
+ });
@@ -0,0 +1,6 @@
1
+ export type {
2
+ BreadcrumbItem,
3
+ BreadcrumbPressEvent,
4
+ BreadcrumbsProps,
5
+ } from '../../types/breadcrumbs';
6
+ export { Breadcrumbs } from './adapters/inbound/Breadcrumbs';