@ankhorage/zora 1.2.0 → 1.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 (366) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +207 -0
  3. package/dist/components/app-bar/meta.d.ts +9 -0
  4. package/dist/components/app-bar/meta.d.ts.map +1 -0
  5. package/dist/components/app-bar/meta.js +9 -0
  6. package/dist/components/app-bar/meta.js.map +1 -0
  7. package/dist/components/avatar/meta.d.ts +9 -0
  8. package/dist/components/avatar/meta.d.ts.map +1 -0
  9. package/dist/components/avatar/meta.js +9 -0
  10. package/dist/components/avatar/meta.js.map +1 -0
  11. package/dist/components/avatar-group/meta.d.ts +9 -0
  12. package/dist/components/avatar-group/meta.d.ts.map +1 -0
  13. package/dist/components/avatar-group/meta.js +9 -0
  14. package/dist/components/avatar-group/meta.js.map +1 -0
  15. package/dist/components/badge/meta.d.ts +9 -0
  16. package/dist/components/badge/meta.d.ts.map +1 -0
  17. package/dist/components/badge/meta.js +9 -0
  18. package/dist/components/badge/meta.js.map +1 -0
  19. package/dist/components/button/meta.d.ts +45 -0
  20. package/dist/components/button/meta.d.ts.map +1 -0
  21. package/dist/components/button/meta.js +45 -0
  22. package/dist/components/button/meta.js.map +1 -0
  23. package/dist/components/card/meta.d.ts +44 -0
  24. package/dist/components/card/meta.d.ts.map +1 -0
  25. package/dist/components/card/meta.js +45 -0
  26. package/dist/components/card/meta.js.map +1 -0
  27. package/dist/components/checkbox/meta.d.ts +17 -0
  28. package/dist/components/checkbox/meta.d.ts.map +1 -0
  29. package/dist/components/checkbox/meta.js +17 -0
  30. package/dist/components/checkbox/meta.js.map +1 -0
  31. package/dist/components/chip/meta.d.ts +9 -0
  32. package/dist/components/chip/meta.d.ts.map +1 -0
  33. package/dist/components/chip/meta.js +9 -0
  34. package/dist/components/chip/meta.js.map +1 -0
  35. package/dist/components/chip-group/meta.d.ts +9 -0
  36. package/dist/components/chip-group/meta.d.ts.map +1 -0
  37. package/dist/components/chip-group/meta.js +9 -0
  38. package/dist/components/chip-group/meta.js.map +1 -0
  39. package/dist/components/drawer/meta.d.ts +9 -0
  40. package/dist/components/drawer/meta.d.ts.map +1 -0
  41. package/dist/components/drawer/meta.js +9 -0
  42. package/dist/components/drawer/meta.js.map +1 -0
  43. package/dist/components/form/meta.d.ts +79 -0
  44. package/dist/components/form/meta.d.ts.map +1 -0
  45. package/dist/components/form/meta.js +79 -0
  46. package/dist/components/form/meta.js.map +1 -0
  47. package/dist/components/heading/meta.d.ts +69 -0
  48. package/dist/components/heading/meta.d.ts.map +1 -0
  49. package/dist/components/heading/meta.js +66 -0
  50. package/dist/components/heading/meta.js.map +1 -0
  51. package/dist/components/icon/meta.d.ts +9 -0
  52. package/dist/components/icon/meta.d.ts.map +1 -0
  53. package/dist/components/icon/meta.js +9 -0
  54. package/dist/components/icon/meta.js.map +1 -0
  55. package/dist/components/icon-button/meta.d.ts +9 -0
  56. package/dist/components/icon-button/meta.d.ts.map +1 -0
  57. package/dist/components/icon-button/meta.js +9 -0
  58. package/dist/components/icon-button/meta.js.map +1 -0
  59. package/dist/components/image/meta.d.ts +9 -0
  60. package/dist/components/image/meta.d.ts.map +1 -0
  61. package/dist/components/image/meta.js +9 -0
  62. package/dist/components/image/meta.js.map +1 -0
  63. package/dist/components/input/meta.d.ts +45 -0
  64. package/dist/components/input/meta.d.ts.map +1 -0
  65. package/dist/components/input/meta.js +45 -0
  66. package/dist/components/input/meta.js.map +1 -0
  67. package/dist/components/media-card/meta.d.ts +9 -0
  68. package/dist/components/media-card/meta.d.ts.map +1 -0
  69. package/dist/components/media-card/meta.js +9 -0
  70. package/dist/components/media-card/meta.js.map +1 -0
  71. package/dist/components/metric-card/meta.d.ts +9 -0
  72. package/dist/components/metric-card/meta.d.ts.map +1 -0
  73. package/dist/components/metric-card/meta.js +9 -0
  74. package/dist/components/metric-card/meta.js.map +1 -0
  75. package/dist/components/modal/meta.d.ts +9 -0
  76. package/dist/components/modal/meta.d.ts.map +1 -0
  77. package/dist/components/modal/meta.js +9 -0
  78. package/dist/components/modal/meta.js.map +1 -0
  79. package/dist/components/navigation-item/meta.d.ts +9 -0
  80. package/dist/components/navigation-item/meta.d.ts.map +1 -0
  81. package/dist/components/navigation-item/meta.js +9 -0
  82. package/dist/components/navigation-item/meta.js.map +1 -0
  83. package/dist/components/navigation-list/meta.d.ts +9 -0
  84. package/dist/components/navigation-list/meta.d.ts.map +1 -0
  85. package/dist/components/navigation-list/meta.js +9 -0
  86. package/dist/components/navigation-list/meta.js.map +1 -0
  87. package/dist/components/progress/meta.d.ts +9 -0
  88. package/dist/components/progress/meta.d.ts.map +1 -0
  89. package/dist/components/progress/meta.js +9 -0
  90. package/dist/components/progress/meta.js.map +1 -0
  91. package/dist/components/radio/meta.d.ts +17 -0
  92. package/dist/components/radio/meta.d.ts.map +1 -0
  93. package/dist/components/radio/meta.js +17 -0
  94. package/dist/components/radio/meta.js.map +1 -0
  95. package/dist/components/rating/meta.d.ts +9 -0
  96. package/dist/components/rating/meta.d.ts.map +1 -0
  97. package/dist/components/rating/meta.js +9 -0
  98. package/dist/components/rating/meta.js.map +1 -0
  99. package/dist/components/search-bar/meta.d.ts +9 -0
  100. package/dist/components/search-bar/meta.d.ts.map +1 -0
  101. package/dist/components/search-bar/meta.js +9 -0
  102. package/dist/components/search-bar/meta.js.map +1 -0
  103. package/dist/components/select/meta.d.ts +9 -0
  104. package/dist/components/select/meta.d.ts.map +1 -0
  105. package/dist/components/select/meta.js +9 -0
  106. package/dist/components/select/meta.js.map +1 -0
  107. package/dist/components/tabs/meta.d.ts +9 -0
  108. package/dist/components/tabs/meta.d.ts.map +1 -0
  109. package/dist/components/tabs/meta.js +9 -0
  110. package/dist/components/tabs/meta.js.map +1 -0
  111. package/dist/components/text/meta.d.ts +71 -0
  112. package/dist/components/text/meta.d.ts.map +1 -0
  113. package/dist/components/text/meta.js +68 -0
  114. package/dist/components/text/meta.js.map +1 -0
  115. package/dist/components/textarea/meta.d.ts +45 -0
  116. package/dist/components/textarea/meta.d.ts.map +1 -0
  117. package/dist/components/textarea/meta.js +45 -0
  118. package/dist/components/textarea/meta.js.map +1 -0
  119. package/dist/components/toolbar/meta.d.ts +17 -0
  120. package/dist/components/toolbar/meta.d.ts.map +1 -0
  121. package/dist/components/toolbar/meta.js +17 -0
  122. package/dist/components/toolbar/meta.js.map +1 -0
  123. package/dist/foundation/meta.d.ts +93 -0
  124. package/dist/foundation/meta.d.ts.map +1 -0
  125. package/dist/foundation/meta.js +84 -0
  126. package/dist/foundation/meta.js.map +1 -0
  127. package/dist/index.d.ts +4 -0
  128. package/dist/index.d.ts.map +1 -1
  129. package/dist/index.js +2 -0
  130. package/dist/index.js.map +1 -1
  131. package/dist/layout/app-shell/meta.d.ts +9 -0
  132. package/dist/layout/app-shell/meta.d.ts.map +1 -0
  133. package/dist/layout/app-shell/meta.js +9 -0
  134. package/dist/layout/app-shell/meta.js.map +1 -0
  135. package/dist/layout/auth-layout/meta.d.ts +33 -0
  136. package/dist/layout/auth-layout/meta.d.ts.map +1 -0
  137. package/dist/layout/auth-layout/meta.js +34 -0
  138. package/dist/layout/auth-layout/meta.js.map +1 -0
  139. package/dist/layout/page/meta.d.ts +19 -0
  140. package/dist/layout/page/meta.d.ts.map +1 -0
  141. package/dist/layout/page/meta.js +20 -0
  142. package/dist/layout/page/meta.js.map +1 -0
  143. package/dist/layout/page-header/meta.d.ts +38 -0
  144. package/dist/layout/page-header/meta.d.ts.map +1 -0
  145. package/dist/layout/page-header/meta.js +38 -0
  146. package/dist/layout/page-header/meta.js.map +1 -0
  147. package/dist/layout/page-section/meta.d.ts +28 -0
  148. package/dist/layout/page-section/meta.d.ts.map +1 -0
  149. package/dist/layout/page-section/meta.js +29 -0
  150. package/dist/layout/page-section/meta.js.map +1 -0
  151. package/dist/layout/settings-layout/meta.d.ts +9 -0
  152. package/dist/layout/settings-layout/meta.d.ts.map +1 -0
  153. package/dist/layout/settings-layout/meta.js +9 -0
  154. package/dist/layout/settings-layout/meta.js.map +1 -0
  155. package/dist/layout/sidebar-layout/meta.d.ts +9 -0
  156. package/dist/layout/sidebar-layout/meta.d.ts.map +1 -0
  157. package/dist/layout/sidebar-layout/meta.js +9 -0
  158. package/dist/layout/sidebar-layout/meta.js.map +1 -0
  159. package/dist/layout/topbar-layout/meta.d.ts +9 -0
  160. package/dist/layout/topbar-layout/meta.d.ts.map +1 -0
  161. package/dist/layout/topbar-layout/meta.js +9 -0
  162. package/dist/layout/topbar-layout/meta.js.map +1 -0
  163. package/dist/metadata/allowedChildren.d.ts +4 -0
  164. package/dist/metadata/allowedChildren.d.ts.map +1 -0
  165. package/dist/metadata/allowedChildren.js +26 -0
  166. package/dist/metadata/allowedChildren.js.map +1 -0
  167. package/dist/metadata/componentMeta.d.ts +3 -0
  168. package/dist/metadata/componentMeta.d.ts.map +1 -0
  169. package/dist/metadata/componentMeta.js +141 -0
  170. package/dist/metadata/componentMeta.js.map +1 -0
  171. package/dist/metadata/index.d.ts +3 -0
  172. package/dist/metadata/index.d.ts.map +1 -0
  173. package/dist/metadata/index.js +2 -0
  174. package/dist/metadata/index.js.map +1 -0
  175. package/dist/metadata/types.d.ts +49 -0
  176. package/dist/metadata/types.d.ts.map +1 -0
  177. package/dist/metadata/types.js +2 -0
  178. package/dist/metadata/types.js.map +1 -0
  179. package/dist/patterns/auth/meta.d.ts +33 -0
  180. package/dist/patterns/auth/meta.d.ts.map +1 -0
  181. package/dist/patterns/auth/meta.js +34 -0
  182. package/dist/patterns/auth/meta.js.map +1 -0
  183. package/dist/patterns/collection-editor/meta.d.ts +9 -0
  184. package/dist/patterns/collection-editor/meta.d.ts.map +1 -0
  185. package/dist/patterns/collection-editor/meta.js +9 -0
  186. package/dist/patterns/collection-editor/meta.js.map +1 -0
  187. package/dist/patterns/confirm-dialog/meta.d.ts +9 -0
  188. package/dist/patterns/confirm-dialog/meta.d.ts.map +1 -0
  189. package/dist/patterns/confirm-dialog/meta.js +9 -0
  190. package/dist/patterns/confirm-dialog/meta.js.map +1 -0
  191. package/dist/patterns/disclosure-section/meta.d.ts +9 -0
  192. package/dist/patterns/disclosure-section/meta.d.ts.map +1 -0
  193. package/dist/patterns/disclosure-section/meta.js +9 -0
  194. package/dist/patterns/disclosure-section/meta.js.map +1 -0
  195. package/dist/patterns/empty-state/meta.d.ts +33 -0
  196. package/dist/patterns/empty-state/meta.d.ts.map +1 -0
  197. package/dist/patterns/empty-state/meta.js +33 -0
  198. package/dist/patterns/empty-state/meta.js.map +1 -0
  199. package/dist/patterns/filter-bar/meta.d.ts +9 -0
  200. package/dist/patterns/filter-bar/meta.d.ts.map +1 -0
  201. package/dist/patterns/filter-bar/meta.js +9 -0
  202. package/dist/patterns/filter-bar/meta.js.map +1 -0
  203. package/dist/patterns/image-preview/meta.d.ts +9 -0
  204. package/dist/patterns/image-preview/meta.d.ts.map +1 -0
  205. package/dist/patterns/image-preview/meta.js +9 -0
  206. package/dist/patterns/image-preview/meta.js.map +1 -0
  207. package/dist/patterns/image-upload-field/meta.d.ts +9 -0
  208. package/dist/patterns/image-upload-field/meta.d.ts.map +1 -0
  209. package/dist/patterns/image-upload-field/meta.js +9 -0
  210. package/dist/patterns/image-upload-field/meta.js.map +1 -0
  211. package/dist/patterns/inspector-field/meta.d.ts +9 -0
  212. package/dist/patterns/inspector-field/meta.d.ts.map +1 -0
  213. package/dist/patterns/inspector-field/meta.js +9 -0
  214. package/dist/patterns/inspector-field/meta.js.map +1 -0
  215. package/dist/patterns/list/meta.d.ts +25 -0
  216. package/dist/patterns/list/meta.d.ts.map +1 -0
  217. package/dist/patterns/list/meta.js +26 -0
  218. package/dist/patterns/list/meta.js.map +1 -0
  219. package/dist/patterns/notice/meta.d.ts +34 -0
  220. package/dist/patterns/notice/meta.d.ts.map +1 -0
  221. package/dist/patterns/notice/meta.js +35 -0
  222. package/dist/patterns/notice/meta.js.map +1 -0
  223. package/dist/patterns/panel/meta.d.ts +44 -0
  224. package/dist/patterns/panel/meta.d.ts.map +1 -0
  225. package/dist/patterns/panel/meta.js +45 -0
  226. package/dist/patterns/panel/meta.js.map +1 -0
  227. package/dist/patterns/responsive-panel/meta.d.ts +9 -0
  228. package/dist/patterns/responsive-panel/meta.d.ts.map +1 -0
  229. package/dist/patterns/responsive-panel/meta.js +9 -0
  230. package/dist/patterns/responsive-panel/meta.js.map +1 -0
  231. package/dist/patterns/section-header/meta.d.ts +33 -0
  232. package/dist/patterns/section-header/meta.d.ts.map +1 -0
  233. package/dist/patterns/section-header/meta.js +33 -0
  234. package/dist/patterns/section-header/meta.js.map +1 -0
  235. package/dist/patterns/selection/SelectableItem.d.ts +4 -0
  236. package/dist/patterns/selection/SelectableItem.d.ts.map +1 -0
  237. package/dist/patterns/selection/SelectableItem.js +72 -0
  238. package/dist/patterns/selection/SelectableItem.js.map +1 -0
  239. package/dist/patterns/selection/SelectionProvider.d.ts +5 -0
  240. package/dist/patterns/selection/SelectionProvider.d.ts.map +1 -0
  241. package/dist/patterns/selection/SelectionProvider.js +64 -0
  242. package/dist/patterns/selection/SelectionProvider.js.map +1 -0
  243. package/dist/patterns/selection/index.d.ts +4 -0
  244. package/dist/patterns/selection/index.d.ts.map +1 -0
  245. package/dist/patterns/selection/index.js +3 -0
  246. package/dist/patterns/selection/index.js.map +1 -0
  247. package/dist/patterns/selection/meta.d.ts +17 -0
  248. package/dist/patterns/selection/meta.d.ts.map +1 -0
  249. package/dist/patterns/selection/meta.js +18 -0
  250. package/dist/patterns/selection/meta.js.map +1 -0
  251. package/dist/patterns/selection/resolveSelectionNextIds.d.ts +15 -0
  252. package/dist/patterns/selection/resolveSelectionNextIds.d.ts.map +1 -0
  253. package/dist/patterns/selection/resolveSelectionNextIds.js +44 -0
  254. package/dist/patterns/selection/resolveSelectionNextIds.js.map +1 -0
  255. package/dist/patterns/selection/types.d.ts +38 -0
  256. package/dist/patterns/selection/types.d.ts.map +1 -0
  257. package/dist/patterns/selection/types.js +2 -0
  258. package/dist/patterns/selection/types.js.map +1 -0
  259. package/dist/patterns/settings-row/meta.d.ts +39 -0
  260. package/dist/patterns/settings-row/meta.d.ts.map +1 -0
  261. package/dist/patterns/settings-row/meta.js +39 -0
  262. package/dist/patterns/settings-row/meta.js.map +1 -0
  263. package/dist/patterns/switch-field/meta.d.ts +9 -0
  264. package/dist/patterns/switch-field/meta.d.ts.map +1 -0
  265. package/dist/patterns/switch-field/meta.js +9 -0
  266. package/dist/patterns/switch-field/meta.js.map +1 -0
  267. package/dist/patterns/theme-composer/meta.d.ts +9 -0
  268. package/dist/patterns/theme-composer/meta.d.ts.map +1 -0
  269. package/dist/patterns/theme-composer/meta.js +9 -0
  270. package/dist/patterns/theme-composer/meta.js.map +1 -0
  271. package/dist/patterns/tile-grid/meta.d.ts +17 -0
  272. package/dist/patterns/tile-grid/meta.d.ts.map +1 -0
  273. package/dist/patterns/tile-grid/meta.js +18 -0
  274. package/dist/patterns/tile-grid/meta.js.map +1 -0
  275. package/dist/patterns/timeline/meta.d.ts +9 -0
  276. package/dist/patterns/timeline/meta.d.ts.map +1 -0
  277. package/dist/patterns/timeline/meta.js +9 -0
  278. package/dist/patterns/timeline/meta.js.map +1 -0
  279. package/dist/patterns/tree-view/meta.d.ts +17 -0
  280. package/dist/patterns/tree-view/meta.d.ts.map +1 -0
  281. package/dist/patterns/tree-view/meta.js +18 -0
  282. package/dist/patterns/tree-view/meta.js.map +1 -0
  283. package/dist/patterns/zora-drawer-content/meta.d.ts +9 -0
  284. package/dist/patterns/zora-drawer-content/meta.d.ts.map +1 -0
  285. package/dist/patterns/zora-drawer-content/meta.js +9 -0
  286. package/dist/patterns/zora-drawer-content/meta.js.map +1 -0
  287. package/dist/patterns/zora-tab-bar/meta.d.ts +9 -0
  288. package/dist/patterns/zora-tab-bar/meta.d.ts.map +1 -0
  289. package/dist/patterns/zora-tab-bar/meta.js +9 -0
  290. package/dist/patterns/zora-tab-bar/meta.js.map +1 -0
  291. package/package.json +1 -1
  292. package/src/components/app-bar/meta.ts +10 -0
  293. package/src/components/avatar/meta.ts +10 -0
  294. package/src/components/avatar-group/meta.ts +10 -0
  295. package/src/components/badge/meta.ts +10 -0
  296. package/src/components/button/meta.ts +46 -0
  297. package/src/components/card/meta.ts +46 -0
  298. package/src/components/checkbox/meta.ts +19 -0
  299. package/src/components/chip/meta.ts +10 -0
  300. package/src/components/chip-group/meta.ts +10 -0
  301. package/src/components/drawer/meta.ts +10 -0
  302. package/src/components/form/meta.ts +83 -0
  303. package/src/components/heading/meta.ts +67 -0
  304. package/src/components/icon/meta.ts +10 -0
  305. package/src/components/icon-button/meta.ts +10 -0
  306. package/src/components/image/meta.ts +10 -0
  307. package/src/components/input/meta.ts +46 -0
  308. package/src/components/media-card/meta.ts +10 -0
  309. package/src/components/metric-card/meta.ts +10 -0
  310. package/src/components/modal/meta.ts +10 -0
  311. package/src/components/navigation-item/meta.ts +10 -0
  312. package/src/components/navigation-list/meta.ts +10 -0
  313. package/src/components/progress/meta.ts +10 -0
  314. package/src/components/radio/meta.ts +19 -0
  315. package/src/components/rating/meta.ts +10 -0
  316. package/src/components/search-bar/meta.ts +10 -0
  317. package/src/components/select/meta.ts +10 -0
  318. package/src/components/tabs/meta.ts +10 -0
  319. package/src/components/text/meta.ts +69 -0
  320. package/src/components/textarea/meta.ts +46 -0
  321. package/src/components/toolbar/meta.ts +19 -0
  322. package/src/foundation/meta.ts +85 -0
  323. package/src/index.ts +22 -0
  324. package/src/layout/app-shell/meta.ts +10 -0
  325. package/src/layout/auth-layout/meta.ts +35 -0
  326. package/src/layout/page/meta.ts +21 -0
  327. package/src/layout/page-header/meta.ts +39 -0
  328. package/src/layout/page-section/meta.ts +30 -0
  329. package/src/layout/settings-layout/meta.ts +10 -0
  330. package/src/layout/sidebar-layout/meta.ts +10 -0
  331. package/src/layout/topbar-layout/meta.ts +10 -0
  332. package/src/metadata/allowedChildren.ts +27 -0
  333. package/src/metadata/componentMeta.test.ts +204 -0
  334. package/src/metadata/componentMeta.ts +147 -0
  335. package/src/metadata/index.ts +13 -0
  336. package/src/metadata/types.ts +74 -0
  337. package/src/patterns/auth/meta.ts +39 -0
  338. package/src/patterns/collection-editor/meta.ts +10 -0
  339. package/src/patterns/confirm-dialog/meta.ts +10 -0
  340. package/src/patterns/disclosure-section/meta.ts +10 -0
  341. package/src/patterns/empty-state/meta.ts +34 -0
  342. package/src/patterns/filter-bar/meta.ts +10 -0
  343. package/src/patterns/image-preview/meta.ts +10 -0
  344. package/src/patterns/image-upload-field/meta.ts +10 -0
  345. package/src/patterns/inspector-field/meta.ts +10 -0
  346. package/src/patterns/list/meta.ts +30 -0
  347. package/src/patterns/notice/meta.ts +36 -0
  348. package/src/patterns/panel/meta.ts +46 -0
  349. package/src/patterns/responsive-panel/meta.ts +10 -0
  350. package/src/patterns/section-header/meta.ts +34 -0
  351. package/src/patterns/selection/SelectableItem.tsx +93 -0
  352. package/src/patterns/selection/SelectionProvider.tsx +102 -0
  353. package/src/patterns/selection/index.ts +10 -0
  354. package/src/patterns/selection/meta.ts +21 -0
  355. package/src/patterns/selection/resolveSelectionNextIds.test.ts +61 -0
  356. package/src/patterns/selection/resolveSelectionNextIds.ts +71 -0
  357. package/src/patterns/selection/types.ts +43 -0
  358. package/src/patterns/settings-row/meta.ts +40 -0
  359. package/src/patterns/switch-field/meta.ts +10 -0
  360. package/src/patterns/theme-composer/meta.ts +10 -0
  361. package/src/patterns/tile-grid/meta.ts +21 -0
  362. package/src/patterns/timeline/meta.ts +10 -0
  363. package/src/patterns/tree-view/meta.ts +21 -0
  364. package/src/patterns/zora-drawer-content/meta.ts +10 -0
  365. package/src/patterns/zora-tab-bar/meta.ts +10 -0
  366. package/src/showcaseCoverage.test.ts +3 -0
@@ -0,0 +1,102 @@
1
+ import React from 'react';
2
+
3
+ import { areIdsEqual, clearIds, normalizeIds, selectId, toggleId } from './resolveSelectionNextIds';
4
+ import type { SelectionMode, SelectionProviderProps, UseSelectionResult } from './types';
5
+
6
+ const MISSING_CONTEXT_MESSAGE =
7
+ 'ZORA selection context is missing. Wrap this tree in <SelectionProvider>.';
8
+
9
+ type SelectionContextValue = UseSelectionResult;
10
+
11
+ const SelectionContext = React.createContext<SelectionContextValue | null>(null);
12
+
13
+ function resolveMode(mode: SelectionMode | undefined): SelectionMode {
14
+ return mode ?? 'single';
15
+ }
16
+
17
+ function resolveDisabled(disabled: boolean | undefined): boolean {
18
+ return disabled ?? false;
19
+ }
20
+
21
+ export function useSelection(): UseSelectionResult {
22
+ const value = React.useContext(SelectionContext);
23
+ if (!value) {
24
+ throw new Error(MISSING_CONTEXT_MESSAGE);
25
+ }
26
+
27
+ return value;
28
+ }
29
+
30
+ export function SelectionProvider({
31
+ children,
32
+ selectedIds,
33
+ defaultSelectedIds,
34
+ mode,
35
+ disabled,
36
+ onSelectionChange,
37
+ }: SelectionProviderProps) {
38
+ const resolvedMode = resolveMode(mode);
39
+ const resolvedDisabled = resolveDisabled(disabled);
40
+ const isControlled = selectedIds !== undefined;
41
+
42
+ const [uncontrolledIds, setUncontrolledIds] = React.useState<readonly string[]>(
43
+ defaultSelectedIds ?? [],
44
+ );
45
+
46
+ const rawIds = isControlled ? selectedIds : uncontrolledIds;
47
+ const currentNormalizedIds = normalizeIds(rawIds, resolvedMode);
48
+
49
+ const selectedIdSet = React.useMemo(() => new Set(currentNormalizedIds), [currentNormalizedIds]);
50
+
51
+ const commitSelectionChange = React.useCallback(
52
+ (nextNormalizedIds: readonly string[]) => {
53
+ if (resolvedDisabled) return;
54
+ if (areIdsEqual(nextNormalizedIds, currentNormalizedIds)) return;
55
+
56
+ onSelectionChange?.(nextNormalizedIds);
57
+
58
+ if (!isControlled) {
59
+ setUncontrolledIds(nextNormalizedIds);
60
+ }
61
+ },
62
+ [currentNormalizedIds, isControlled, onSelectionChange, resolvedDisabled],
63
+ );
64
+
65
+ const clear = React.useCallback(() => {
66
+ commitSelectionChange(normalizeIds(clearIds(), resolvedMode));
67
+ }, [commitSelectionChange, resolvedMode]);
68
+
69
+ const select = React.useCallback(
70
+ (id: string) => {
71
+ const nextIds = selectId({ mode: resolvedMode, ids: currentNormalizedIds, id });
72
+ const nextNormalizedIds = normalizeIds(nextIds, resolvedMode);
73
+ commitSelectionChange(nextNormalizedIds);
74
+ },
75
+ [commitSelectionChange, currentNormalizedIds, resolvedMode],
76
+ );
77
+
78
+ const toggle = React.useCallback(
79
+ (id: string) => {
80
+ const nextIds = toggleId({ mode: resolvedMode, ids: currentNormalizedIds, id });
81
+ const nextNormalizedIds = normalizeIds(nextIds, resolvedMode);
82
+ commitSelectionChange(nextNormalizedIds);
83
+ },
84
+ [commitSelectionChange, currentNormalizedIds, resolvedMode],
85
+ );
86
+
87
+ const value = React.useMemo<UseSelectionResult>(() => {
88
+ return {
89
+ mode: resolvedMode,
90
+ disabled: resolvedDisabled,
91
+ selectedIds: currentNormalizedIds,
92
+ selectedCount: currentNormalizedIds.length,
93
+ hasSelection: currentNormalizedIds.length > 0,
94
+ isSelected: (id: string) => selectedIdSet.has(id),
95
+ select,
96
+ toggle,
97
+ clear,
98
+ };
99
+ }, [clear, currentNormalizedIds, resolvedDisabled, resolvedMode, select, selectedIdSet, toggle]);
100
+
101
+ return <SelectionContext.Provider value={value}>{children}</SelectionContext.Provider>;
102
+ }
@@ -0,0 +1,10 @@
1
+ export { SelectableItem } from './SelectableItem';
2
+ export { SelectionProvider, useSelection } from './SelectionProvider';
3
+ export type {
4
+ SelectableItemProps,
5
+ SelectableItemState,
6
+ SelectionMode,
7
+ SelectionProviderProps,
8
+ SelectionTrigger,
9
+ UseSelectionResult,
10
+ } from './types';
@@ -0,0 +1,21 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+
3
+ const SELECTION_NOTE = 'Selection pattern component; not represented as a manifest node in v1.';
4
+
5
+ export const selectableItemMeta = {
6
+ name: 'SelectableItem',
7
+ category: 'pattern',
8
+ directManifestNode: false,
9
+ allowedChildren: [],
10
+ note: SELECTION_NOTE,
11
+ props: {},
12
+ } as const satisfies ZoraComponentMeta;
13
+
14
+ export const selectionProviderMeta = {
15
+ name: 'SelectionProvider',
16
+ category: 'pattern',
17
+ directManifestNode: false,
18
+ allowedChildren: [],
19
+ note: SELECTION_NOTE,
20
+ props: {},
21
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,61 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+
3
+ import { areIdsEqual, clearIds, normalizeIds, selectId, toggleId } from './resolveSelectionNextIds';
4
+ import type { SelectionMode } from './types';
5
+
6
+ describe('resolveSelectionNextIds', () => {
7
+ test('normalizeIds removes duplicates, preserves order', () => {
8
+ expect(normalizeIds(['a', 'b', 'a', 'c'], 'multi')).toEqual(['a', 'b', 'c']);
9
+ });
10
+
11
+ test('normalizeIds keeps only first id in single mode', () => {
12
+ expect(normalizeIds(['a', 'b', 'c'], 'single')).toEqual(['a']);
13
+ });
14
+
15
+ test('normalizeIds treats undefined as empty', () => {
16
+ expect(normalizeIds(undefined, 'multi')).toEqual([]);
17
+ });
18
+
19
+ test('areIdsEqual compares order', () => {
20
+ expect(areIdsEqual(['a'], ['a'])).toBeTrue();
21
+ expect(areIdsEqual(['a'], ['b'])).toBeFalse();
22
+ expect(areIdsEqual(['a', 'b'], ['a', 'b'])).toBeTrue();
23
+ expect(areIdsEqual(['a', 'b'], ['b', 'a'])).toBeFalse();
24
+ });
25
+
26
+ test('clearIds returns empty selection', () => {
27
+ expect(clearIds()).toEqual([]);
28
+ });
29
+
30
+ test('selectId replaces selection in single mode', () => {
31
+ expect(selectId({ mode: 'single', ids: ['a'], id: 'b' })).toEqual(['b']);
32
+ });
33
+
34
+ test('selectId adds id in multi mode when missing', () => {
35
+ expect(selectId({ mode: 'multi', ids: ['a'], id: 'b' })).toEqual(['a', 'b']);
36
+ });
37
+
38
+ test('selectId is no-op in multi mode when already selected', () => {
39
+ const ids = ['a', 'b'];
40
+ expect(selectId({ mode: 'multi', ids, id: 'b' })).toBe(ids);
41
+ });
42
+
43
+ test('toggleId clears id when already selected (single mode)', () => {
44
+ expect(toggleId({ mode: 'single', ids: ['a'], id: 'a' })).toEqual([]);
45
+ });
46
+
47
+ test('toggleId selects id when not selected (single mode)', () => {
48
+ expect(toggleId({ mode: 'single', ids: [], id: 'a' })).toEqual(['a']);
49
+ });
50
+
51
+ test('toggleId toggles membership (multi mode)', () => {
52
+ expect(toggleId({ mode: 'multi', ids: ['a'], id: 'b' })).toEqual(['a', 'b']);
53
+ expect(toggleId({ mode: 'multi', ids: ['a', 'b'], id: 'b' })).toEqual(['a']);
54
+ });
55
+
56
+ test('mode-change normalization example', () => {
57
+ const internalIds = ['a', 'b'];
58
+ const mode: SelectionMode = 'single';
59
+ expect(normalizeIds(internalIds, mode)).toEqual(['a']);
60
+ });
61
+ });
@@ -0,0 +1,71 @@
1
+ import type { SelectionMode } from './types';
2
+
3
+ export function normalizeIds(
4
+ ids: readonly string[] | undefined,
5
+ mode: SelectionMode,
6
+ ): readonly string[] {
7
+ const uniqueIds: string[] = [];
8
+ const seen = new Set<string>();
9
+
10
+ for (const id of ids ?? []) {
11
+ if (seen.has(id)) continue;
12
+ seen.add(id);
13
+ uniqueIds.push(id);
14
+ if (mode === 'single') break;
15
+ }
16
+
17
+ return uniqueIds;
18
+ }
19
+
20
+ export function areIdsEqual(a: readonly string[], b: readonly string[]): boolean {
21
+ if (a.length !== b.length) return false;
22
+ for (let index = 0; index < a.length; index += 1) {
23
+ if (a[index] !== b[index]) return false;
24
+ }
25
+
26
+ return true;
27
+ }
28
+
29
+ export function clearIds(): readonly string[] {
30
+ return [];
31
+ }
32
+
33
+ export function selectId({
34
+ mode,
35
+ ids,
36
+ id,
37
+ }: {
38
+ mode: SelectionMode;
39
+ ids: readonly string[];
40
+ id: string;
41
+ }): readonly string[] {
42
+ if (mode === 'single') {
43
+ return [id];
44
+ }
45
+
46
+ if (ids.includes(id)) {
47
+ return ids;
48
+ }
49
+
50
+ return [...ids, id];
51
+ }
52
+
53
+ export function toggleId({
54
+ mode,
55
+ ids,
56
+ id,
57
+ }: {
58
+ mode: SelectionMode;
59
+ ids: readonly string[];
60
+ id: string;
61
+ }): readonly string[] {
62
+ if (ids.includes(id)) {
63
+ return ids.filter((existingId) => existingId !== id);
64
+ }
65
+
66
+ if (mode === 'single') {
67
+ return [id];
68
+ }
69
+
70
+ return [...ids, id];
71
+ }
@@ -0,0 +1,43 @@
1
+ import type React from 'react';
2
+
3
+ export type SelectionMode = 'single' | 'multi';
4
+
5
+ export type SelectionTrigger = 'press' | 'longPress' | 'manual';
6
+
7
+ export interface SelectionProviderProps {
8
+ children: React.ReactNode;
9
+ selectedIds?: readonly string[];
10
+ defaultSelectedIds?: readonly string[];
11
+ mode?: SelectionMode;
12
+ disabled?: boolean;
13
+ onSelectionChange?: (ids: readonly string[]) => void;
14
+ }
15
+
16
+ export interface UseSelectionResult {
17
+ mode: SelectionMode;
18
+ disabled: boolean;
19
+ selectedIds: readonly string[];
20
+ selectedCount: number;
21
+ hasSelection: boolean;
22
+ isSelected: (id: string) => boolean;
23
+ select: (id: string) => void;
24
+ toggle: (id: string) => void;
25
+ clear: () => void;
26
+ }
27
+
28
+ export interface SelectableItemState {
29
+ id: string;
30
+ selected: boolean;
31
+ disabled: boolean;
32
+ mode: SelectionMode;
33
+ select: () => void;
34
+ toggle: () => void;
35
+ clear: () => void;
36
+ }
37
+
38
+ export interface SelectableItemProps {
39
+ id: string;
40
+ trigger?: SelectionTrigger;
41
+ disabled?: boolean;
42
+ children: React.ReactNode | ((state: SelectableItemState) => React.ReactNode);
43
+ }
@@ -0,0 +1,40 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+
3
+ export const settingsRowMeta = {
4
+ name: 'SettingsRow',
5
+ category: 'pattern',
6
+ directManifestNode: true,
7
+ allowedChildren: [],
8
+ blueprint: {
9
+ label: 'Settings row',
10
+ defaultProps: {
11
+ title: 'Setting',
12
+ description: 'Setting description.',
13
+ },
14
+ },
15
+ props: {
16
+ title: {
17
+ type: 'string',
18
+ category: 'Content',
19
+ label: 'Title',
20
+ default: 'Setting',
21
+ },
22
+ description: {
23
+ type: 'string',
24
+ category: 'Content',
25
+ label: 'Description',
26
+ default: 'Setting description.',
27
+ },
28
+ meta: {
29
+ type: 'string',
30
+ category: 'Content',
31
+ label: 'Meta',
32
+ },
33
+ disabled: {
34
+ type: 'boolean',
35
+ category: 'State',
36
+ label: 'Disabled',
37
+ default: false,
38
+ },
39
+ },
40
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,10 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+
3
+ export const switchFieldMeta = {
4
+ name: 'SwitchField',
5
+ category: 'pattern',
6
+ directManifestNode: false,
7
+ allowedChildren: [],
8
+ note: 'Form pattern; not represented as a manifest node in v1.',
9
+ props: {},
10
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,10 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+
3
+ export const themeComposerMeta = {
4
+ name: 'ThemeComposer',
5
+ category: 'pattern',
6
+ directManifestNode: false,
7
+ allowedChildren: [],
8
+ note: 'Theme tooling pattern; not represented as a manifest node in v1.',
9
+ props: {},
10
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,21 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+
3
+ const TILE_GRID_NOTE = 'Tile grid pattern component; not represented as a manifest node in v1.';
4
+
5
+ export const paletteItemMeta = {
6
+ name: 'PaletteItem',
7
+ category: 'pattern',
8
+ directManifestNode: false,
9
+ allowedChildren: [],
10
+ note: TILE_GRID_NOTE,
11
+ props: {},
12
+ } as const satisfies ZoraComponentMeta;
13
+
14
+ export const tileGridMeta = {
15
+ name: 'TileGrid',
16
+ category: 'pattern',
17
+ directManifestNode: false,
18
+ allowedChildren: [],
19
+ note: TILE_GRID_NOTE,
20
+ props: {},
21
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,10 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+
3
+ export const timelineMeta = {
4
+ name: 'Timeline',
5
+ category: 'pattern',
6
+ directManifestNode: false,
7
+ allowedChildren: [],
8
+ note: 'Timeline pattern component; not represented as a manifest node in v1.',
9
+ props: {},
10
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,21 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+
3
+ const TREE_NOTE = 'Tree view pattern component; not represented as a manifest node in v1.';
4
+
5
+ export const treeItemMeta = {
6
+ name: 'TreeItem',
7
+ category: 'pattern',
8
+ directManifestNode: false,
9
+ allowedChildren: [],
10
+ note: TREE_NOTE,
11
+ props: {},
12
+ } as const satisfies ZoraComponentMeta;
13
+
14
+ export const treeViewMeta = {
15
+ name: 'TreeView',
16
+ category: 'pattern',
17
+ directManifestNode: false,
18
+ allowedChildren: [],
19
+ note: TREE_NOTE,
20
+ props: {},
21
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,10 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+
3
+ export const zoraDrawerContentMeta = {
4
+ name: 'ZoraDrawerContent',
5
+ category: 'pattern',
6
+ directManifestNode: false,
7
+ allowedChildren: [],
8
+ note: 'Navigation chrome pattern; not represented as a manifest node in v1.',
9
+ props: {},
10
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,10 @@
1
+ import type { ZoraComponentMeta } from '../../metadata';
2
+
3
+ export const zoraTabBarMeta = {
4
+ name: 'ZoraTabBar',
5
+ category: 'pattern',
6
+ directManifestNode: false,
7
+ allowedChildren: [],
8
+ note: 'Navigation chrome pattern; not represented as a manifest node in v1.',
9
+ props: {},
10
+ } as const satisfies ZoraComponentMeta;
@@ -86,6 +86,9 @@ const REQUIRED_SHOWCASE_COVERAGE = {
86
86
  'DisclosureSection',
87
87
  'EmptyState',
88
88
  'FilterBar',
89
+ 'SelectableItem',
90
+ 'SelectionProvider',
91
+ 'useSelection',
89
92
  'List',
90
93
  'ListRow',
91
94
  'ListSection',