@ankhorage/zora 23.2.5 → 23.4.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 (311) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -6
  3. package/dist/capabilities/index.d.ts +75 -0
  4. package/dist/capabilities/index.d.ts.map +1 -0
  5. package/dist/capabilities/index.js +62 -0
  6. package/dist/capabilities/index.js.map +1 -0
  7. package/dist/cli/index.d.ts +74 -1
  8. package/dist/cli/index.d.ts.map +1 -1
  9. package/dist/cli/index.js +4 -5
  10. package/dist/cli/index.js.map +1 -1
  11. package/dist/constants/authoring.d.ts +8 -0
  12. package/dist/constants/authoring.d.ts.map +1 -1
  13. package/dist/constants/authoring.js +6 -0
  14. package/dist/constants/authoring.js.map +1 -1
  15. package/dist/features/app-bar/appBarMeta.d.ts +10 -1
  16. package/dist/features/app-bar/appBarMeta.d.ts.map +1 -1
  17. package/dist/features/app-bar/appBarMeta.js +2 -1
  18. package/dist/features/app-bar/appBarMeta.js.map +1 -1
  19. package/dist/features/app-header/adapters/inbound/AppHeader.d.ts +5 -0
  20. package/dist/features/app-header/adapters/inbound/AppHeader.d.ts.map +1 -0
  21. package/dist/features/app-header/adapters/inbound/AppHeader.js +7 -0
  22. package/dist/features/app-header/adapters/inbound/AppHeader.js.map +1 -0
  23. package/dist/features/app-header/appHeaderMeta.d.ts +18 -0
  24. package/dist/features/app-header/appHeaderMeta.d.ts.map +1 -0
  25. package/dist/features/app-header/appHeaderMeta.js +12 -0
  26. package/dist/features/app-header/appHeaderMeta.js.map +1 -0
  27. package/dist/features/app-header/public.d.ts +3 -0
  28. package/dist/features/app-header/public.d.ts.map +1 -0
  29. package/dist/features/app-header/public.js +2 -0
  30. package/dist/features/app-header/public.js.map +1 -0
  31. package/dist/features/game/adapters/inbound/Game.d.ts +1 -1
  32. package/dist/features/game/adapters/inbound/Game.d.ts.map +1 -1
  33. package/dist/features/game/adapters/inbound/Game.js +4 -1
  34. package/dist/features/game/adapters/inbound/Game.js.map +1 -1
  35. package/dist/features/game/adapters/inbound/GameEntity.d.ts +1 -1
  36. package/dist/features/game/adapters/inbound/GameEntity.d.ts.map +1 -1
  37. package/dist/features/game/adapters/inbound/GameEntity.js +4 -1
  38. package/dist/features/game/adapters/inbound/GameEntity.js.map +1 -1
  39. package/dist/features/game/adapters/inbound/GameField.d.ts +1 -1
  40. package/dist/features/game/adapters/inbound/GameField.d.ts.map +1 -1
  41. package/dist/features/game/adapters/inbound/GameField.js +4 -1
  42. package/dist/features/game/adapters/inbound/GameField.js.map +1 -1
  43. package/dist/features/game/adapters/inbound/GameInputZone.d.ts +1 -1
  44. package/dist/features/game/adapters/inbound/GameInputZone.d.ts.map +1 -1
  45. package/dist/features/game/adapters/inbound/GameInputZone.js +4 -1
  46. package/dist/features/game/adapters/inbound/GameInputZone.js.map +1 -1
  47. package/dist/features/game/adapters/inbound/GameMeasurementProbe.d.ts +2 -1
  48. package/dist/features/game/adapters/inbound/GameMeasurementProbe.d.ts.map +1 -1
  49. package/dist/features/game/adapters/inbound/GameMeasurementProbe.js +4 -1
  50. package/dist/features/game/adapters/inbound/GameMeasurementProbe.js.map +1 -1
  51. package/dist/features/game/adapters/inbound/GameOverlay.d.ts +1 -1
  52. package/dist/features/game/adapters/inbound/GameOverlay.d.ts.map +1 -1
  53. package/dist/features/game/adapters/inbound/GameOverlay.js +4 -1
  54. package/dist/features/game/adapters/inbound/GameOverlay.js.map +1 -1
  55. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.d.ts.map +1 -1
  56. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js +2 -0
  57. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js.map +1 -1
  58. package/dist/features/registry/bindableComponentMeta.d.ts +415 -327
  59. package/dist/features/registry/bindableComponentMeta.d.ts.map +1 -1
  60. package/dist/features/registry/bindableComponentMeta.js +12 -0
  61. package/dist/features/registry/bindableComponentMeta.js.map +1 -1
  62. package/dist/features/registry/componentMeta.d.ts.map +1 -1
  63. package/dist/features/registry/componentMeta.js +2 -0
  64. package/dist/features/registry/componentMeta.js.map +1 -1
  65. package/dist/features/registry/finalizeFeatureMetadata.d.ts.map +1 -1
  66. package/dist/features/registry/finalizeFeatureMetadata.js +5 -4
  67. package/dist/features/registry/finalizeFeatureMetadata.js.map +1 -1
  68. package/dist/features/selection/adapters/inbound/SelectableItem.d.ts +1 -1
  69. package/dist/features/selection/adapters/inbound/SelectableItem.d.ts.map +1 -1
  70. package/dist/features/selection/adapters/inbound/SelectableItem.js +4 -1
  71. package/dist/features/selection/adapters/inbound/SelectableItem.js.map +1 -1
  72. package/dist/features/theme/adapters/inbound/ThemeModeToggle.d.ts +2 -1
  73. package/dist/features/theme/adapters/inbound/ThemeModeToggle.d.ts.map +1 -1
  74. package/dist/features/theme/adapters/inbound/ThemeModeToggle.js +5 -1
  75. package/dist/features/theme/adapters/inbound/ThemeModeToggle.js.map +1 -1
  76. package/dist/features/theme/adapters/inbound/ZoraThemeScope.d.ts +2 -1
  77. package/dist/features/theme/adapters/inbound/ZoraThemeScope.d.ts.map +1 -1
  78. package/dist/features/theme/adapters/inbound/ZoraThemeScope.js +7 -5
  79. package/dist/features/theme/adapters/inbound/ZoraThemeScope.js.map +1 -1
  80. package/dist/features/theme/adapters/inbound/withZoraThemeScope.d.ts +1 -0
  81. package/dist/features/theme/adapters/inbound/withZoraThemeScope.d.ts.map +1 -1
  82. package/dist/features/theme/adapters/inbound/withZoraThemeScope.js +9 -4
  83. package/dist/features/theme/adapters/inbound/withZoraThemeScope.js.map +1 -1
  84. package/dist/index.d.ts +1 -0
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +1 -0
  87. package/dist/index.js.map +1 -1
  88. package/dist/types/app-header.d.ts +3 -0
  89. package/dist/types/app-header.d.ts.map +1 -0
  90. package/dist/types/app-header.js +2 -0
  91. package/dist/types/app-header.js.map +1 -0
  92. package/dist/types/base.d.ts +2 -0
  93. package/dist/types/base.d.ts.map +1 -1
  94. package/dist/types/base.js.map +1 -1
  95. package/dist/types/gamePresentation.d.ts +6 -6
  96. package/dist/types/gamePresentation.d.ts.map +1 -1
  97. package/dist/types/gamePresentation.js.map +1 -1
  98. package/dist/types/selection.d.ts +2 -1
  99. package/dist/types/selection.d.ts.map +1 -1
  100. package/dist/types/selection.js.map +1 -1
  101. package/dist/types/theme-mode-toggle.d.ts +2 -1
  102. package/dist/types/theme-mode-toggle.d.ts.map +1 -1
  103. package/dist/types/theme-mode-toggle.js.map +1 -1
  104. package/package.json +103 -7
  105. package/src/capabilities/index.test.ts +50 -0
  106. package/src/capabilities/index.ts +63 -0
  107. package/src/cli/index.test.ts +10 -1
  108. package/src/cli/index.ts +7 -14
  109. package/src/constants/authoring.ts +7 -0
  110. package/src/features/app-bar/appBarMeta.ts +2 -1
  111. package/src/features/app-header/adapters/inbound/AppHeader.tsx +9 -0
  112. package/src/features/app-header/appHeaderMeta.ts +13 -0
  113. package/src/features/app-header/public.ts +2 -0
  114. package/src/features/game/adapters/inbound/Game.tsx +5 -1
  115. package/src/features/game/adapters/inbound/GameEntity.tsx +5 -1
  116. package/src/features/game/adapters/inbound/GameField.tsx +5 -1
  117. package/src/features/game/adapters/inbound/GameInputZone.tsx +5 -1
  118. package/src/features/game/adapters/inbound/GameMeasurementProbe.tsx +5 -1
  119. package/src/features/game/adapters/inbound/GameOverlay.tsx +5 -1
  120. package/src/features/registry/ZORA_COMPONENT_REGISTRY.ts +2 -0
  121. package/src/features/registry/authoringMeta.test.ts +11 -0
  122. package/src/features/registry/bindableComponentMeta.ts +12 -0
  123. package/src/features/registry/componentMeta.ts +2 -0
  124. package/src/features/registry/finalizeFeatureMetadata.ts +7 -6
  125. package/src/features/registry/registry.test.ts +1 -0
  126. package/src/features/selection/adapters/inbound/SelectableItem.tsx +5 -1
  127. package/src/features/theme/adapters/inbound/ThemeModeToggle.tsx +6 -1
  128. package/src/features/theme/adapters/inbound/ZoraThemeScope.tsx +12 -5
  129. package/src/features/theme/adapters/inbound/withZoraThemeScope.tsx +9 -4
  130. package/src/features/theme/themeConfigScope.test.ts +1 -1
  131. package/src/features/theme/themeScopeStructure.test.ts +6 -1
  132. package/src/index.ts +1 -0
  133. package/src/invertedThemeAcceptance.test.tsx +177 -0
  134. package/src/structureOwnership.test.ts +1 -1
  135. package/src/types/app-header.ts +3 -0
  136. package/src/types/base.ts +3 -0
  137. package/src/types/gamePresentation.ts +7 -6
  138. package/src/types/selection.ts +3 -1
  139. package/src/types/theme-mode-toggle.ts +3 -4
  140. package/web-dist/chunks/{Accordion-c3yfjhex.js → Accordion-0047zyx7.js} +4 -4
  141. package/web-dist/chunks/{Accordion-vq198z68.js → Accordion-0yhkg017.js} +9 -9
  142. package/web-dist/chunks/{Accordion-hztfb9ex.js → Accordion-0yvepteg.js} +5 -5
  143. package/web-dist/chunks/{Accordion-r1geqzsp.js → Accordion-1e1nfhtc.js} +5 -5
  144. package/web-dist/chunks/{Accordion-vc8pv1jf.js → Accordion-1xpq9bxk.js} +7 -7
  145. package/web-dist/chunks/{Accordion-11xym8p8.js → Accordion-2dqpjya2.js} +7 -7
  146. package/web-dist/chunks/{Accordion-g69czys5.js → Accordion-37n4bt3g.js} +2 -2
  147. package/web-dist/chunks/{Accordion-0f748ad5.js → Accordion-3m6de80j.js} +1 -1
  148. package/web-dist/chunks/{Accordion-jynbc7d0.js → Accordion-693gvpde.js} +3 -3
  149. package/web-dist/chunks/{Accordion-een6jq8f.js → Accordion-6xrse5my.js} +1 -1
  150. package/web-dist/chunks/{Accordion-904ncmad.js → Accordion-6ytrt7xj.js} +5 -5
  151. package/web-dist/chunks/{Accordion-jfjery84.js → Accordion-70g7n6tk.js} +8 -8
  152. package/web-dist/chunks/{Accordion-n7hckxte.js → Accordion-73x0gt11.js} +6 -6
  153. package/web-dist/chunks/{Accordion-7cgv14wd.js → Accordion-7y9wt946.js} +2 -2
  154. package/web-dist/chunks/{Accordion-scacsnhj.js → Accordion-8bxy3g7a.js} +3 -3
  155. package/web-dist/chunks/{Accordion-6h4zc69v.js → Accordion-8fne0gf9.js} +4 -4
  156. package/web-dist/chunks/{Accordion-xak1mcaf.js → Accordion-8z7naxj2.js} +18 -13
  157. package/web-dist/chunks/{Accordion-whhnrz92.js → Accordion-a1ervhyg.js} +13 -13
  158. package/web-dist/chunks/{Accordion-tp2gn95w.js → Accordion-adc7k14q.js} +37 -13
  159. package/web-dist/chunks/{Accordion-vtndpbzt.js → Accordion-ancjf7q8.js} +7 -3
  160. package/web-dist/chunks/{Accordion-7ccpdvga.js → Accordion-axxgq453.js} +7 -7
  161. package/web-dist/chunks/{Accordion-bn954rjh.js → Accordion-basd2gyf.js} +2 -2
  162. package/web-dist/chunks/{Accordion-z4d0pncs.js → Accordion-bz2dzbad.js} +9 -9
  163. package/web-dist/chunks/{Accordion-pt0f1v0m.js → Accordion-ct805sm7.js} +2 -2
  164. package/web-dist/chunks/{Accordion-katngqxf.js → Accordion-d24n7srd.js} +4 -4
  165. package/web-dist/chunks/{Accordion-a09gnx45.js → Accordion-dbxpv5eq.js} +3 -3
  166. package/web-dist/chunks/{Accordion-8zerapbc.js → Accordion-e2kr1z3g.js} +5 -5
  167. package/web-dist/chunks/{Accordion-8rx1stgv.js → Accordion-ebw6xj6x.js} +5 -7
  168. package/web-dist/chunks/{Accordion-090whwtv.js → Accordion-ekjwm5dw.js} +17 -8
  169. package/web-dist/chunks/{Accordion-ej4p6ae3.js → Accordion-g2d4fskg.js} +2 -2
  170. package/web-dist/chunks/{Accordion-65kvpq6z.js → Accordion-gkx1kszz.js} +1 -1
  171. package/web-dist/chunks/{Accordion-40sj6k87.js → Accordion-k6dg8zd2.js} +3 -3
  172. package/web-dist/chunks/{Accordion-xdgpa7kf.js → Accordion-kxa15n19.js} +1 -1
  173. package/web-dist/chunks/{Accordion-ps286k56.js → Accordion-m4brcz8v.js} +5 -5
  174. package/web-dist/chunks/{Accordion-hdnpzyk9.js → Accordion-mbqtk7y0.js} +1 -1
  175. package/web-dist/chunks/{Accordion-sh0sk3cz.js → Accordion-nkd7nhyx.js} +5 -5
  176. package/web-dist/chunks/{Accordion-qqsxfq5h.js → Accordion-p0fh69qq.js} +6 -6
  177. package/web-dist/chunks/{Accordion-02d3sw7t.js → Accordion-ph15h010.js} +10 -10
  178. package/web-dist/chunks/{Accordion-a60dhqsv.js → Accordion-pvz3r99n.js} +38 -1
  179. package/web-dist/chunks/{Accordion-qd4r5b4s.js → Accordion-q9zge7kd.js} +2 -2
  180. package/web-dist/chunks/{Accordion-1dppb4fr.js → Accordion-qyssgtwe.js} +2 -2
  181. package/web-dist/chunks/{Accordion-pe49atda.js → Accordion-rmp9sfra.js} +1 -1
  182. package/web-dist/chunks/{Accordion-v1fxp6yd.js → Accordion-snyacfyh.js} +8 -8
  183. package/web-dist/chunks/{Accordion-47mg9vze.js → Accordion-tdjh81ax.js} +5 -5
  184. package/web-dist/chunks/{Accordion-3v7sz3vv.js → Accordion-v4n4ygwn.js} +1 -1
  185. package/web-dist/chunks/{Accordion-2z0415ed.js → Accordion-vjgk1sz7.js} +1 -1
  186. package/web-dist/chunks/{Accordion-qq9bvraa.js → Accordion-wgesygtk.js} +10 -10
  187. package/web-dist/chunks/{Accordion-tvzq4dw8.js → Accordion-wxbh98kp.js} +8 -8
  188. package/web-dist/chunks/{Accordion-3w1t105s.js → Accordion-wytj5wwc.js} +3 -3
  189. package/web-dist/chunks/{Accordion-19j1mncn.js → Accordion-yae3m7g7.js} +4 -4
  190. package/web-dist/chunks/{Accordion-c7pd59w7.js → Accordion-zgzrah0a.js} +6 -6
  191. package/web-dist/components/accordion/Accordion.js +12 -13
  192. package/web-dist/components/accordion-item/AccordionItem.js +12 -13
  193. package/web-dist/components/activity-indicator/ActivityIndicator.js +3 -4
  194. package/web-dist/components/app-bar/AppBar.js +19 -20
  195. package/web-dist/components/app-header/AppHeader.d.ts +3 -0
  196. package/web-dist/components/app-header/AppHeader.js +41 -0
  197. package/web-dist/components/app-header/index.d.ts +1 -0
  198. package/web-dist/components/app-header/index.js +2 -0
  199. package/web-dist/components/app-shell/AppShell.js +6 -7
  200. package/web-dist/components/auth-screen/AuthScreen.js +21 -22
  201. package/web-dist/components/avatar/Avatar.js +12 -13
  202. package/web-dist/components/avatar-group/AvatarGroup.js +12 -13
  203. package/web-dist/components/badge/Badge.js +7 -8
  204. package/web-dist/components/barcode-scanner-view/BarcodeScannerView.js +20 -21
  205. package/web-dist/components/bottom-sheet/BottomSheet.js +8 -9
  206. package/web-dist/components/bottom-sheet-flat-list/BottomSheetFlatList.js +8 -9
  207. package/web-dist/components/bottom-sheet-scroll-view/BottomSheetScrollView.js +8 -9
  208. package/web-dist/components/bottom-sheet-section-list/BottomSheetSectionList.js +8 -9
  209. package/web-dist/components/bottom-sheet-view/BottomSheetView.js +8 -9
  210. package/web-dist/components/bottom-sheet-virtualized-list/BottomSheetVirtualizedList.js +8 -9
  211. package/web-dist/components/breadcrumbs/Breadcrumbs.js +14 -15
  212. package/web-dist/components/button/Button.js +12 -13
  213. package/web-dist/components/button-group/ButtonGroup.js +12 -13
  214. package/web-dist/components/camera-permission-view/CameraPermissionView.js +20 -21
  215. package/web-dist/components/card/Card.js +19 -20
  216. package/web-dist/components/card-back/CardBack.js +4 -5
  217. package/web-dist/components/card-hand/CardHand.js +4 -5
  218. package/web-dist/components/chat-list-item/ChatListItem.js +16 -17
  219. package/web-dist/components/checkbox/Checkbox.js +12 -13
  220. package/web-dist/components/checkbox-group/CheckboxGroup.js +12 -13
  221. package/web-dist/components/chess-board/ChessBoard.js +4 -5
  222. package/web-dist/components/chip/Chip.js +13 -14
  223. package/web-dist/components/chip-group/ChipGroup.js +13 -14
  224. package/web-dist/components/collection-editor/CollectionEditor.js +19 -20
  225. package/web-dist/components/content-rail/ContentRail.js +13 -14
  226. package/web-dist/components/data-table/DataTable.js +26 -27
  227. package/web-dist/components/date-picker/DatePicker.js +17 -18
  228. package/web-dist/components/dialog/Dialog.js +12 -13
  229. package/web-dist/components/divider/Divider.js +6 -7
  230. package/web-dist/components/empty-state/EmptyState.js +20 -21
  231. package/web-dist/components/field/Field.js +12 -13
  232. package/web-dist/components/flat-list/FlatList.js +13 -14
  233. package/web-dist/components/forgot-password-form/ForgotPasswordForm.js +21 -22
  234. package/web-dist/components/form/Form.js +16 -17
  235. package/web-dist/components/form-actions/FormActions.js +16 -17
  236. package/web-dist/components/form-error/FormError.js +16 -17
  237. package/web-dist/components/game/Game.js +7 -8
  238. package/web-dist/components/game-entity/GameEntity.js +7 -8
  239. package/web-dist/components/game-field/GameField.js +7 -8
  240. package/web-dist/components/game-input-zone/GameInputZone.js +7 -8
  241. package/web-dist/components/game-measurement-probe/GameMeasurementProbe.js +7 -8
  242. package/web-dist/components/game-overlay/GameOverlay.js +7 -8
  243. package/web-dist/components/gradient/Gradient.js +7 -8
  244. package/web-dist/components/gradient-renderer-provider/GradientRendererProvider.js +7 -8
  245. package/web-dist/components/grid/Grid.js +6 -7
  246. package/web-dist/components/heading/Heading.js +6 -7
  247. package/web-dist/components/hero/Hero.js +19 -20
  248. package/web-dist/components/icon/Icon.js +4 -5
  249. package/web-dist/components/icon-button/IconButton.js +12 -13
  250. package/web-dist/components/image/Image.js +10 -11
  251. package/web-dist/components/keyboard-avoiding-view/KeyboardAvoidingView.js +3 -4
  252. package/web-dist/components/list/List.js +13 -14
  253. package/web-dist/components/list-item/ListItem.js +13 -14
  254. package/web-dist/components/list-section/ListSection.js +13 -14
  255. package/web-dist/components/media-card/MediaCard.js +19 -20
  256. package/web-dist/components/message-bubble/MessageBubble.js +16 -17
  257. package/web-dist/components/metric-card/MetricCard.js +19 -20
  258. package/web-dist/components/missing-element/MissingElement.js +11 -12
  259. package/web-dist/components/o-auth-provider-button/OAuthProviderButton.js +21 -22
  260. package/web-dist/components/o-auth-provider-list/OAuthProviderList.js +21 -22
  261. package/web-dist/components/opening-book/OpeningBook.js +4 -5
  262. package/web-dist/components/otp-form/OtpForm.js +21 -22
  263. package/web-dist/components/pagination/Pagination.js +13 -14
  264. package/web-dist/components/palette-item/PaletteItem.js +19 -20
  265. package/web-dist/components/playing-card/PlayingCard.js +4 -5
  266. package/web-dist/components/poker-training-table/PokerTrainingTable.js +4 -5
  267. package/web-dist/components/popover-menu/PopoverMenu.js +14 -15
  268. package/web-dist/components/post-card/PostCard.js +19 -20
  269. package/web-dist/components/product-card/ProductCard.js +19 -20
  270. package/web-dist/components/progress/Progress.js +10 -11
  271. package/web-dist/components/progress-ring/ProgressRing.js +10 -11
  272. package/web-dist/components/radio/Radio.js +14 -15
  273. package/web-dist/components/radio-group/RadioGroup.js +14 -15
  274. package/web-dist/components/rating/Rating.js +9 -10
  275. package/web-dist/components/reader-surface/ReaderSurface.js +21 -22
  276. package/web-dist/components/scan-overlay/ScanOverlay.js +20 -21
  277. package/web-dist/components/screen/Screen.js +6 -7
  278. package/web-dist/components/screen-section/ScreenSection.js +10 -11
  279. package/web-dist/components/scroll-view/ScrollView.js +6 -7
  280. package/web-dist/components/search-input/SearchInput.js +13 -14
  281. package/web-dist/components/section-header/SectionHeader.js +10 -11
  282. package/web-dist/components/section-list/SectionList.js +13 -14
  283. package/web-dist/components/select/Select.js +16 -17
  284. package/web-dist/components/selectable-item/SelectableItem.js +6 -5
  285. package/web-dist/components/selection-provider/SelectionProvider.js +6 -5
  286. package/web-dist/components/sign-in-form/SignInForm.js +21 -22
  287. package/web-dist/components/sign-up-form/SignUpForm.js +21 -22
  288. package/web-dist/components/skeleton/Skeleton.js +22 -23
  289. package/web-dist/components/skeleton-card/SkeletonCard.js +22 -23
  290. package/web-dist/components/skeleton-list/SkeletonList.js +22 -23
  291. package/web-dist/components/skeleton-text/SkeletonText.js +22 -23
  292. package/web-dist/components/surface/Surface.js +7 -8
  293. package/web-dist/components/switch/Switch.js +7 -8
  294. package/web-dist/components/tab/Tab.js +7 -8
  295. package/web-dist/components/tab-list/TabList.js +7 -8
  296. package/web-dist/components/tab-panel/TabPanel.js +7 -8
  297. package/web-dist/components/tabletop-table/TabletopTable.js +4 -5
  298. package/web-dist/components/tabs/Tabs.js +7 -8
  299. package/web-dist/components/text/Text.js +6 -7
  300. package/web-dist/components/text-input/TextInput.js +13 -14
  301. package/web-dist/components/time-picker/TimePicker.js +17 -18
  302. package/web-dist/components/timeline/Timeline.js +11 -12
  303. package/web-dist/components/toast/Toast.js +9 -10
  304. package/web-dist/components/toast-provider/ToastProvider.js +9 -10
  305. package/web-dist/components/toolbar/Toolbar.js +19 -20
  306. package/web-dist/components/tree-item/TreeItem.js +17 -18
  307. package/web-dist/components/uploader/Uploader.js +22 -23
  308. package/web-dist/components/view/View.js +6 -7
  309. package/web-dist/manifest.json +1500 -1567
  310. package/web-dist/runtime/ZoraProvider.js +12 -14
  311. package/web-dist/chunks/Accordion-kcx57mk5.js +0 -39
@@ -0,0 +1,63 @@
1
+ import type { Capability } from '@ankhorage/contracts/capabilities';
2
+
3
+ export const CAPABILITIES = [
4
+ {
5
+ id: 'zora.create',
6
+ owner: '@ankhorage/zora',
7
+ access: ['invoke'],
8
+ binding: {
9
+ kind: 'action',
10
+ bindableAs: ['target'],
11
+ },
12
+ label: 'Materialize ZORA web component',
13
+ description: 'Materialize a declared ZORA component and reconcile its web runtime.',
14
+ input: {
15
+ schema: {
16
+ type: 'object',
17
+ required: ['component', 'platform'],
18
+ properties: {
19
+ component: { type: 'string' },
20
+ platform: { type: 'string', const: 'web' },
21
+ },
22
+ additionalProperties: false,
23
+ },
24
+ },
25
+ output: {
26
+ schema: {
27
+ type: 'object',
28
+ required: ['exitCode'],
29
+ properties: { exitCode: { type: 'integer' } },
30
+ additionalProperties: false,
31
+ },
32
+ },
33
+ },
34
+ {
35
+ id: 'zora.sync',
36
+ owner: '@ankhorage/zora',
37
+ access: ['invoke'],
38
+ binding: {
39
+ kind: 'action',
40
+ bindableAs: ['target'],
41
+ },
42
+ label: 'Synchronize ZORA web components',
43
+ description: 'Reconcile the web runtime from the declared ZORA component set.',
44
+ input: {
45
+ schema: {
46
+ type: 'object',
47
+ required: ['platform'],
48
+ properties: {
49
+ platform: { type: 'string', const: 'web' },
50
+ },
51
+ additionalProperties: false,
52
+ },
53
+ },
54
+ output: {
55
+ schema: {
56
+ type: 'object',
57
+ required: ['exitCode'],
58
+ properties: { exitCode: { type: 'integer' } },
59
+ additionalProperties: false,
60
+ },
61
+ },
62
+ },
63
+ ] as const satisfies readonly Capability[];
@@ -1,11 +1,12 @@
1
1
  import { expect, test } from 'bun:test';
2
2
 
3
+ import { CAPABILITIES } from '../capabilities';
3
4
  import provider from './index';
4
5
 
5
6
  test('publishes ZORA create and sync through the Ankh provider', () => {
6
7
  expect(provider.id).toBe('@ankhorage/zora');
7
8
  expect(provider.category).toBe('zora');
8
- expect(provider.capabilities).toEqual(['zora.create', 'zora.sync']);
9
+ expect(provider.capabilities).toBe(CAPABILITIES);
9
10
  expect(provider.commands).toEqual([
10
11
  {
11
12
  path: ['create'],
@@ -22,3 +23,11 @@ test('publishes ZORA create and sync through the Ankh provider', () => {
22
23
  expect(provider.handlers[0]?.path).toEqual(['create']);
23
24
  expect(provider.handlers[1]?.path).toEqual(['sync']);
24
25
  });
26
+
27
+ test('maps every provider command to one canonical capability independent of catalog order', () => {
28
+ const commandCapabilityIds = provider.commands.map((command) => command.capability);
29
+ const capabilityIds = CAPABILITIES.map((capability) => capability.id);
30
+
31
+ expect(new Set(commandCapabilityIds).size).toBe(commandCapabilityIds.length);
32
+ expect(new Set(commandCapabilityIds)).toEqual(new Set(capabilityIds));
33
+ });
package/src/cli/index.ts CHANGED
@@ -2,36 +2,29 @@ import { readFileSync } from 'node:fs';
2
2
  import { dirname, resolve } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
 
5
- import type { AnkhCapabilityId, AnkhCommandProviderManifest } from '@ankhorage/contracts/cli';
5
+ import type { AnkhRuntimeCommandProvider } from '@ankhorage/ankh';
6
+ import type { Capability } from '@ankhorage/contracts/capabilities';
6
7
 
8
+ import { CAPABILITIES } from '../capabilities';
7
9
  import { create } from './commands/create';
8
10
  import { sync } from './commands/sync';
9
11
 
10
- const CREATE_CAPABILITY = 'zora.create' satisfies AnkhCapabilityId;
11
- const SYNC_CAPABILITY = 'zora.sync' satisfies AnkhCapabilityId;
12
12
  const CREATE_COMMAND = {
13
13
  path: ['create'],
14
- capability: CREATE_CAPABILITY,
14
+ capability: 'zora.create' satisfies Capability['id'],
15
15
  summary: 'Materialize a canonical ZORA component for a target platform.',
16
16
  } as const;
17
17
  const SYNC_COMMAND = {
18
18
  path: ['sync'],
19
- capability: SYNC_CAPABILITY,
19
+ capability: 'zora.sync' satisfies Capability['id'],
20
20
  summary: 'Regenerate the declared ZORA web materialization.',
21
21
  } as const;
22
22
 
23
- interface ZoraRuntimeProvider extends AnkhCommandProviderManifest {
24
- readonly handlers: readonly {
25
- readonly path: readonly string[];
26
- readonly handler: typeof create | typeof sync;
27
- }[];
28
- }
29
-
30
23
  const provider = {
31
24
  id: '@ankhorage/zora',
32
25
  category: 'zora',
33
26
  version: readPackageVersion(),
34
- capabilities: [CREATE_CAPABILITY, SYNC_CAPABILITY],
27
+ capabilities: CAPABILITIES,
35
28
  commands: [CREATE_COMMAND, SYNC_COMMAND],
36
29
  handlers: [
37
30
  {
@@ -43,7 +36,7 @@ const provider = {
43
36
  handler: sync,
44
37
  },
45
38
  ],
46
- } satisfies ZoraRuntimeProvider;
39
+ } satisfies AnkhRuntimeCommandProvider;
47
40
 
48
41
  export default provider;
49
42
 
@@ -4,6 +4,13 @@ export const COMPONENT_THEME_AUTHORING = {
4
4
  allowInstanceOverride: true,
5
5
  } as const;
6
6
 
7
+ export const INVERTED_POLARITY_PROP = {
8
+ type: 'boolean',
9
+ category: 'Theme',
10
+ label: 'Inverted surface polarity (inherits when omitted; false resets)',
11
+ authoring: { authority: 'instance' },
12
+ } as const;
13
+
7
14
  export const FEATURE_MANIFEST_ELEMENTS = {
8
15
  auth: [
9
16
  'AuthScreen',
@@ -1,3 +1,4 @@
1
+ import { INVERTED_POLARITY_PROP } from '../../constants/authoring';
1
2
  import type { ZoraComponentMeta } from '../../types/authoring';
2
3
 
3
4
  export const appBarMeta = {
@@ -6,5 +7,5 @@ export const appBarMeta = {
6
7
  directManifestNode: false,
7
8
  allowedChildren: [],
8
9
  note: 'Application chrome component; not represented as a manifest node in v1.',
9
- props: {},
10
+ props: { inverted: INVERTED_POLARITY_PROP },
10
11
  } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+
3
+ import type { AppHeaderProps } from '../../../../types/app-header';
4
+ import { AppBar } from '../../../app-bar/public';
5
+
6
+ /*** Composes application header chrome through the scoped ZORA AppBar. */
7
+ export function AppHeader(props: AppHeaderProps) {
8
+ return <AppBar {...props} />;
9
+ }
@@ -0,0 +1,13 @@
1
+ import { INVERTED_POLARITY_PROP } from '../../constants/authoring';
2
+ import type { ZoraComponentMeta } from '../../types/authoring';
3
+
4
+ export const appHeaderMeta = {
5
+ name: 'AppHeader',
6
+ category: 'pattern',
7
+ directManifestNode: false,
8
+ allowedChildren: [],
9
+ note: 'Application header built from AppBar. Inverted is inherited surface polarity; false resets the subtree to normal polarity.',
10
+ props: {
11
+ inverted: INVERTED_POLARITY_PROP,
12
+ },
13
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,2 @@
1
+ export type { AppHeaderProps } from '../../types/app-header';
2
+ export { AppHeader } from './adapters/inbound/AppHeader';
@@ -2,6 +2,7 @@ import { RuntimeRendererConfigProvider } from '@ankhorage/runtime';
2
2
  import React from 'react';
3
3
 
4
4
  import type { GameProps } from '../../../../types/gamePresentation';
5
+ import { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThemeScope';
5
6
  import { createGameBindingContext } from '../../composition/createGameBindingContext';
6
7
  import { createGameMeasurementRegistry } from '../../composition/createGameMeasurementRegistry';
7
8
  import { GameRuntimeContext } from '../../composition/GameRuntimeContext';
@@ -9,7 +10,10 @@ import { useGameRuntime } from '../../composition/useGameRuntime';
9
10
  import { GameField } from './GameField';
10
11
 
11
12
  /*** Bind one serializable game definition to a local transient session and presentation field. */
12
- export function Game(props: GameProps) {
13
+ export const Game = withZoraThemeScope(GameInner);
14
+
15
+ /*** Render the game session inside the inherited ZORA theme scope. */
16
+ function GameInner(props: GameProps) {
13
17
  const runtime = useGameRuntime(props);
14
18
  const [measurementRegistry] = React.useState(createGameMeasurementRegistry);
15
19
  const runtimeContext = React.useMemo(
@@ -2,11 +2,15 @@ import React from 'react';
2
2
  import { Animated, StyleSheet, type View, type ViewStyle } from 'react-native';
3
3
 
4
4
  import type { GameEntityProps } from '../../../../types/gamePresentation';
5
+ import { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThemeScope';
5
6
  import { useGameEntityAnimatedStyle } from '../../utils/useGameEntityAnimatedStyle';
6
7
  import { useGameEntityMeasurement } from '../../utils/useGameEntityMeasurement';
7
8
 
8
9
  /*** Render one generic positioned game entity without owning gameplay semantics. */
9
- export function GameEntity(props: GameEntityProps) {
10
+ export const GameEntity = withZoraThemeScope(GameEntityInner);
11
+
12
+ /*** Render the positioned entity inside the inherited ZORA theme scope. */
13
+ function GameEntityInner(props: GameEntityProps) {
10
14
  const elementRef = React.useRef<View | null>(null);
11
15
  const animatedStyle = useGameEntityAnimatedStyle(props);
12
16
  useGameEntityMeasurement(elementRef, props.measurementId);
@@ -2,9 +2,13 @@ import { StyleSheet } from 'react-native';
2
2
 
3
3
  import type { GameFieldProps } from '../../../../types/gamePresentation';
4
4
  import { View } from '../../../layout/public';
5
+ import { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThemeScope';
5
6
 
6
7
  /*** Render a bounded relative-positioning surface for game presentation content. */
7
- export function GameField({
8
+ export const GameField = withZoraThemeScope(GameFieldInner);
9
+
10
+ /*** Render the field inside the inherited ZORA theme scope. */
11
+ function GameFieldInner({
8
12
  children,
9
13
  aspectRatio,
10
14
  minHeight = 320,
@@ -1,11 +1,15 @@
1
1
  import { Platform, StyleSheet, View, type ViewStyle } from 'react-native';
2
2
 
3
3
  import type { GameInputZoneProps } from '../../../../types/gamePresentation';
4
+ import { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThemeScope';
4
5
  import { toGamePercentage } from '../../utils/toGamePercentage';
5
6
  import { useGameInputZoneResponder } from './useGameInputZoneResponder';
6
7
 
7
8
  /*** Capture pointer/touch geometry and optional keyboard input as normalized generic Game events. */
8
- export function GameInputZone({
9
+ export const GameInputZone = withZoraThemeScope(GameInputZoneInner);
10
+
11
+ /*** Capture game input inside the inherited ZORA theme scope. */
12
+ function GameInputZoneInner({
9
13
  x = 0,
10
14
  y = 0,
11
15
  width = 100,
@@ -2,11 +2,15 @@ import React from 'react';
2
2
 
3
3
  import type { GameMeasurementProbeProps } from '../../../../types/gamePresentation';
4
4
  import type { GameRuntimeContextValue } from '../../../../types/gameRuntime';
5
+ import { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThemeScope';
5
6
  import { GameRuntimeContext } from '../../composition/GameRuntimeContext';
6
7
  import { createGameMeasurementEvent } from './createGameMeasurementEvent';
7
8
 
8
9
  /*** Measure two registered game entities and dispatch only their raw rendered geometry. */
9
- export function GameMeasurementProbe({
10
+ export const GameMeasurementProbe = withZoraThemeScope(GameMeasurementProbeInner);
11
+
12
+ /*** Measure geometry inside the inherited ZORA theme scope. */
13
+ function GameMeasurementProbeInner({
10
14
  sourceId,
11
15
  targetId,
12
16
  eventType = 'game.measurement',
@@ -2,9 +2,13 @@ import { StyleSheet, type ViewStyle } from 'react-native';
2
2
 
3
3
  import type { GameOverlayPlacement, GameOverlayProps } from '../../../../types/gamePresentation';
4
4
  import { View } from '../../../layout/public';
5
+ import { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThemeScope';
5
6
 
6
7
  /*** Render an absolute game presentation layer for HUD, feedback, and phase content. */
7
- export function GameOverlay({
8
+ export const GameOverlay = withZoraThemeScope(GameOverlayInner);
9
+
10
+ /*** Render the overlay inside the inherited ZORA theme scope. */
11
+ function GameOverlayInner({
8
12
  children,
9
13
  placement = 'fill',
10
14
  blocking = false,
@@ -5,6 +5,7 @@ import type { ZoraComponentRegistry } from '../../types/registry';
5
5
  import { Accordion, AccordionItem } from '../accordion/public';
6
6
  import { ActivityIndicator } from '../activity-indicator/public';
7
7
  import { AppBar } from '../app-bar/public';
8
+ import { AppHeader } from '../app-header/public';
8
9
  import {
9
10
  AuthScreen,
10
11
  ForgotPasswordForm,
@@ -108,6 +109,7 @@ const _ZORA_COMPONENT_REGISTRY = {
108
109
  AccordionItem,
109
110
  ActivityIndicator,
110
111
  AppBar,
112
+ AppHeader,
111
113
  Avatar,
112
114
  AvatarGroup,
113
115
  Badge,
@@ -1,5 +1,6 @@
1
1
  import { describe, expect, test } from 'bun:test';
2
2
 
3
+ import { INVERTED_POLARITY_PROP } from '../../constants/authoring';
3
4
  import { ZORA_COMPONENT_META, type ZoraComponentPropAuthoring } from '.';
4
5
 
5
6
  const componentMetaByName = new Map(Object.entries(ZORA_COMPONENT_META));
@@ -43,4 +44,14 @@ describe('ZORA component prop authoring authority', () => {
43
44
  test('does not introduce a system authority', () => {
44
45
  expect(JSON.stringify(ZORA_COMPONENT_META)).not.toContain('"authority":"system"');
45
46
  });
47
+
48
+ test('describes inherited surface polarity for every direct manifest component', () => {
49
+ for (const [name, meta] of componentMetaByName) {
50
+ if (!meta.directManifestNode) continue;
51
+ expect(meta.props.inverted, name).toEqual(INVERTED_POLARITY_PROP);
52
+ expect(meta.bindings?.props?.inverted?.value.type, name).toBe('boolean');
53
+ }
54
+ expect(ZORA_COMPONENT_META.AppBar.props.inverted).toEqual(INVERTED_POLARITY_PROP);
55
+ expect(ZORA_COMPONENT_META.AppHeader.props.inverted).toEqual(INVERTED_POLARITY_PROP);
56
+ });
46
57
  });
@@ -1,5 +1,6 @@
1
1
  import type { UiComponentMetaRegistry } from '@ankhorage/contracts';
2
2
 
3
+ import { INVERTED_POLARITY_PROP } from '../../constants/authoring';
3
4
  import { imageMeta } from '../image/imageMeta';
4
5
  import { readerSurfaceMeta } from '../reader/meta';
5
6
 
@@ -22,6 +23,7 @@ export const ZORA_BINDABLE_COMPONENT_META = {
22
23
  },
23
24
  },
24
25
  props: {
26
+ inverted: INVERTED_POLARITY_PROP,
25
27
  text: {
26
28
  type: 'string',
27
29
  category: 'Content',
@@ -47,6 +49,7 @@ export const ZORA_BINDABLE_COMPONENT_META = {
47
49
  },
48
50
  },
49
51
  props: {
52
+ inverted: INVERTED_POLARITY_PROP,
50
53
  text: {
51
54
  type: 'string',
52
55
  category: 'Content',
@@ -97,6 +100,7 @@ export const ZORA_BINDABLE_COMPONENT_META = {
97
100
  },
98
101
  },
99
102
  props: {
103
+ inverted: INVERTED_POLARITY_PROP,
100
104
  children: {
101
105
  type: 'string',
102
106
  category: 'Content',
@@ -111,6 +115,7 @@ export const ZORA_BINDABLE_COMPONENT_META = {
111
115
  },
112
116
  Image: {
113
117
  ...imageMeta,
118
+ props: { ...imageMeta.props, inverted: INVERTED_POLARITY_PROP },
114
119
  bindings: {
115
120
  props: {
116
121
  source: {
@@ -174,6 +179,7 @@ export const ZORA_BINDABLE_COMPONENT_META = {
174
179
  },
175
180
  },
176
181
  props: {
182
+ inverted: INVERTED_POLARITY_PROP,
177
183
  value: {
178
184
  type: 'string',
179
185
  category: 'Content',
@@ -229,6 +235,7 @@ export const ZORA_BINDABLE_COMPONENT_META = {
229
235
  },
230
236
  },
231
237
  props: {
238
+ inverted: INVERTED_POLARITY_PROP,
232
239
  value: {
233
240
  type: 'string',
234
241
  category: 'Content',
@@ -284,6 +291,7 @@ export const ZORA_BINDABLE_COMPONENT_META = {
284
291
  },
285
292
  },
286
293
  props: {
294
+ inverted: INVERTED_POLARITY_PROP,
287
295
  checked: {
288
296
  type: 'boolean',
289
297
  category: 'State',
@@ -339,6 +347,7 @@ export const ZORA_BINDABLE_COMPONENT_META = {
339
347
  },
340
348
  },
341
349
  props: {
350
+ inverted: INVERTED_POLARITY_PROP,
342
351
  checked: { type: 'boolean', category: 'State', label: 'Checked' },
343
352
  disabled: { type: 'boolean', category: 'State', label: 'Disabled' },
344
353
  },
@@ -364,6 +373,7 @@ export const ZORA_BINDABLE_COMPONENT_META = {
364
373
  },
365
374
  },
366
375
  props: {
376
+ inverted: INVERTED_POLARITY_PROP,
367
377
  items: {
368
378
  type: 'array',
369
379
  category: 'Data',
@@ -392,6 +402,7 @@ export const ZORA_BINDABLE_COMPONENT_META = {
392
402
  },
393
403
  },
394
404
  props: {
405
+ inverted: INVERTED_POLARITY_PROP,
395
406
  rows: {
396
407
  type: 'array',
397
408
  category: 'Data',
@@ -401,6 +412,7 @@ export const ZORA_BINDABLE_COMPONENT_META = {
401
412
  },
402
413
  ReaderSurface: {
403
414
  ...readerSurfaceMeta,
415
+ props: { ...readerSurfaceMeta.props, inverted: INVERTED_POLARITY_PROP },
404
416
  bindings: {
405
417
  props: {
406
418
  location: {
@@ -3,6 +3,7 @@ import { accordionItemMeta } from '../accordion/accordionItemMeta';
3
3
  import { accordionMeta } from '../accordion/accordionMeta';
4
4
  import { activityIndicatorMeta } from '../activity-indicator/activityIndicatorMeta';
5
5
  import { appBarMeta } from '../app-bar/appBarMeta';
6
+ import { appHeaderMeta } from '../app-header/appHeaderMeta';
6
7
  import { authScreenMeta } from '../auth/authScreenMeta';
7
8
  import { forgotPasswordFormMeta } from '../auth/forgotPasswordFormMeta';
8
9
  import { oauthProviderButtonMeta } from '../auth/oauthProviderButtonMeta';
@@ -115,6 +116,7 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = finalizeFeatureMet
115
116
  Divider: dividerMeta,
116
117
  Surface: surfaceMeta,
117
118
  AppBar: appBarMeta,
119
+ AppHeader: appHeaderMeta,
118
120
  Avatar: avatarMeta,
119
121
  AvatarGroup: avatarGroupMeta,
120
122
  Badge: badgeMeta,
@@ -1,20 +1,21 @@
1
- import { FEATURE_MANIFEST_ELEMENTS } from '../../constants/authoring';
2
- import type { ZoraComponentMetaRegistry } from '../../types/authoring';
1
+ import { INVERTED_POLARITY_PROP } from '../../constants/authoring';
2
+ import type { ZoraComponentMeta, ZoraComponentMetaRegistry } from '../../types/authoring';
3
3
  import { createManifestBindings } from './createManifestBindings';
4
4
 
5
5
  /*** Completes feature bindings while preserving each component's explicit value contracts. */
6
6
  export function finalizeFeatureMetadata(
7
7
  registry: ZoraComponentMetaRegistry,
8
8
  ): ZoraComponentMetaRegistry {
9
- const names: ReadonlySet<string> = new Set(Object.values(FEATURE_MANIFEST_ELEMENTS).flat());
10
9
  return Object.fromEntries(
11
- Object.entries(registry).map(([name, meta]) => {
12
- if (!names.has(name)) return [name, meta];
13
- const bindings = createManifestBindings(meta.props, meta.events);
10
+ Object.entries(registry).map(([name, meta]): [string, ZoraComponentMeta] => {
11
+ if (!meta.directManifestNode) return [name, meta];
12
+ const props = { ...meta.props, inverted: INVERTED_POLARITY_PROP };
13
+ const bindings = createManifestBindings(props, meta.events);
14
14
  return [
15
15
  name,
16
16
  {
17
17
  ...meta,
18
+ props,
18
19
  bindings: {
19
20
  props: { ...bindings.props, ...meta.bindings?.props },
20
21
  events: { ...bindings.events, ...meta.bindings?.events },
@@ -76,6 +76,7 @@ describe('ZORA_COMPONENT_REGISTRY', () => {
76
76
  expect(registry).toEqual({});
77
77
  expect(registryEntries).toContain('Screen');
78
78
  expect(registryEntries).toContain('View');
79
+ expect(registryEntries).toContain('AppHeader');
79
80
  expect(source).toContain("export type { ZoraComponentRegistry } from './types/registry';");
80
81
  expect(source).toContain(
81
82
  "export { ZORA_COMPONENT_REGISTRY } from './features/registry/public';",
@@ -8,6 +8,7 @@ import type {
8
8
  SelectableItemState,
9
9
  SelectionTrigger,
10
10
  } from '../../../../types/selection';
11
+ import { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThemeScope';
11
12
  import { resolveSelectionEventIntent } from '../../application/resolveSelectionEventIntent';
12
13
  import { useSelection } from './SelectionProvider';
13
14
 
@@ -24,7 +25,10 @@ function isRenderProp(
24
25
  }
25
26
 
26
27
  /*** Adds selection behavior to arbitrary child content via render props. */
27
- export function SelectableItem({
28
+ export const SelectableItem = withZoraThemeScope(SelectableItemInner);
29
+
30
+ /*** Render a selectable item inside the inherited ZORA theme scope. */
31
+ function SelectableItemInner({
28
32
  id,
29
33
  trigger,
30
34
  disabled = false,
@@ -2,8 +2,13 @@ import type { ThemeModeToggleProps } from '../../../../types/theme-mode-toggle';
2
2
  import { IconButton } from '../../../button/public';
3
3
  import { useZoraTheme } from '../../composition/useZoraTheme';
4
4
  import { resolveThemeModeToggleState } from '../../utils/resolveThemeModeToggleState';
5
+ import { withZoraThemeScope } from './withZoraThemeScope';
5
6
 
6
- export function ThemeModeToggle({
7
+ /*** Provide a theme mode control with inherited surface polarity. */
8
+ export const ThemeModeToggle = withZoraThemeScope(ThemeModeToggleInner);
9
+
10
+ /*** Render the control from the active theme mode. */
11
+ function ThemeModeToggleInner({
7
12
  disabled,
8
13
  interactionPolicy,
9
14
  size = 'm',
@@ -12,20 +12,21 @@ export interface ZoraThemeScopeProps {
12
12
  children: React.ReactNode;
13
13
  themeId?: ZoraThemeId;
14
14
  mode?: ZoraThemeMode;
15
+ inverted?: boolean;
15
16
  }
16
17
 
17
18
  /*** Applies nested ZORA theme overrides through the public Surface theme scope. */
18
- export function ZoraThemeScope({ children, themeId, mode }: ZoraThemeScopeProps) {
19
- if (mode === undefined && themeId === undefined) return children;
19
+ export function ZoraThemeScope({ children, themeId, mode, inverted }: ZoraThemeScopeProps) {
20
+ if (mode === undefined && themeId === undefined && inverted === undefined) return children;
20
21
  return (
21
- <ZoraThemeScopeInner mode={mode} themeId={themeId}>
22
+ <ZoraThemeScopeInner mode={mode} themeId={themeId} inverted={inverted}>
22
23
  {children}
23
24
  </ZoraThemeScopeInner>
24
25
  );
25
26
  }
26
27
 
27
28
  /*** Resolves and provides the scoped Surface and ZORA theme runtime values. */
28
- function ZoraThemeScopeInner({ children, themeId, mode }: ZoraThemeScopeProps) {
29
+ function ZoraThemeScopeInner({ children, themeId, mode, inverted }: ZoraThemeScopeProps) {
29
30
  const parentRuntime = useZoraThemeRuntime();
30
31
  const scopedThemeId = resolveZoraScopedThemeId({
31
32
  desiredThemeId: themeId,
@@ -33,7 +34,13 @@ function ZoraThemeScopeInner({ children, themeId, mode }: ZoraThemeScopeProps) {
33
34
  });
34
35
  const scopedRuntimeValue = useMemo(() => ({ themeId: scopedThemeId }), [scopedThemeId]);
35
36
  const scopedChildren =
36
- mode === undefined ? children : <ThemeScope mode={mode}>{children}</ThemeScope>;
37
+ mode === undefined && inverted === undefined ? (
38
+ children
39
+ ) : (
40
+ <ThemeScope mode={mode} inverted={inverted}>
41
+ {children}
42
+ </ThemeScope>
43
+ );
37
44
 
38
45
  return (
39
46
  <ZoraThemeRuntimeContext value={scopedRuntimeValue}>{scopedChildren}</ZoraThemeRuntimeContext>
@@ -3,17 +3,22 @@ import React from 'react';
3
3
  import type { ZoraBaseProps } from '../../../../types/base';
4
4
  import { ZoraThemeScope } from './ZoraThemeScope';
5
5
 
6
+ /*** Applies optional theme and polarity overrides to any ZORA component. */
6
7
  export function withZoraThemeScope<P extends ZoraBaseProps>(
7
8
  Component: (props: P) => React.ReactElement | null,
8
9
  ): (props: P) => React.ReactElement | null {
9
10
  const Wrapped = (props: P) => {
10
- if (props.mode === undefined && props.themeId === undefined) {
11
- return React.createElement(Component, props);
11
+ const componentProps = { ...props };
12
+ delete componentProps.themeId;
13
+ delete componentProps.mode;
14
+ delete componentProps.inverted;
15
+ if (props.mode === undefined && props.themeId === undefined && props.inverted === undefined) {
16
+ return React.createElement(Component, componentProps);
12
17
  }
13
18
 
14
19
  return (
15
- <ZoraThemeScope mode={props.mode} themeId={props.themeId}>
16
- {React.createElement(Component, props)}
20
+ <ZoraThemeScope mode={props.mode} themeId={props.themeId} inverted={props.inverted}>
21
+ {React.createElement(Component, componentProps)}
17
22
  </ZoraThemeScope>
18
23
  );
19
24
  };
@@ -27,7 +27,7 @@ describe('canonical ThemeConfig scope propagation', () => {
27
27
  test('nested scopes delegate Surface config and mode ownership to ThemeScope', () => {
28
28
  const scope = readFileSync(join(themeDir, 'adapters', 'inbound', 'ZoraThemeScope.tsx'), 'utf8');
29
29
  expect(scope).toContain("import { ThemeScope } from '@ankhorage/surface';");
30
- expect(scope).toContain('<ThemeScope mode={mode}>');
30
+ expect(scope).toContain('<ThemeScope mode={mode} inverted={inverted}>');
31
31
  expect(scope).not.toContain('parentSurface');
32
32
  expect(scope).not.toContain('sourceConfig');
33
33
  expect(scope).not.toContain('createTheme');
@@ -178,6 +178,7 @@ describe('theme scope structure', () => {
178
178
  it('delegates nested Surface runtime ownership to the public ThemeScope boundary', () => {
179
179
  expect(themeScopeSource).toMatch(/import \{ ThemeScope \} from '@ankhorage\/surface'/u);
180
180
  expect(themeScopeSource).toMatch(/<ThemeScope\s+mode=/u);
181
+ expect(themeScopeSource).toMatch(/inverted=\{inverted\}/u);
181
182
  expect(themeScopeSource).not.toMatch(/ThemeContext/u);
182
183
  expect(themeScopeSource).not.toMatch(/useFontContext/u);
183
184
  expect(themeScopeSource).not.toMatch(/createTheme\(/u);
@@ -185,9 +186,13 @@ describe('theme scope structure', () => {
185
186
  expect(themeScopeSource).not.toMatch(/<ThemeProvider\b/u);
186
187
  });
187
188
 
188
- it('wraps components only when mode/themeId overrides are present', () => {
189
+ it('wraps components only when mode/themeId/inverted overrides are present', () => {
189
190
  expect(hocSource).toMatch(/props\.mode === undefined/u);
190
191
  expect(hocSource).toMatch(/props\.themeId === undefined/u);
192
+ expect(hocSource).toMatch(/props\.inverted === undefined/u);
193
+ expect(hocSource).toMatch(/delete componentProps\.themeId/u);
194
+ expect(hocSource).toMatch(/delete componentProps\.mode/u);
195
+ expect(hocSource).toMatch(/delete componentProps\.inverted/u);
191
196
  expect(hocSource).toMatch(/<ZoraThemeScope/u);
192
197
  });
193
198
 
package/src/index.ts CHANGED
@@ -13,6 +13,7 @@ export {
13
13
  } from './features/activity-indicator/public';
14
14
  export type { AppBarMode, AppBarOverflowMenu, AppBarProps } from './features/app-bar/public';
15
15
  export { AppBar } from './features/app-bar/public';
16
+ export { AppHeader, type AppHeaderProps } from './features/app-header/public';
16
17
  export type {
17
18
  AuthFormBaseProps,
18
19
  AuthIdentifierKind,