@delacour/react-native-ui 0.4.0-alpha.20261020083124 → 0.4.0-alpha.20261020143428

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 (798) hide show
  1. package/package.json +66 -2
  2. package/src/components/animated-badge/AGENTS.md +132 -0
  3. package/src/components/animated-badge/animated-badge-content.tsx +58 -0
  4. package/src/components/animated-badge/animated-badge-glyph.tsx +118 -0
  5. package/src/components/animated-badge/animated-badge-measure.tsx +69 -0
  6. package/src/components/animated-badge/animated-badge.tsx +181 -0
  7. package/src/components/animated-badge/animated-badge.types.ts +28 -0
  8. package/src/components/animated-badge/animated-badge.variants.test.ts +290 -0
  9. package/src/components/animated-badge/animated-badge.variants.ts +213 -0
  10. package/src/components/animated-badge/index.ts +17 -0
  11. package/src/components/animated-badge/use-animated-badge-roll.ts +122 -0
  12. package/src/components/attachment/AGENTS.md +156 -0
  13. package/src/components/attachment/attachment-content.tsx +34 -0
  14. package/src/components/attachment/attachment-group.tsx +91 -0
  15. package/src/components/attachment/attachment-meta.tsx +34 -0
  16. package/src/components/attachment/attachment-name.tsx +41 -0
  17. package/src/components/attachment/attachment-preview.tsx +73 -0
  18. package/src/components/attachment/attachment-progress.tsx +60 -0
  19. package/src/components/attachment/attachment-remove.tsx +55 -0
  20. package/src/components/attachment/attachment-retry.tsx +54 -0
  21. package/src/components/attachment/attachment.context.tsx +121 -0
  22. package/src/components/attachment/attachment.tsx +468 -0
  23. package/src/components/attachment/attachment.types.ts +31 -0
  24. package/src/components/attachment/attachment.utils.test.ts +358 -0
  25. package/src/components/attachment/attachment.utils.ts +393 -0
  26. package/src/components/attachment/attachment.variants.test.ts +306 -0
  27. package/src/components/attachment/attachment.variants.ts +251 -0
  28. package/src/components/attachment/index.ts +59 -0
  29. package/src/components/avatar/AGENTS.md +5 -2
  30. package/src/components/avatar/avatar.variants.test.ts +7 -1
  31. package/src/components/avatar/avatar.variants.ts +10 -1
  32. package/src/components/breadcrumb/AGENTS.md +112 -0
  33. package/src/components/breadcrumb/breadcrumb-ellipsis.tsx +72 -0
  34. package/src/components/breadcrumb/breadcrumb-glyph.tsx +17 -0
  35. package/src/components/breadcrumb/breadcrumb-item.tsx +21 -0
  36. package/src/components/breadcrumb/breadcrumb-link.tsx +63 -0
  37. package/src/components/breadcrumb/breadcrumb-list.tsx +135 -0
  38. package/src/components/breadcrumb/breadcrumb-page.tsx +35 -0
  39. package/src/components/breadcrumb/breadcrumb-separator.tsx +63 -0
  40. package/src/components/breadcrumb/breadcrumb.context.tsx +61 -0
  41. package/src/components/breadcrumb/breadcrumb.tsx +94 -0
  42. package/src/components/breadcrumb/breadcrumb.types.ts +11 -0
  43. package/src/components/breadcrumb/breadcrumb.variants.test.ts +292 -0
  44. package/src/components/breadcrumb/breadcrumb.variants.ts +246 -0
  45. package/src/components/breadcrumb/index.ts +34 -0
  46. package/src/components/circular-text/AGENTS.md +160 -0
  47. package/src/components/circular-text/circular-text-ring.tsx +72 -0
  48. package/src/components/circular-text/circular-text-spin.ts +69 -0
  49. package/src/components/circular-text/circular-text.tsx +249 -0
  50. package/src/components/circular-text/circular-text.types.ts +53 -0
  51. package/src/components/circular-text/circular-text.variants.test.ts +347 -0
  52. package/src/components/circular-text/circular-text.variants.ts +271 -0
  53. package/src/components/circular-text/index.ts +19 -0
  54. package/src/components/color-picker/AGENTS.md +128 -0
  55. package/src/components/color-picker/color-picker-alpha.tsx +23 -0
  56. package/src/components/color-picker/color-picker-area.tsx +201 -0
  57. package/src/components/color-picker/color-picker-checkerboard.tsx +64 -0
  58. package/src/components/color-picker/color-picker-content.tsx +33 -0
  59. package/src/components/color-picker/color-picker-gradient.tsx +78 -0
  60. package/src/components/color-picker/color-picker-hue.tsx +16 -0
  61. package/src/components/color-picker/color-picker-input.tsx +140 -0
  62. package/src/components/color-picker/color-picker-preview.tsx +42 -0
  63. package/src/components/color-picker/color-picker-sheet.tsx +58 -0
  64. package/src/components/color-picker/color-picker-swatch.tsx +75 -0
  65. package/src/components/color-picker/color-picker-swatches.tsx +32 -0
  66. package/src/components/color-picker/color-picker-thumb.tsx +104 -0
  67. package/src/components/color-picker/color-picker-track.tsx +217 -0
  68. package/src/components/color-picker/color-picker-trigger.tsx +53 -0
  69. package/src/components/color-picker/color-picker.color.test.ts +366 -0
  70. package/src/components/color-picker/color-picker.color.ts +399 -0
  71. package/src/components/color-picker/color-picker.context.tsx +105 -0
  72. package/src/components/color-picker/color-picker.tsx +330 -0
  73. package/src/components/color-picker/color-picker.types.ts +22 -0
  74. package/src/components/color-picker/color-picker.variants.test.ts +253 -0
  75. package/src/components/color-picker/color-picker.variants.ts +256 -0
  76. package/src/components/color-picker/index.ts +49 -0
  77. package/src/components/combobox/AGENTS.md +139 -0
  78. package/src/components/combobox/combobox-chip-row.tsx +101 -0
  79. package/src/components/combobox/combobox-create-row.tsx +62 -0
  80. package/src/components/combobox/combobox-empty.tsx +36 -0
  81. package/src/components/combobox/combobox-group.tsx +19 -0
  82. package/src/components/combobox/combobox-item.tsx +28 -0
  83. package/src/components/combobox/combobox-trigger.tsx +213 -0
  84. package/src/components/combobox/combobox.collect.test.ts +65 -0
  85. package/src/components/combobox/combobox.collect.ts +66 -0
  86. package/src/components/combobox/combobox.context.tsx +106 -0
  87. package/src/components/combobox/combobox.filter.test.ts +312 -0
  88. package/src/components/combobox/combobox.filter.ts +291 -0
  89. package/src/components/combobox/combobox.tsx +643 -0
  90. package/src/components/combobox/combobox.types.ts +54 -0
  91. package/src/components/combobox/combobox.variants.test.ts +240 -0
  92. package/src/components/combobox/combobox.variants.ts +198 -0
  93. package/src/components/combobox/index.ts +48 -0
  94. package/src/components/compare/AGENTS.md +150 -0
  95. package/src/components/compare/compare-after.tsx +29 -0
  96. package/src/components/compare/compare-before.tsx +60 -0
  97. package/src/components/compare/compare-handle.tsx +138 -0
  98. package/src/components/compare/compare-label.tsx +58 -0
  99. package/src/components/compare/compare.context.tsx +97 -0
  100. package/src/components/compare/compare.tsx +464 -0
  101. package/src/components/compare/compare.types.ts +9 -0
  102. package/src/components/compare/compare.variants.test.ts +548 -0
  103. package/src/components/compare/compare.variants.ts +459 -0
  104. package/src/components/compare/index.ts +40 -0
  105. package/src/components/countdown/AGENTS.md +123 -0
  106. package/src/components/countdown/countdown-digit.tsx +51 -0
  107. package/src/components/countdown/countdown-segment.tsx +62 -0
  108. package/src/components/countdown/countdown.tsx +141 -0
  109. package/src/components/countdown/countdown.variants.test.ts +283 -0
  110. package/src/components/countdown/countdown.variants.ts +251 -0
  111. package/src/components/countdown/index.ts +28 -0
  112. package/src/components/countdown/use-countdown-clock.ts +80 -0
  113. package/src/components/date-picker/AGENTS.md +110 -0
  114. package/src/components/date-picker/date-picker-calendar.tsx +79 -0
  115. package/src/components/date-picker/date-picker-clear.tsx +33 -0
  116. package/src/components/date-picker/date-picker-content.tsx +67 -0
  117. package/src/components/date-picker/date-picker-done.tsx +31 -0
  118. package/src/components/date-picker/date-picker-icon.tsx +27 -0
  119. package/src/components/date-picker/date-picker-trigger.tsx +63 -0
  120. package/src/components/date-picker/date-picker-value.tsx +26 -0
  121. package/src/components/date-picker/date-picker.context.tsx +105 -0
  122. package/src/components/date-picker/date-picker.tsx +370 -0
  123. package/src/components/date-picker/date-picker.types.ts +99 -0
  124. package/src/components/date-picker/date-picker.variants.test.ts +326 -0
  125. package/src/components/date-picker/date-picker.variants.ts +304 -0
  126. package/src/components/date-picker/index.ts +46 -0
  127. package/src/components/date-time-picker/AGENTS.md +158 -0
  128. package/src/components/date-time-picker/date-time-picker-calendar.tsx +67 -0
  129. package/src/components/date-time-picker/date-time-picker-clear.tsx +33 -0
  130. package/src/components/date-time-picker/date-time-picker-content.tsx +155 -0
  131. package/src/components/date-time-picker/date-time-picker-done.tsx +34 -0
  132. package/src/components/date-time-picker/date-time-picker-icon.tsx +27 -0
  133. package/src/components/date-time-picker/date-time-picker-time.tsx +144 -0
  134. package/src/components/date-time-picker/date-time-picker-trigger.tsx +63 -0
  135. package/src/components/date-time-picker/date-time-picker-value.tsx +22 -0
  136. package/src/components/date-time-picker/date-time-picker.context.tsx +123 -0
  137. package/src/components/date-time-picker/date-time-picker.tsx +379 -0
  138. package/src/components/date-time-picker/date-time-picker.types.ts +94 -0
  139. package/src/components/date-time-picker/date-time-picker.value.test.ts +369 -0
  140. package/src/components/date-time-picker/date-time-picker.value.ts +321 -0
  141. package/src/components/date-time-picker/date-time-picker.variants.test.ts +187 -0
  142. package/src/components/date-time-picker/date-time-picker.variants.ts +145 -0
  143. package/src/components/date-time-picker/index.ts +61 -0
  144. package/src/components/direction/AGENTS.md +89 -0
  145. package/src/components/direction/direction.context.tsx +74 -0
  146. package/src/components/direction/direction.tsx +84 -0
  147. package/src/components/direction/direction.variants.test.ts +90 -0
  148. package/src/components/direction/direction.variants.ts +69 -0
  149. package/src/components/direction/index.ts +20 -0
  150. package/src/components/drawer/AGENTS.md +6 -7
  151. package/src/components/feedback/AGENTS.md +3 -5
  152. package/src/components/flip-card/AGENTS.md +149 -0
  153. package/src/components/flip-card/flip-card-back.tsx +22 -0
  154. package/src/components/flip-card/flip-card-face.tsx +78 -0
  155. package/src/components/flip-card/flip-card-front.tsx +14 -0
  156. package/src/components/flip-card/flip-card-trigger.tsx +58 -0
  157. package/src/components/flip-card/flip-card.context.tsx +81 -0
  158. package/src/components/flip-card/flip-card.tsx +453 -0
  159. package/src/components/flip-card/flip-card.types.ts +13 -0
  160. package/src/components/flip-card/flip-card.variants.test.ts +436 -0
  161. package/src/components/flip-card/flip-card.variants.ts +346 -0
  162. package/src/components/flip-card/index.ts +28 -0
  163. package/src/components/flow/AGENTS.md +127 -0
  164. package/src/components/flow/flow-background.tsx +85 -0
  165. package/src/components/flow/flow-connection-preview.tsx +55 -0
  166. package/src/components/flow/flow-controls.tsx +91 -0
  167. package/src/components/flow/flow-edge.tsx +174 -0
  168. package/src/components/flow/flow-geometry.test.ts +513 -0
  169. package/src/components/flow/flow-geometry.ts +504 -0
  170. package/src/components/flow/flow-group.tsx +168 -0
  171. package/src/components/flow/flow-handle.tsx +140 -0
  172. package/src/components/flow/flow-minimap.tsx +119 -0
  173. package/src/components/flow/flow-node.tsx +258 -0
  174. package/src/components/flow/flow-registry.ts +115 -0
  175. package/src/components/flow/flow-svg.ts +15 -0
  176. package/src/components/flow/flow.context.tsx +140 -0
  177. package/src/components/flow/flow.tsx +433 -0
  178. package/src/components/flow/flow.variants.test.ts +373 -0
  179. package/src/components/flow/flow.variants.ts +317 -0
  180. package/src/components/flow/index.ts +63 -0
  181. package/src/components/frame/AGENTS.md +103 -0
  182. package/src/components/frame/frame-action.tsx +46 -0
  183. package/src/components/frame/frame-description.tsx +12 -0
  184. package/src/components/frame/frame-dividers.tsx +41 -0
  185. package/src/components/frame/frame-footer.tsx +41 -0
  186. package/src/components/frame/frame-header.tsx +45 -0
  187. package/src/components/frame/frame-section.tsx +51 -0
  188. package/src/components/frame/frame-title.tsx +25 -0
  189. package/src/components/frame/frame-tray.tsx +59 -0
  190. package/src/components/frame/frame.context.tsx +81 -0
  191. package/src/components/frame/frame.tsx +104 -0
  192. package/src/components/frame/frame.types.ts +9 -0
  193. package/src/components/frame/frame.variants.test.ts +244 -0
  194. package/src/components/frame/frame.variants.ts +215 -0
  195. package/src/components/frame/index.ts +25 -0
  196. package/src/components/grid-item/AGENTS.md +139 -0
  197. package/src/components/grid-item/grid-item-actions.tsx +35 -0
  198. package/src/components/grid-item/grid-item-background.tsx +26 -0
  199. package/src/components/grid-item/grid-item-description.tsx +21 -0
  200. package/src/components/grid-item/grid-item-footer.tsx +14 -0
  201. package/src/components/grid-item/grid-item-group.tsx +188 -0
  202. package/src/components/grid-item/grid-item-media.tsx +30 -0
  203. package/src/components/grid-item/grid-item-title.tsx +23 -0
  204. package/src/components/grid-item/grid-item-value.tsx +24 -0
  205. package/src/components/grid-item/grid-item.context.tsx +155 -0
  206. package/src/components/grid-item/grid-item.layout.test.ts +289 -0
  207. package/src/components/grid-item/grid-item.layout.ts +190 -0
  208. package/src/components/grid-item/grid-item.tsx +208 -0
  209. package/src/components/grid-item/grid-item.types.ts +8 -0
  210. package/src/components/grid-item/grid-item.variants.test.ts +240 -0
  211. package/src/components/grid-item/grid-item.variants.ts +166 -0
  212. package/src/components/grid-item/index.ts +47 -0
  213. package/src/components/image-viewer/AGENTS.md +181 -0
  214. package/src/components/image-viewer/image-viewer-chrome.tsx +78 -0
  215. package/src/components/image-viewer/image-viewer-close.tsx +36 -0
  216. package/src/components/image-viewer/image-viewer-image.tsx +37 -0
  217. package/src/components/image-viewer/image-viewer-layer.tsx +629 -0
  218. package/src/components/image-viewer/image-viewer-page.tsx +190 -0
  219. package/src/components/image-viewer/image-viewer-trigger.tsx +188 -0
  220. package/src/components/image-viewer/image-viewer.context.tsx +114 -0
  221. package/src/components/image-viewer/image-viewer.tsx +306 -0
  222. package/src/components/image-viewer/image-viewer.types.ts +34 -0
  223. package/src/components/image-viewer/image-viewer.variants.test.ts +449 -0
  224. package/src/components/image-viewer/image-viewer.variants.ts +372 -0
  225. package/src/components/image-viewer/index.ts +54 -0
  226. package/src/components/input/AGENTS.md +51 -7
  227. package/src/components/input/index.ts +15 -1
  228. package/src/components/input/input-group-block.tsx +71 -0
  229. package/src/components/input/input-group-button.tsx +71 -0
  230. package/src/components/input/input-group-decorator.tsx +43 -8
  231. package/src/components/input/input-group-prefix.tsx +2 -2
  232. package/src/components/input/input-group-separator.tsx +37 -0
  233. package/src/components/input/input-group-suffix.tsx +2 -2
  234. package/src/components/input/input-group.tsx +96 -16
  235. package/src/components/input/input.context.tsx +32 -1
  236. package/src/components/input/input.tsx +12 -1
  237. package/src/components/input/input.types.ts +13 -0
  238. package/src/components/input/input.variants.test.ts +247 -3
  239. package/src/components/input/input.variants.ts +163 -8
  240. package/src/components/leaderboard/AGENTS.md +100 -0
  241. package/src/components/leaderboard/index.ts +35 -0
  242. package/src/components/leaderboard/leaderboard-empty.tsx +23 -0
  243. package/src/components/leaderboard/leaderboard-movement.tsx +46 -0
  244. package/src/components/leaderboard/leaderboard-podium-place.tsx +162 -0
  245. package/src/components/leaderboard/leaderboard-podium.tsx +72 -0
  246. package/src/components/leaderboard/leaderboard-row.tsx +78 -0
  247. package/src/components/leaderboard/leaderboard.context.tsx +46 -0
  248. package/src/components/leaderboard/leaderboard.tsx +161 -0
  249. package/src/components/leaderboard/leaderboard.types.ts +21 -0
  250. package/src/components/leaderboard/leaderboard.variants.test.ts +509 -0
  251. package/src/components/leaderboard/leaderboard.variants.ts +341 -0
  252. package/src/components/markdown-editor/AGENTS.md +144 -0
  253. package/src/components/markdown-editor/index.ts +58 -0
  254. package/src/components/markdown-editor/markdown-editor-action.tsx +74 -0
  255. package/src/components/markdown-editor/markdown-editor-input.tsx +82 -0
  256. package/src/components/markdown-editor/markdown-editor-preview.tsx +63 -0
  257. package/src/components/markdown-editor/markdown-editor-render.tsx +164 -0
  258. package/src/components/markdown-editor/markdown-editor-toolbar.tsx +106 -0
  259. package/src/components/markdown-editor/markdown-editor.commands.test.ts +464 -0
  260. package/src/components/markdown-editor/markdown-editor.commands.ts +729 -0
  261. package/src/components/markdown-editor/markdown-editor.context.tsx +103 -0
  262. package/src/components/markdown-editor/markdown-editor.parse.test.ts +257 -0
  263. package/src/components/markdown-editor/markdown-editor.parse.ts +434 -0
  264. package/src/components/markdown-editor/markdown-editor.tsx +330 -0
  265. package/src/components/markdown-editor/markdown-editor.types.ts +62 -0
  266. package/src/components/markdown-editor/markdown-editor.variants.test.ts +204 -0
  267. package/src/components/markdown-editor/markdown-editor.variants.ts +240 -0
  268. package/src/components/marker/AGENTS.md +119 -0
  269. package/src/components/marker/index.ts +16 -0
  270. package/src/components/marker/marker-content.tsx +46 -0
  271. package/src/components/marker/marker-icon.tsx +27 -0
  272. package/src/components/marker/marker-shimmer-clock.ts +60 -0
  273. package/src/components/marker/marker.context.tsx +82 -0
  274. package/src/components/marker/marker.tsx +192 -0
  275. package/src/components/marker/marker.variants.test.ts +187 -0
  276. package/src/components/marker/marker.variants.ts +121 -0
  277. package/src/components/marquee/AGENTS.md +147 -0
  278. package/src/components/marquee/index.ts +21 -0
  279. package/src/components/marquee/marquee-fade.tsx +62 -0
  280. package/src/components/marquee/marquee-group.tsx +38 -0
  281. package/src/components/marquee/marquee-scroller.tsx +29 -0
  282. package/src/components/marquee/marquee-track.tsx +167 -0
  283. package/src/components/marquee/marquee.context.tsx +42 -0
  284. package/src/components/marquee/marquee.tsx +142 -0
  285. package/src/components/marquee/marquee.types.ts +12 -0
  286. package/src/components/marquee/marquee.variants.test.ts +289 -0
  287. package/src/components/marquee/marquee.variants.ts +230 -0
  288. package/src/components/message/AGENTS.md +139 -0
  289. package/src/components/message/index.ts +46 -0
  290. package/src/components/message/message-actions.tsx +12 -0
  291. package/src/components/message/message-attachments.tsx +16 -0
  292. package/src/components/message/message-author.tsx +25 -0
  293. package/src/components/message/message-avatar.tsx +26 -0
  294. package/src/components/message/message-bubble.tsx +67 -0
  295. package/src/components/message/message-header.tsx +12 -0
  296. package/src/components/message/message-reactions.tsx +43 -0
  297. package/src/components/message/message-status.tsx +65 -0
  298. package/src/components/message/message-text.tsx +29 -0
  299. package/src/components/message/message-timestamp.tsx +23 -0
  300. package/src/components/message/message-typing.tsx +85 -0
  301. package/src/components/message/message.context.tsx +93 -0
  302. package/src/components/message/message.tsx +301 -0
  303. package/src/components/message/message.types.ts +24 -0
  304. package/src/components/message/message.utils.test.ts +307 -0
  305. package/src/components/message/message.utils.ts +329 -0
  306. package/src/components/message/message.variants.test.ts +329 -0
  307. package/src/components/message/message.variants.ts +240 -0
  308. package/src/components/message-scroller/AGENTS.md +132 -0
  309. package/src/components/message-scroller/index.ts +33 -0
  310. package/src/components/message-scroller/message-scroller-date-separator.tsx +40 -0
  311. package/src/components/message-scroller/message-scroller-jump-button.tsx +100 -0
  312. package/src/components/message-scroller/message-scroller-list.tsx +111 -0
  313. package/src/components/message-scroller/message-scroller-loading-older.tsx +38 -0
  314. package/src/components/message-scroller/message-scroller-unread-divider.tsx +43 -0
  315. package/src/components/message-scroller/message-scroller.context.tsx +130 -0
  316. package/src/components/message-scroller/message-scroller.tsx +249 -0
  317. package/src/components/message-scroller/message-scroller.types.ts +121 -0
  318. package/src/components/message-scroller/message-scroller.utils.test.ts +430 -0
  319. package/src/components/message-scroller/message-scroller.utils.ts +350 -0
  320. package/src/components/message-scroller/message-scroller.variants.test.ts +197 -0
  321. package/src/components/message-scroller/message-scroller.variants.ts +98 -0
  322. package/src/components/message-scroller/use-message-scroller-state.ts +241 -0
  323. package/src/components/number-input/AGENTS.md +156 -0
  324. package/src/components/number-input/index.ts +57 -0
  325. package/src/components/number-input/number-input-decrement.tsx +24 -0
  326. package/src/components/number-input/number-input-field.tsx +119 -0
  327. package/src/components/number-input/number-input-increment.tsx +24 -0
  328. package/src/components/number-input/number-input-stepper.tsx +147 -0
  329. package/src/components/number-input/number-input.context.tsx +114 -0
  330. package/src/components/number-input/number-input.format.test.ts +516 -0
  331. package/src/components/number-input/number-input.format.ts +512 -0
  332. package/src/components/number-input/number-input.tsx +376 -0
  333. package/src/components/number-input/number-input.types.ts +31 -0
  334. package/src/components/number-input/number-input.variants.test.ts +100 -0
  335. package/src/components/number-input/number-input.variants.ts +103 -0
  336. package/src/components/number-input/use-step-repeat.ts +55 -0
  337. package/src/components/otp-input/AGENTS.md +122 -0
  338. package/src/components/otp-input/index.ts +48 -0
  339. package/src/components/otp-input/otp-input-group.tsx +16 -0
  340. package/src/components/otp-input/otp-input-separator.tsx +16 -0
  341. package/src/components/otp-input/otp-input-slot.tsx +117 -0
  342. package/src/components/otp-input/otp-input.context.tsx +73 -0
  343. package/src/components/otp-input/otp-input.logic.test.ts +357 -0
  344. package/src/components/otp-input/otp-input.logic.ts +224 -0
  345. package/src/components/otp-input/otp-input.tsx +335 -0
  346. package/src/components/otp-input/otp-input.variants.test.ts +213 -0
  347. package/src/components/otp-input/otp-input.variants.ts +153 -0
  348. package/src/components/page-header/AGENTS.md +160 -0
  349. package/src/components/page-header/index.ts +41 -0
  350. package/src/components/page-header/page-header-actions.tsx +23 -0
  351. package/src/components/page-header/page-header-avatar.tsx +93 -0
  352. package/src/components/page-header/page-header-content.tsx +24 -0
  353. package/src/components/page-header/page-header-cover.tsx +177 -0
  354. package/src/components/page-header/page-header-description.tsx +33 -0
  355. package/src/components/page-header/page-header-meta.tsx +32 -0
  356. package/src/components/page-header/page-header-stat.tsx +68 -0
  357. package/src/components/page-header/page-header-stats.tsx +71 -0
  358. package/src/components/page-header/page-header-title.tsx +30 -0
  359. package/src/components/page-header/page-header.context.tsx +115 -0
  360. package/src/components/page-header/page-header.tsx +155 -0
  361. package/src/components/page-header/page-header.types.ts +8 -0
  362. package/src/components/page-header/page-header.utils.test.ts +131 -0
  363. package/src/components/page-header/page-header.utils.ts +118 -0
  364. package/src/components/page-header/page-header.variants.test.ts +287 -0
  365. package/src/components/page-header/page-header.variants.ts +290 -0
  366. package/src/components/pagination/AGENTS.md +127 -0
  367. package/src/components/pagination/index.ts +51 -0
  368. package/src/components/pagination/pagination-compact.tsx +56 -0
  369. package/src/components/pagination/pagination-control.tsx +92 -0
  370. package/src/components/pagination/pagination-ellipsis.tsx +60 -0
  371. package/src/components/pagination/pagination-item.tsx +79 -0
  372. package/src/components/pagination/pagination-next.tsx +10 -0
  373. package/src/components/pagination/pagination-previous.tsx +10 -0
  374. package/src/components/pagination/pagination-status.tsx +36 -0
  375. package/src/components/pagination/pagination-summary.tsx +16 -0
  376. package/src/components/pagination/pagination.context.tsx +78 -0
  377. package/src/components/pagination/pagination.tsx +238 -0
  378. package/src/components/pagination/pagination.types.ts +10 -0
  379. package/src/components/pagination/pagination.variants.test.ts +474 -0
  380. package/src/components/pagination/pagination.variants.ts +343 -0
  381. package/src/components/planner/AGENTS.md +180 -0
  382. package/src/components/planner/index.ts +72 -0
  383. package/src/components/planner/planner-action.tsx +16 -0
  384. package/src/components/planner/planner-dates.test.ts +287 -0
  385. package/src/components/planner/planner-dates.ts +206 -0
  386. package/src/components/planner/planner-day.tsx +271 -0
  387. package/src/components/planner/planner-details.tsx +75 -0
  388. package/src/components/planner/planner-footer.tsx +12 -0
  389. package/src/components/planner/planner-grid.tsx +139 -0
  390. package/src/components/planner/planner-header.tsx +17 -0
  391. package/src/components/planner/planner-legend.tsx +56 -0
  392. package/src/components/planner/planner-nav.tsx +55 -0
  393. package/src/components/planner/planner-scroller.tsx +116 -0
  394. package/src/components/planner/planner-summary.tsx +25 -0
  395. package/src/components/planner/planner-title.tsx +29 -0
  396. package/src/components/planner/planner-today.tsx +32 -0
  397. package/src/components/planner/planner-weekdays.tsx +34 -0
  398. package/src/components/planner/planner.context.tsx +108 -0
  399. package/src/components/planner/planner.tsx +289 -0
  400. package/src/components/planner/planner.types.ts +50 -0
  401. package/src/components/planner/planner.variants.test.ts +354 -0
  402. package/src/components/planner/planner.variants.ts +324 -0
  403. package/src/components/planner/use-planner-today.ts +51 -0
  404. package/src/components/post/AGENTS.md +130 -0
  405. package/src/components/post/index.ts +46 -0
  406. package/src/components/post/post-action.tsx +31 -0
  407. package/src/components/post/post-author.tsx +114 -0
  408. package/src/components/post/post-body.tsx +123 -0
  409. package/src/components/post/post-community.tsx +80 -0
  410. package/src/components/post/post-footer.tsx +16 -0
  411. package/src/components/post/post-header.tsx +18 -0
  412. package/src/components/post/post-media.tsx +170 -0
  413. package/src/components/post/post-stat-count.tsx +77 -0
  414. package/src/components/post/post-stat.tsx +126 -0
  415. package/src/components/post/post-title.tsx +20 -0
  416. package/src/components/post/post-votes.tsx +92 -0
  417. package/src/components/post/post.context.tsx +59 -0
  418. package/src/components/post/post.tsx +132 -0
  419. package/src/components/post/post.types.ts +8 -0
  420. package/src/components/post/post.utils.test.ts +277 -0
  421. package/src/components/post/post.utils.ts +268 -0
  422. package/src/components/post/post.variants.test.ts +328 -0
  423. package/src/components/post/post.variants.ts +325 -0
  424. package/src/components/pressable/AGENTS.md +7 -1
  425. package/src/components/pressable/pressable.tsx +9 -3
  426. package/src/components/pressable/pressable.variants.test.ts +44 -0
  427. package/src/components/pressable/pressable.variants.ts +33 -0
  428. package/src/components/qr-code/AGENTS.md +142 -0
  429. package/src/components/qr-code/index.ts +39 -0
  430. package/src/components/qr-code/qr-code-logo.tsx +40 -0
  431. package/src/components/qr-code/qr-code.constants.ts +58 -0
  432. package/src/components/qr-code/qr-code.context.tsx +37 -0
  433. package/src/components/qr-code/qr-code.encode.test.ts +237 -0
  434. package/src/components/qr-code/qr-code.encode.ts +290 -0
  435. package/src/components/qr-code/qr-code.fixtures.ts +450 -0
  436. package/src/components/qr-code/qr-code.format.test.ts +77 -0
  437. package/src/components/qr-code/qr-code.format.ts +68 -0
  438. package/src/components/qr-code/qr-code.gf.test.ts +96 -0
  439. package/src/components/qr-code/qr-code.gf.ts +77 -0
  440. package/src/components/qr-code/qr-code.logo.test.ts +109 -0
  441. package/src/components/qr-code/qr-code.logo.ts +175 -0
  442. package/src/components/qr-code/qr-code.mask.test.ts +157 -0
  443. package/src/components/qr-code/qr-code.mask.ts +135 -0
  444. package/src/components/qr-code/qr-code.matrix.test.ts +129 -0
  445. package/src/components/qr-code/qr-code.matrix.ts +151 -0
  446. package/src/components/qr-code/qr-code.path.test.ts +149 -0
  447. package/src/components/qr-code/qr-code.path.ts +209 -0
  448. package/src/components/qr-code/qr-code.tables.test.ts +142 -0
  449. package/src/components/qr-code/qr-code.tables.ts +148 -0
  450. package/src/components/qr-code/qr-code.test-helpers.ts +304 -0
  451. package/src/components/qr-code/qr-code.tsx +165 -0
  452. package/src/components/qr-code/qr-code.types.ts +44 -0
  453. package/src/components/qr-code/qr-code.variants.test.ts +161 -0
  454. package/src/components/qr-code/qr-code.variants.ts +155 -0
  455. package/src/components/qr-code/qr-code.warn.ts +8 -0
  456. package/src/components/qr-code/use-qr-code.ts +15 -0
  457. package/src/components/questionnaire/AGENTS.md +124 -0
  458. package/src/components/questionnaire/index.ts +75 -0
  459. package/src/components/questionnaire/questionnaire-back.tsx +41 -0
  460. package/src/components/questionnaire/questionnaire-control.tsx +324 -0
  461. package/src/components/questionnaire/questionnaire-footer.tsx +50 -0
  462. package/src/components/questionnaire/questionnaire-next.tsx +57 -0
  463. package/src/components/questionnaire/questionnaire-progress.tsx +91 -0
  464. package/src/components/questionnaire/questionnaire-question.tsx +143 -0
  465. package/src/components/questionnaire/questionnaire-skip.tsx +42 -0
  466. package/src/components/questionnaire/questionnaire-spacer.tsx +13 -0
  467. package/src/components/questionnaire/questionnaire-submit.tsx +57 -0
  468. package/src/components/questionnaire/questionnaire-title.tsx +21 -0
  469. package/src/components/questionnaire/questionnaire.context.tsx +117 -0
  470. package/src/components/questionnaire/questionnaire.logic.test.ts +836 -0
  471. package/src/components/questionnaire/questionnaire.logic.ts +760 -0
  472. package/src/components/questionnaire/questionnaire.tsx +370 -0
  473. package/src/components/questionnaire/questionnaire.types.ts +182 -0
  474. package/src/components/questionnaire/questionnaire.variants.test.ts +252 -0
  475. package/src/components/questionnaire/questionnaire.variants.ts +230 -0
  476. package/src/components/scroll-blur/AGENTS.md +112 -0
  477. package/src/components/scroll-blur/index.ts +20 -0
  478. package/src/components/scroll-blur/scroll-blur-band.tsx +108 -0
  479. package/src/components/scroll-blur/scroll-blur.context.tsx +31 -0
  480. package/src/components/scroll-blur/scroll-blur.tsx +106 -0
  481. package/src/components/scroll-blur/scroll-blur.types.ts +61 -0
  482. package/src/components/scroll-blur/scroll-blur.variants.test.ts +82 -0
  483. package/src/components/scroll-blur/scroll-blur.variants.ts +96 -0
  484. package/src/components/scroll-canvas/AGENTS.md +131 -0
  485. package/src/components/scroll-canvas/index.ts +24 -0
  486. package/src/components/scroll-canvas/scroll-canvas-image.tsx +81 -0
  487. package/src/components/scroll-canvas/scroll-canvas-sequence.tsx +95 -0
  488. package/src/components/scroll-canvas/scroll-canvas.tsx +111 -0
  489. package/src/components/scroll-canvas/scroll-canvas.types.ts +60 -0
  490. package/src/components/scroll-canvas/scroll-canvas.variants.test.ts +232 -0
  491. package/src/components/scroll-canvas/scroll-canvas.variants.ts +200 -0
  492. package/src/components/scroll-canvas/use-frame-progress.ts +131 -0
  493. package/src/components/scroll-fade/AGENTS.md +139 -0
  494. package/src/components/scroll-fade/index.ts +8 -0
  495. package/src/components/scroll-fade/scroll-fade-edge.tsx +73 -0
  496. package/src/components/scroll-fade/scroll-fade.tsx +127 -0
  497. package/src/components/scroll-fade/scroll-fade.variants.test.ts +50 -0
  498. package/src/components/scroll-fade/scroll-fade.variants.ts +41 -0
  499. package/src/components/scroll-header/AGENTS.md +169 -0
  500. package/src/components/scroll-header/index.ts +32 -0
  501. package/src/components/scroll-header/scroll-header-bar-surface.tsx +75 -0
  502. package/src/components/scroll-header/scroll-header-bar-title.tsx +49 -0
  503. package/src/components/scroll-header/scroll-header-bar.tsx +83 -0
  504. package/src/components/scroll-header/scroll-header-cover.tsx +73 -0
  505. package/src/components/scroll-header/scroll-header-flat-list.tsx +97 -0
  506. package/src/components/scroll-header/scroll-header-inset.tsx +20 -0
  507. package/src/components/scroll-header/scroll-header-large.tsx +67 -0
  508. package/src/components/scroll-header/scroll-header-root.tsx +201 -0
  509. package/src/components/scroll-header/scroll-header-scroll-view.tsx +56 -0
  510. package/src/components/scroll-header/scroll-header.context.tsx +27 -0
  511. package/src/components/scroll-header/scroll-header.tsx +70 -0
  512. package/src/components/scroll-header/scroll-header.types.ts +66 -0
  513. package/src/components/scroll-header/scroll-header.variants.test.ts +173 -0
  514. package/src/components/scroll-header/scroll-header.variants.ts +173 -0
  515. package/src/components/scroll-header/use-scroll-header-scroll-props.ts +57 -0
  516. package/src/components/scroll-text/AGENTS.md +116 -0
  517. package/src/components/scroll-text/index.ts +34 -0
  518. package/src/components/scroll-text/scroll-text-source.ts +105 -0
  519. package/src/components/scroll-text/scroll-text-unit.tsx +86 -0
  520. package/src/components/scroll-text/scroll-text.tsx +277 -0
  521. package/src/components/scroll-text/scroll-text.types.ts +36 -0
  522. package/src/components/scroll-text/scroll-text.variants.test.ts +525 -0
  523. package/src/components/scroll-text/scroll-text.variants.ts +451 -0
  524. package/src/components/search-bar/AGENTS.md +109 -0
  525. package/src/components/search-bar/index.ts +29 -0
  526. package/src/components/search-bar/search-bar-cancel-reveal.tsx +90 -0
  527. package/src/components/search-bar/search-bar-cancel.tsx +48 -0
  528. package/src/components/search-bar/search-bar-clear.tsx +46 -0
  529. package/src/components/search-bar/search-bar-tokens.tsx +58 -0
  530. package/src/components/search-bar/search-bar.context.tsx +80 -0
  531. package/src/components/search-bar/search-bar.debounce.test.ts +134 -0
  532. package/src/components/search-bar/search-bar.debounce.ts +76 -0
  533. package/src/components/search-bar/search-bar.responder.ts +14 -0
  534. package/src/components/search-bar/search-bar.tsx +403 -0
  535. package/src/components/search-bar/search-bar.types.ts +23 -0
  536. package/src/components/search-bar/search-bar.variants.test.ts +198 -0
  537. package/src/components/search-bar/search-bar.variants.ts +173 -0
  538. package/src/components/section-progress/AGENTS.md +134 -0
  539. package/src/components/section-progress/index.ts +37 -0
  540. package/src/components/section-progress/section-progress-item.tsx +70 -0
  541. package/src/components/section-progress/section-progress-panel.tsx +77 -0
  542. package/src/components/section-progress/section-progress-pill.tsx +61 -0
  543. package/src/components/section-progress/section-progress-ring.tsx +73 -0
  544. package/src/components/section-progress/section-progress.context.tsx +77 -0
  545. package/src/components/section-progress/section-progress.tsx +336 -0
  546. package/src/components/section-progress/section-progress.variants.test.ts +319 -0
  547. package/src/components/section-progress/section-progress.variants.ts +260 -0
  548. package/src/components/section-rail/AGENTS.md +103 -0
  549. package/src/components/section-rail/index.ts +38 -0
  550. package/src/components/section-rail/section-rail-bar.tsx +60 -0
  551. package/src/components/section-rail/section-rail-content.tsx +92 -0
  552. package/src/components/section-rail/section-rail-item.tsx +80 -0
  553. package/src/components/section-rail/section-rail-scrim.tsx +26 -0
  554. package/src/components/section-rail/section-rail-trigger.tsx +150 -0
  555. package/src/components/section-rail/section-rail.context.tsx +86 -0
  556. package/src/components/section-rail/section-rail.tsx +305 -0
  557. package/src/components/section-rail/section-rail.variants.test.ts +325 -0
  558. package/src/components/section-rail/section-rail.variants.ts +238 -0
  559. package/src/components/select/AGENTS.md +126 -0
  560. package/src/components/select/index.ts +46 -0
  561. package/src/components/select/select-group.tsx +20 -0
  562. package/src/components/select/select-item.tsx +30 -0
  563. package/src/components/select/select-option-row.tsx +154 -0
  564. package/src/components/select/select-trigger.tsx +161 -0
  565. package/src/components/select/select.collect.test.ts +80 -0
  566. package/src/components/select/select.collect.ts +74 -0
  567. package/src/components/select/select.context.tsx +88 -0
  568. package/src/components/select/select.tsx +396 -0
  569. package/src/components/select/select.types.ts +62 -0
  570. package/src/components/select/select.variants.test.ts +568 -0
  571. package/src/components/select/select.variants.ts +473 -0
  572. package/src/components/signature/AGENTS.md +114 -0
  573. package/src/components/signature/index.ts +58 -0
  574. package/src/components/signature/signature-action-button.tsx +63 -0
  575. package/src/components/signature/signature-alternative.tsx +44 -0
  576. package/src/components/signature/signature-clear.tsx +14 -0
  577. package/src/components/signature/signature-live-path.tsx +41 -0
  578. package/src/components/signature/signature-pad.tsx +223 -0
  579. package/src/components/signature/signature-path.tsx +56 -0
  580. package/src/components/signature/signature-redo.tsx +14 -0
  581. package/src/components/signature/signature-toolbar.tsx +28 -0
  582. package/src/components/signature/signature-undo.tsx +14 -0
  583. package/src/components/signature/signature.context.tsx +105 -0
  584. package/src/components/signature/signature.stroke.test.ts +413 -0
  585. package/src/components/signature/signature.stroke.ts +392 -0
  586. package/src/components/signature/signature.tsx +379 -0
  587. package/src/components/signature/signature.types.ts +65 -0
  588. package/src/components/signature/signature.variants.test.ts +245 -0
  589. package/src/components/signature/signature.variants.ts +229 -0
  590. package/src/components/sketch/AGENTS.md +245 -0
  591. package/src/components/sketch/index.ts +66 -0
  592. package/src/components/sketch/sketch-canvas.tsx +286 -0
  593. package/src/components/sketch/sketch-size.tsx +53 -0
  594. package/src/components/sketch/sketch-swatches.tsx +54 -0
  595. package/src/components/sketch/sketch-tool.tsx +104 -0
  596. package/src/components/sketch/sketch-toolbar.tsx +64 -0
  597. package/src/components/sketch/sketch-undo.tsx +41 -0
  598. package/src/components/sketch/sketch.context.tsx +103 -0
  599. package/src/components/sketch/sketch.paths.test.ts +359 -0
  600. package/src/components/sketch/sketch.paths.ts +324 -0
  601. package/src/components/sketch/sketch.skia.ts +88 -0
  602. package/src/components/sketch/sketch.tsx +410 -0
  603. package/src/components/sketch/sketch.types.ts +46 -0
  604. package/src/components/sketch/sketch.variants.test.ts +221 -0
  605. package/src/components/sketch/sketch.variants.ts +211 -0
  606. package/src/components/sortable/AGENTS.md +121 -0
  607. package/src/components/sortable/index.ts +39 -0
  608. package/src/components/sortable/sortable-handle.tsx +79 -0
  609. package/src/components/sortable/sortable-item.tsx +198 -0
  610. package/src/components/sortable/sortable.context.tsx +135 -0
  611. package/src/components/sortable/sortable.tsx +464 -0
  612. package/src/components/sortable/sortable.types.ts +25 -0
  613. package/src/components/sortable/sortable.variants.test.ts +402 -0
  614. package/src/components/sortable/sortable.variants.ts +335 -0
  615. package/src/components/sortable/use-sortable-drag-gesture.ts +54 -0
  616. package/src/components/split-view/AGENTS.md +193 -0
  617. package/src/components/split-view/index.ts +20 -0
  618. package/src/components/split-view/split-view-bottom.tsx +21 -0
  619. package/src/components/split-view/split-view-drag-area.tsx +223 -0
  620. package/src/components/split-view/split-view-handle.tsx +29 -0
  621. package/src/components/split-view/split-view-top.tsx +28 -0
  622. package/src/components/split-view/split-view.context.tsx +87 -0
  623. package/src/components/split-view/split-view.tsx +315 -0
  624. package/src/components/split-view/split-view.types.ts +10 -0
  625. package/src/components/split-view/split-view.variants.test.ts +380 -0
  626. package/src/components/split-view/split-view.variants.ts +326 -0
  627. package/src/components/splitter/AGENTS.md +194 -0
  628. package/src/components/splitter/index.ts +32 -0
  629. package/src/components/splitter/splitter-grip.tsx +30 -0
  630. package/src/components/splitter/splitter-handle.tsx +269 -0
  631. package/src/components/splitter/splitter-pane.tsx +70 -0
  632. package/src/components/splitter/splitter.context.tsx +123 -0
  633. package/src/components/splitter/splitter.math.test.ts +134 -0
  634. package/src/components/splitter/splitter.math.ts +113 -0
  635. package/src/components/splitter/splitter.tsx +341 -0
  636. package/src/components/splitter/splitter.types.ts +5 -0
  637. package/src/components/splitter/splitter.variants.test.ts +615 -0
  638. package/src/components/splitter/splitter.variants.ts +604 -0
  639. package/src/components/support/AGENTS.md +148 -0
  640. package/src/components/support/index.ts +58 -0
  641. package/src/components/support/support-agent.tsx +81 -0
  642. package/src/components/support/support-article.tsx +27 -0
  643. package/src/components/support/support-articles.tsx +21 -0
  644. package/src/components/support/support-channel.tsx +52 -0
  645. package/src/components/support/support-channels.tsx +21 -0
  646. package/src/components/support/support-conversation.tsx +74 -0
  647. package/src/components/support/support-conversations.tsx +21 -0
  648. package/src/components/support/support-handoff.tsx +51 -0
  649. package/src/components/support/support-header.tsx +33 -0
  650. package/src/components/support/support-note.tsx +54 -0
  651. package/src/components/support/support-replies.tsx +45 -0
  652. package/src/components/support/support-reply.tsx +41 -0
  653. package/src/components/support/support-resolution.tsx +37 -0
  654. package/src/components/support/support-section.tsx +38 -0
  655. package/src/components/support/support-status.tsx +49 -0
  656. package/src/components/support/support-ticket.tsx +37 -0
  657. package/src/components/support/support-topic.tsx +75 -0
  658. package/src/components/support/support-topics.tsx +76 -0
  659. package/src/components/support/support-typing.tsx +91 -0
  660. package/src/components/support/support.context.tsx +80 -0
  661. package/src/components/support/support.tsx +112 -0
  662. package/src/components/support/support.types.ts +24 -0
  663. package/src/components/support/support.utils.test.ts +214 -0
  664. package/src/components/support/support.utils.ts +206 -0
  665. package/src/components/support/support.variants.test.ts +198 -0
  666. package/src/components/support/support.variants.ts +124 -0
  667. package/src/components/table/AGENTS.md +125 -0
  668. package/src/components/table/index.ts +57 -0
  669. package/src/components/table/table-body.tsx +32 -0
  670. package/src/components/table/table-caption.tsx +16 -0
  671. package/src/components/table/table-cell.tsx +62 -0
  672. package/src/components/table/table-empty.tsx +29 -0
  673. package/src/components/table/table-footer.tsx +22 -0
  674. package/src/components/table/table-frame.tsx +47 -0
  675. package/src/components/table/table-head.tsx +99 -0
  676. package/src/components/table/table-header.tsx +24 -0
  677. package/src/components/table/table-row.tsx +145 -0
  678. package/src/components/table/table-scroll.tsx +129 -0
  679. package/src/components/table/table-section.tsx +26 -0
  680. package/src/components/table/table.context.tsx +126 -0
  681. package/src/components/table/table.tsx +174 -0
  682. package/src/components/table/table.types.ts +19 -0
  683. package/src/components/table/table.variants.test.ts +531 -0
  684. package/src/components/table/table.variants.ts +476 -0
  685. package/src/components/tag-input/AGENTS.md +131 -0
  686. package/src/components/tag-input/index.ts +39 -0
  687. package/src/components/tag-input/tag-input-chip.tsx +89 -0
  688. package/src/components/tag-input/tag-input-suffix.tsx +75 -0
  689. package/src/components/tag-input/tag-input.context.tsx +85 -0
  690. package/src/components/tag-input/tag-input.logic.test.ts +414 -0
  691. package/src/components/tag-input/tag-input.logic.ts +345 -0
  692. package/src/components/tag-input/tag-input.tsx +528 -0
  693. package/src/components/tag-input/tag-input.types.ts +47 -0
  694. package/src/components/tag-input/tag-input.variants.test.ts +233 -0
  695. package/src/components/tag-input/tag-input.variants.ts +136 -0
  696. package/src/components/text-animation/AGENTS.md +183 -0
  697. package/src/components/text-animation/index.ts +34 -0
  698. package/src/components/text-animation/text-animation-caret.tsx +67 -0
  699. package/src/components/text-animation/text-animation-clock.ts +75 -0
  700. package/src/components/text-animation/text-animation-counting.tsx +166 -0
  701. package/src/components/text-animation/text-animation-rolling.tsx +259 -0
  702. package/src/components/text-animation/text-animation-rotating.tsx +225 -0
  703. package/src/components/text-animation/text-animation-typing.tsx +309 -0
  704. package/src/components/text-animation/text-animation-unit.tsx +112 -0
  705. package/src/components/text-animation/text-animation.tsx +294 -0
  706. package/src/components/text-animation/text-animation.types.ts +19 -0
  707. package/src/components/text-animation/text-animation.variants.test.ts +532 -0
  708. package/src/components/text-animation/text-animation.variants.ts +577 -0
  709. package/src/components/textarea/AGENTS.md +7 -4
  710. package/src/components/textarea/textarea.tsx +21 -3
  711. package/src/components/textarea/textarea.variants.test.ts +35 -0
  712. package/src/components/textarea/textarea.variants.ts +25 -5
  713. package/src/components/theme-selector/AGENTS.md +107 -0
  714. package/src/components/theme-selector/index.ts +37 -0
  715. package/src/components/theme-selector/theme-selector-option.tsx +52 -0
  716. package/src/components/theme-selector/theme-selector.context.tsx +65 -0
  717. package/src/components/theme-selector/theme-selector.logic.test.ts +160 -0
  718. package/src/components/theme-selector/theme-selector.logic.ts +130 -0
  719. package/src/components/theme-selector/theme-selector.tsx +171 -0
  720. package/src/components/theme-selector/theme-selector.types.ts +8 -0
  721. package/src/components/theme-selector/theme-selector.variants.test.ts +86 -0
  722. package/src/components/theme-selector/theme-selector.variants.ts +85 -0
  723. package/src/components/theme-selector/use-theme-selection.ts +51 -0
  724. package/src/components/time-picker/AGENTS.md +153 -0
  725. package/src/components/time-picker/index.ts +78 -0
  726. package/src/components/time-picker/time-picker-clear.tsx +34 -0
  727. package/src/components/time-picker/time-picker-content.tsx +61 -0
  728. package/src/components/time-picker/time-picker-done.tsx +32 -0
  729. package/src/components/time-picker/time-picker-icon.tsx +29 -0
  730. package/src/components/time-picker/time-picker-trigger.tsx +65 -0
  731. package/src/components/time-picker/time-picker-value.tsx +33 -0
  732. package/src/components/time-picker/time-picker-wheel-column.tsx +247 -0
  733. package/src/components/time-picker/time-picker-wheel-slot.tsx +38 -0
  734. package/src/components/time-picker/time-picker-wheel.tsx +134 -0
  735. package/src/components/time-picker/time-picker.context.tsx +92 -0
  736. package/src/components/time-picker/time-picker.time.test.ts +337 -0
  737. package/src/components/time-picker/time-picker.time.ts +290 -0
  738. package/src/components/time-picker/time-picker.tsx +260 -0
  739. package/src/components/time-picker/time-picker.types.ts +82 -0
  740. package/src/components/time-picker/time-picker.variants.test.ts +324 -0
  741. package/src/components/time-picker/time-picker.variants.ts +320 -0
  742. package/src/components/timeline/AGENTS.md +150 -0
  743. package/src/components/timeline/index.ts +66 -0
  744. package/src/components/timeline/timeline-aside.tsx +34 -0
  745. package/src/components/timeline/timeline-content.tsx +24 -0
  746. package/src/components/timeline/timeline-date.tsx +20 -0
  747. package/src/components/timeline/timeline-description.tsx +20 -0
  748. package/src/components/timeline/timeline-header.tsx +17 -0
  749. package/src/components/timeline/timeline-indicator.tsx +65 -0
  750. package/src/components/timeline/timeline-item.tsx +174 -0
  751. package/src/components/timeline/timeline-list.tsx +155 -0
  752. package/src/components/timeline/timeline-masthead.tsx +39 -0
  753. package/src/components/timeline/timeline-meta.tsx +20 -0
  754. package/src/components/timeline/timeline-stat.tsx +34 -0
  755. package/src/components/timeline/timeline-stats.tsx +13 -0
  756. package/src/components/timeline/timeline-title.tsx +85 -0
  757. package/src/components/timeline/timeline-track.tsx +43 -0
  758. package/src/components/timeline/timeline-trailing.tsx +17 -0
  759. package/src/components/timeline/timeline.context.tsx +141 -0
  760. package/src/components/timeline/timeline.tsx +221 -0
  761. package/src/components/timeline/timeline.types.ts +39 -0
  762. package/src/components/timeline/timeline.variants.test.ts +392 -0
  763. package/src/components/timeline/timeline.variants.ts +473 -0
  764. package/src/components/timeline/use-timeline-reading-edge.ts +54 -0
  765. package/src/components/toast/AGENTS.md +6 -7
  766. package/src/components/tooltip/AGENTS.md +2 -4
  767. package/src/components/tour/AGENTS.md +128 -0
  768. package/src/components/tour/index.ts +54 -0
  769. package/src/components/tour/tour-card.tsx +155 -0
  770. package/src/components/tour/tour-mask.tsx +50 -0
  771. package/src/components/tour/tour-overlay.tsx +234 -0
  772. package/src/components/tour/tour-scrim.tsx +88 -0
  773. package/src/components/tour/tour-step.tsx +55 -0
  774. package/src/components/tour/tour.context.tsx +85 -0
  775. package/src/components/tour/tour.tsx +275 -0
  776. package/src/components/tour/tour.types.ts +34 -0
  777. package/src/components/tour/tour.variants.test.ts +479 -0
  778. package/src/components/tour/tour.variants.ts +439 -0
  779. package/src/components/tree/AGENTS.md +141 -0
  780. package/src/components/tree/index.ts +56 -0
  781. package/src/components/tree/tree-actions.tsx +18 -0
  782. package/src/components/tree/tree-group.tsx +61 -0
  783. package/src/components/tree/tree-icon.tsx +19 -0
  784. package/src/components/tree/tree-indicator.tsx +91 -0
  785. package/src/components/tree/tree-item.tsx +90 -0
  786. package/src/components/tree/tree-label.tsx +30 -0
  787. package/src/components/tree/tree-trigger.tsx +170 -0
  788. package/src/components/tree/tree.context.tsx +144 -0
  789. package/src/components/tree/tree.tsx +216 -0
  790. package/src/components/tree/tree.types.ts +10 -0
  791. package/src/components/tree/tree.variants.test.ts +373 -0
  792. package/src/components/tree/tree.variants.ts +317 -0
  793. package/src/expo/blur-layer.tsx +40 -0
  794. package/src/hooks/use-reduce-transparency.ts +34 -0
  795. package/src/hooks/use-scroll-source.tsx +4 -4
  796. package/src/lib/color.test.ts +35 -1
  797. package/src/lib/color.ts +40 -0
  798. package/src/styles/theme.css +16 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delacour/react-native-ui",
3
- "version": "0.4.0-alpha.20261020083124",
3
+ "version": "0.4.0-alpha.20261020143428",
4
4
  "description": "React Native UI components — Uniwind, Reanimated, Gesture Handler",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -35,9 +35,12 @@
35
35
  "./styles/theme": "./src/styles/theme.css",
36
36
  "./accordion": "./src/components/accordion/index.ts",
37
37
  "./alert": "./src/components/alert/index.ts",
38
+ "./animated-badge": "./src/components/animated-badge/index.ts",
39
+ "./attachment": "./src/components/attachment/index.ts",
38
40
  "./avatar": "./src/components/avatar/index.ts",
39
41
  "./badge": "./src/components/badge/index.ts",
40
42
  "./bottom-sheet": "./src/components/bottom-sheet/index.ts",
43
+ "./breadcrumb": "./src/components/breadcrumb/index.ts",
41
44
  "./button": "./src/components/button/index.ts",
42
45
  "./calendar": "./src/components/calendar/index.ts",
43
46
  "./card": "./src/components/card/index.ts",
@@ -45,54 +48,106 @@
45
48
  "./chart": "./src/components/chart/index.ts",
46
49
  "./checkbox": "./src/components/checkbox/index.ts",
47
50
  "./chip": "./src/components/chip/index.ts",
51
+ "./circular-text": "./src/components/circular-text/index.ts",
48
52
  "./collapsible": "./src/components/collapsible/index.ts",
53
+ "./color-picker": "./src/components/color-picker/index.ts",
54
+ "./combobox": "./src/components/combobox/index.ts",
55
+ "./compare": "./src/components/compare/index.ts",
49
56
  "./context-menu": "./src/components/context-menu/index.ts",
57
+ "./countdown": "./src/components/countdown/index.ts",
58
+ "./date-picker": "./src/components/date-picker/index.ts",
59
+ "./date-time-picker": "./src/components/date-time-picker/index.ts",
50
60
  "./dialog": "./src/components/dialog/index.ts",
61
+ "./direction": "./src/components/direction/index.ts",
51
62
  "./drawer": "./src/components/drawer/index.ts",
52
63
  "./empty-state": "./src/components/empty-state/index.ts",
53
64
  "./fab": "./src/components/fab/index.ts",
54
65
  "./feedback": "./src/components/feedback/index.ts",
55
66
  "./field": "./src/components/field/index.ts",
67
+ "./flip-card": "./src/components/flip-card/index.ts",
68
+ "./flow": "./src/components/flow/index.ts",
69
+ "./frame": "./src/components/frame/index.ts",
70
+ "./grid-item": "./src/components/grid-item/index.ts",
56
71
  "./icon": "./src/components/icon/index.ts",
72
+ "./image-viewer": "./src/components/image-viewer/index.ts",
57
73
  "./input": "./src/components/input/index.ts",
58
74
  "./item": "./src/components/item/index.ts",
59
75
  "./kpi": "./src/components/kpi/index.ts",
60
76
  "./label": "./src/components/label/index.ts",
77
+ "./leaderboard": "./src/components/leaderboard/index.ts",
61
78
  "./list-group": "./src/components/list-group/index.ts",
62
79
  "./map": "./src/components/map/index.ts",
80
+ "./markdown-editor": "./src/components/markdown-editor/index.ts",
81
+ "./marker": "./src/components/marker/index.ts",
82
+ "./marquee": "./src/components/marquee/index.ts",
63
83
  "./menu": "./src/components/menu/index.ts",
84
+ "./message": "./src/components/message/index.ts",
85
+ "./message-scroller": "./src/components/message-scroller/index.ts",
64
86
  "./meter": "./src/components/meter/index.ts",
87
+ "./number-input": "./src/components/number-input/index.ts",
88
+ "./otp-input": "./src/components/otp-input/index.ts",
65
89
  "./overlay": "./src/components/overlay/index.ts",
90
+ "./page-header": "./src/components/page-header/index.ts",
91
+ "./pagination": "./src/components/pagination/index.ts",
92
+ "./planner": "./src/components/planner/index.ts",
66
93
  "./popover": "./src/components/popover/index.ts",
94
+ "./post": "./src/components/post/index.ts",
67
95
  "./pressable": "./src/components/pressable/index.ts",
68
96
  "./progress": "./src/components/progress/index.ts",
69
97
  "./progress-button": "./src/components/progress-button/index.ts",
70
98
  "./provider": "./src/components/provider/index.ts",
99
+ "./qr-code": "./src/components/qr-code/index.ts",
100
+ "./questionnaire": "./src/components/questionnaire/index.ts",
71
101
  "./radio": "./src/components/radio/index.ts",
72
102
  "./rating": "./src/components/rating/index.ts",
73
103
  "./screen": "./src/components/screen/index.ts",
104
+ "./scroll-blur": "./src/components/scroll-blur/index.ts",
105
+ "./scroll-canvas": "./src/components/scroll-canvas/index.ts",
106
+ "./scroll-fade": "./src/components/scroll-fade/index.ts",
107
+ "./scroll-header": "./src/components/scroll-header/index.ts",
108
+ "./scroll-text": "./src/components/scroll-text/index.ts",
109
+ "./search-bar": "./src/components/search-bar/index.ts",
110
+ "./section-progress": "./src/components/section-progress/index.ts",
111
+ "./section-rail": "./src/components/section-rail/index.ts",
112
+ "./select": "./src/components/select/index.ts",
74
113
  "./selection-mode": "./src/components/selection-mode/index.ts",
75
114
  "./separator": "./src/components/separator/index.ts",
115
+ "./signature": "./src/components/signature/index.ts",
76
116
  "./skeleton": "./src/components/skeleton/index.ts",
117
+ "./sketch": "./src/components/sketch/index.ts",
77
118
  "./slide-button": "./src/components/slide-button/index.ts",
78
119
  "./slider": "./src/components/slider/index.ts",
120
+ "./sortable": "./src/components/sortable/index.ts",
79
121
  "./spinner": "./src/components/spinner/index.ts",
122
+ "./split-view": "./src/components/split-view/index.ts",
123
+ "./splitter": "./src/components/splitter/index.ts",
80
124
  "./stack-card": "./src/components/stack-card/index.ts",
81
125
  "./steps": "./src/components/steps/index.ts",
126
+ "./support": "./src/components/support/index.ts",
82
127
  "./surface": "./src/components/surface/index.ts",
83
128
  "./swipe": "./src/components/swipe/index.ts",
84
129
  "./switch": "./src/components/switch/index.ts",
130
+ "./table": "./src/components/table/index.ts",
85
131
  "./tabs": "./src/components/tabs/index.ts",
132
+ "./tag-input": "./src/components/tag-input/index.ts",
86
133
  "./text": "./src/components/text/index.ts",
134
+ "./text-animation": "./src/components/text-animation/index.ts",
87
135
  "./textarea": "./src/components/textarea/index.ts",
136
+ "./theme-selector": "./src/components/theme-selector/index.ts",
137
+ "./time-picker": "./src/components/time-picker/index.ts",
138
+ "./timeline": "./src/components/timeline/index.ts",
88
139
  "./toast": "./src/components/toast/index.ts",
89
140
  "./toggle-button": "./src/components/toggle-button/index.ts",
90
141
  "./tooltip": "./src/components/tooltip/index.ts",
142
+ "./tour": "./src/components/tour/index.ts",
143
+ "./tree": "./src/components/tree/index.ts",
144
+ "./expo/blur-layer": "./src/expo/blur-layer.tsx",
91
145
  "./expo/navigation-theme": "./src/expo/navigation-theme.tsx",
92
146
  "./hooks/use-calm-motion": "./src/hooks/use-calm-motion.tsx",
93
147
  "./hooks/use-controllable-state": "./src/hooks/use-controllable-state.ts",
94
148
  "./hooks/use-keyboard-state-sync": "./src/hooks/use-keyboard-state-sync.tsx",
95
149
  "./hooks/use-navigation-theme": "./src/hooks/use-navigation-theme.ts",
150
+ "./hooks/use-reduce-transparency": "./src/hooks/use-reduce-transparency.ts",
96
151
  "./hooks/use-scroll-sections": "./src/hooks/use-scroll-sections.ts",
97
152
  "./hooks/use-scroll-source": "./src/hooks/use-scroll-source.tsx",
98
153
  "./hooks/use-theme-color": "./src/hooks/use-theme-color.ts",
@@ -123,11 +178,13 @@
123
178
  "tailwind-variants": "^3.3.1"
124
179
  },
125
180
  "peerDependencies": {
181
+ "expo-blur": ">=15",
126
182
  "@maplibre/maplibre-react-native": "^11.5.0",
127
183
  "@central-icons-react-native/round-outlined-radius-1-stroke-1.5": "^1.1",
128
- "@delacour/react-native-bottom-sheet": "0.2.0-alpha.20261020083124",
184
+ "@delacour/react-native-bottom-sheet": "0.2.0-alpha.20261020143428",
129
185
  "@delacour/react-native-charts": ">=0.1.0",
130
186
  "@legendapp/list": ">=3.3",
187
+ "@shopify/react-native-skia": ">=2",
131
188
  "expo-linear-gradient": ">=15",
132
189
  "expo-router": ">=57",
133
190
  "react": ">=19",
@@ -145,6 +202,9 @@
145
202
  "uniwind": "^1.11.0"
146
203
  },
147
204
  "peerDependenciesMeta": {
205
+ "expo-blur": {
206
+ "optional": true
207
+ },
148
208
  "@maplibre/maplibre-react-native": {
149
209
  "optional": true
150
210
  },
@@ -157,6 +217,9 @@
157
217
  "@legendapp/list": {
158
218
  "optional": true
159
219
  },
220
+ "@shopify/react-native-skia": {
221
+ "optional": true
222
+ },
160
223
  "expo-router": {
161
224
  "optional": true
162
225
  },
@@ -168,6 +231,7 @@
168
231
  }
169
232
  },
170
233
  "devDependencies": {
234
+ "expo-blur": "~58.0.5",
171
235
  "@maplibre/maplibre-react-native": "^11.5.0",
172
236
  "@delacour/biome-config": "workspace:*",
173
237
  "@delacour/react-native-bottom-sheet": "workspace:*",
@@ -0,0 +1,132 @@
1
+ # AnimatedBadge
2
+
3
+ A status pill whose content moves when it changes: the old glyph and label roll
4
+ out, the new ones roll in, and the capsule springs to the new width. One paint,
5
+ one job, a small closed API.
6
+
7
+ `import { AnimatedBadge } from "@delacour/react-native-ui/animated-badge";`
8
+
9
+ ## Files
10
+
11
+ | File | What it holds |
12
+ | --- | --- |
13
+ | `index.ts` | → `@delacour/react-native-ui/animated-badge` (component, props, statuses, sizes, resolvers) |
14
+ | `animated-badge.tsx` | The root — builds the frame, owns the width spring and the layout transition |
15
+ | `animated-badge-content.tsx` | The moving glyph + label unit (internal leaf, `DelacourUI.AnimatedBadge.Content`) |
16
+ | `animated-badge-glyph.tsx` | Status → glyph map, the spinner for `loading`, the pulse (internal leaf, `…Glyph`) |
17
+ | `animated-badge-measure.tsx` | The invisible measurer that lays out the incoming content (internal leaf, `…Measure`) |
18
+ | `use-animated-badge-roll.ts` | The roll: holds the outgoing frame until it is off-screen, then lands the newest |
19
+ | `animated-badge.types.ts` | `AnimatedBadgeFrame`, shared by the root, the roll, the content and the measurer |
20
+ | `animated-badge.variants.ts` | Statuses, sizes, status → colour, constants, pure resolvers — no RN imports |
21
+ | `animated-badge.variants.test.ts` | Written first |
22
+
23
+ ## Design
24
+
25
+ - **Not a `Badge`, and not a mode of one.** `Badge` is a static label with four
26
+ paints, six colours and composed content. This is one paint and one job — say a
27
+ status, and move when it changes. Folding a roll into `Badge` would put a
28
+ measurer and two springs under every tag in a list that never changes.
29
+ - **No compound parts.** The roll has to own the glyph and the label together as
30
+ one moving unit, so an `AnimatedBadge.Label` would only invite a child the roll
31
+ cannot see. A caller wanting composed content uses `Badge`.
32
+ - **No `onPress`.** A status pill reports; it has no action. The root is a plain
33
+ `Animated.View` with `accessibilityRole="text"`. A tappable status is a `Badge`
34
+ with `onPress`, which already brings `Pressable`, feedback and haptics.
35
+ - **One paint: `Badge`'s soft row, read rather than restated.**
36
+ `resolveAnimatedBadgeSlots` calls `badgeVariants({ variant: "soft", color, size })`
37
+ from `../badge/badge.variants` — a leaf, legal across folders (package rule 3);
38
+ never `../badge`. A test asserts the root, label and icon slots equal `Badge`'s
39
+ at every status and size, so the two sit level in a row. No ring: the soft
40
+ badge's reserved border stays transparent.
41
+ - **`status` maps to a `BadgeColor`, and `neutral` and `loading` share the
42
+ neutral fill.** `destructive`, never `danger`. Work in flight has no verdict
43
+ yet; the spinner already says it is moving. The glyph's colour is
44
+ `BADGE_FOREGROUND_TOKEN.soft[color]`, the token the label resolves to, pinned by
45
+ a test and checked against both themes.
46
+ - **Sizes are `sm` and `md` only.** A status pill sits in a list row, a header or
47
+ a sentence; `lg` is a banner's size, and that is `Alert`.
48
+ - **Glyphs match `Alert`'s** for the four statuses both have: `IconCircleInfo`,
49
+ `IconCircleCheck`, `IconExclamationTriangle` (warning) and
50
+ `IconExclamationCircle` (destructive) — triangle against circle, so the two
51
+ read apart without colour. `neutral` is a bare `IconCircle`. `loading` is a
52
+ `Spinner`, sized and coloured by the same `IconDefaultsProvider` as an icon.
53
+ - **A custom `icon` beats the status's glyph, `loading` included.** It is the
54
+ caller's explicit word. `showIcon={false}` draws nothing; the two are a
55
+ discriminated union so `icon` with `showIcon={false}` does not typecheck.
56
+ - **`icon` takes an `IconComponent`, not a node.** The badge renders it through
57
+ `<Icon>`, so its size and colour come from the badge — icons inherit, never
58
+ hand-sized.
59
+ - **The roll is one view, never two copies.** `useAnimatedBadgeRoll` holds the
60
+ frame on screen while the exit runs (`ROLL_OUT_MS`, toward `-ROLL_DISTANCE`,
61
+ fading out). The swap happens from the exit's completion callback via
62
+ `scheduleOnRN`, while the content is invisible; the enter springs in from
63
+ `+ROLL_DISTANCE` in a layout effect after that commit, so it never starts on the
64
+ outgoing word. Two overlapping copies double up mid-swap, which is the failure
65
+ this shape exists to prevent.
66
+ - **A change mid-roll retargets.** The exit continues from where it is, and
67
+ whichever frame is newest when it finishes lands — intermediates are skipped. A
68
+ change back to the frame still on screen returns it home instead of rolling.
69
+ The effect is keyed on the two keys, not on the frame object, so a parent
70
+ re-rendering mid-exit does not restart the exit's clock.
71
+ - **The capsule paints from the frame on screen**, not from the incoming props.
72
+ Its fill changes while the outgoing word is invisible, rather than under it, and
73
+ the outgoing word keeps its own colour on its way out.
74
+ - **The width spring measures the next content before it arrives.**
75
+ `AnimatedBadgeMeasure` is a copy of the capsule — the root's classes, the row,
76
+ the one-line label — on an absolutely positioned, transparent,
77
+ `pointerEvents="none"`, hidden-from-assistive-technology canvas. Its `onLayout`
78
+ drives the root's `width` with `withSpring`. The canvas is
79
+ `MEASURE_CANVAS_WIDTH` wide because Yoga caps an absolute child's available
80
+ width at its parent's: without it a narrow badge would wrap the next word and
81
+ report the wrapped width. The glyph is measured as a box of the icon step — a
82
+ spinner in the measurer would spin for nobody.
83
+ - **The first paint never jumps.** The root carries no width until the first
84
+ measure, and that first measure is set without a spring.
85
+ - **A text label is drawn on one line** (`numberOfLines={1}`) — the measurer lays
86
+ it out on one line too, so the measured width is the width drawn. A status is
87
+ a word or two; a sentence belongs in an `Alert`.
88
+ - **Padding, never a height** — `Badge`'s rule and reason: OS font scaling.
89
+ - **`animateLayout`** puts `LinearTransition.springify()` on the root, so the
90
+ badge springs to a new position when the layout around it moves. Inside
91
+ flowing text that would slide the badge across lines when the sentence
92
+ reflows, so `animateLayout={false}` turns it off.
93
+ - **Change detection is a string key.** `resolveAnimatedBadgeKey`:
94
+ `contentKey` wins (`status:contentKey`), then text children — a string, a
95
+ number, or an array of only those (`status:joined`) — then the status alone. A
96
+ non-text label therefore rolls only on a status change unless it is given a
97
+ `contentKey`. The same key across a re-render does nothing.
98
+ - **Reduce motion cuts over; calm motion stills only the pulse.**
99
+ `resolveAnimatedBadgeMotion` returns `{ roll, resize, layout, pulse }`. Under
100
+ `useReducedMotion()` the content swaps, the width is set, no layout transition
101
+ runs and nothing pulses. Under the app's `isMotionCalm` alone (E2E) the roll
102
+ and springs still run — they settle, which is all a test runner waits for —
103
+ and only the endless pulse holds still.
104
+ - **The pulse is on the glyph, not the capsule.** A swelling capsule pushes the
105
+ layout around it and reads as noise; a swelling glyph reads as breathing. It
106
+ defaults on for `loading`, and an explicit `pulse={false}` wins. Its repeat
107
+ sets `ReduceMotion.Never` and is gated one level up, exactly like
108
+ `useSkeletonClock` — under the default policy a `withRepeat(-1)` of a
109
+ zero-length timing spins forever.
110
+ - **Accessibility.** The root is `accessible`, `accessibilityRole="text"`,
111
+ labelled with the label text (a caller's `accessibilityLabel` wins) and
112
+ `accessibilityState.busy` while `loading`. The glyph is hidden — it duplicates
113
+ the word — and so is the measurer. With `announce` (default `true`) the root
114
+ is a polite live region on Android, and iOS calls
115
+ `AccessibilityInfo.announceForAccessibility` once the new content lands, never
116
+ on mount. Pass `announce={false}` in a list of fifty, where every row
117
+ announcing is noise.
118
+
119
+ ## Where the spec and the icon set disagreed
120
+
121
+ - The usage examples name a sparkles glyph; Central has `IconSparkle`, singular.
122
+ The demos and docs use `IconSparkle`.
123
+ - The spec's file map has no measurer, roll hook or types file. Each exists
124
+ because the root, the content and the measurer all need the frame, and a part
125
+ must never import its own root (package rule 3).
126
+ - No demo carries `meta.capture` yet. A captured demo must have committed media
127
+ in `apps/web/src/previews/manifest.ts`, and that is written only by
128
+ `bun run previews` on a simulator, which this change did not run. The intended
129
+ set is `status-flow` (hero), `statuses`, `sizes`, `custom-icon` and
130
+ `inline-text`; `reduced-motion` stays uncaptured. Add `capture` to those five
131
+ in the same commit that photographs them, then add `<Preview>` heroes to the
132
+ docs page.
@@ -0,0 +1,58 @@
1
+ import type { ReactElement } from "react";
2
+ import Animated from "react-native-reanimated";
3
+ import { IconDefaultsProvider } from "../icon";
4
+ import { Text } from "../text";
5
+ import { TextClassProvider } from "../text/text.context";
6
+ import type { AnimatedBadgeAnimatedStyle, AnimatedBadgeFrame } from "./animated-badge.types";
7
+ import {
8
+ type AnimatedBadgeSize,
9
+ resolveAnimatedBadgeForeground,
10
+ resolveAnimatedBadgeSlots,
11
+ } from "./animated-badge.variants";
12
+ import { AnimatedBadgeGlyph } from "./animated-badge-glyph";
13
+
14
+ export type AnimatedBadgeContentProps = {
15
+ frame: AnimatedBadgeFrame;
16
+ size: AnimatedBadgeSize;
17
+ labelClassName: string | undefined;
18
+ /** The roll's offset and opacity, from `useAnimatedBadgeRoll`. */
19
+ rollStyle: AnimatedBadgeAnimatedStyle;
20
+ isPulsing: boolean;
21
+ };
22
+
23
+ /**
24
+ * The moving unit: glyph and label in one row, rolled as one view.
25
+ *
26
+ * Paints from the frame it is handed rather than from the root's props, so the
27
+ * outgoing word keeps its own colour until it has left. A text label is drawn
28
+ * on one line — the measurer lays the next one out on one line too, and the
29
+ * capsule springs to that width.
30
+ */
31
+ export function AnimatedBadgeContent({
32
+ frame,
33
+ size,
34
+ labelClassName,
35
+ rollStyle,
36
+ isPulsing,
37
+ }: AnimatedBadgeContentProps): ReactElement {
38
+ const slots = resolveAnimatedBadgeSlots({ status: frame.status, size, labelClassName });
39
+ const iconDefaults = { className: slots.icon, color: resolveAnimatedBadgeForeground(frame.status) };
40
+
41
+ return (
42
+ <IconDefaultsProvider value={iconDefaults}>
43
+ <TextClassProvider value={slots.label}>
44
+ <Animated.View className={slots.content} style={rollStyle}>
45
+ <AnimatedBadgeGlyph icon={frame.icon} isPulsing={isPulsing} kind={frame.glyph} status={frame.status} />
46
+ {frame.text === undefined ? (
47
+ frame.label
48
+ ) : (
49
+ <Text className={slots.label} numberOfLines={1}>
50
+ {frame.text}
51
+ </Text>
52
+ )}
53
+ </Animated.View>
54
+ </TextClassProvider>
55
+ </IconDefaultsProvider>
56
+ );
57
+ }
58
+ AnimatedBadgeContent.displayName = "DelacourUI.AnimatedBadge.Content";
@@ -0,0 +1,118 @@
1
+ import { type ReactElement, useEffect } from "react";
2
+ import Animated, {
3
+ cancelAnimation,
4
+ Easing,
5
+ ReduceMotion,
6
+ useAnimatedStyle,
7
+ useSharedValue,
8
+ withRepeat,
9
+ withTiming,
10
+ } from "react-native-reanimated";
11
+ import {
12
+ IconCircle,
13
+ IconCircleCheck,
14
+ IconCircleInfo,
15
+ IconExclamationCircle,
16
+ IconExclamationTriangle,
17
+ } from "../../icons/central";
18
+ import { Icon, type IconComponent } from "../icon";
19
+ import { Spinner } from "../spinner";
20
+ import {
21
+ type AnimatedBadgeGlyphKind,
22
+ type AnimatedBadgeStatus,
23
+ PULSE_CYCLE_MS,
24
+ PULSE_MAX_SCALE,
25
+ PULSE_MIN_OPACITY,
26
+ } from "./animated-badge.variants";
27
+
28
+ /**
29
+ * The glyph each status draws when the caller names none.
30
+ *
31
+ * The four statuses `Alert` also has take `Alert`'s glyphs, so a warning reads
32
+ * the same in a badge as in a banner — and `warning` and `destructive` differ in
33
+ * shape as well as colour, a triangle against a circle, for anyone who cannot
34
+ * tell amber from red. `neutral` is a bare ring: a status with no verdict.
35
+ * `loading` is absent because it spins instead.
36
+ *
37
+ * Lives here rather than in `animated-badge.variants.ts` because the glyphs are
38
+ * React Native SVG components, and that file must stay importable from `bun test`.
39
+ */
40
+ const STATUS_GLYPHS: Record<Exclude<AnimatedBadgeStatus, "loading">, IconComponent> = {
41
+ neutral: IconCircle,
42
+ info: IconCircleInfo,
43
+ success: IconCircleCheck,
44
+ warning: IconExclamationTriangle,
45
+ destructive: IconExclamationCircle,
46
+ };
47
+
48
+ /**
49
+ * The element for a resolved glyph kind. `loading` with no custom icon always
50
+ * spins, whichever kind it arrives with.
51
+ */
52
+ function pickGlyph(
53
+ kind: "spinner" | "icon",
54
+ status: AnimatedBadgeStatus,
55
+ icon: IconComponent | undefined
56
+ ): ReactElement {
57
+ if (kind === "icon" && icon) return <Icon icon={icon} />;
58
+ if (status === "loading") return <Spinner />;
59
+ return <Icon icon={icon ?? STATUS_GLYPHS[status]} />;
60
+ }
61
+
62
+ export type AnimatedBadgeGlyphProps = {
63
+ kind: AnimatedBadgeGlyphKind;
64
+ status: AnimatedBadgeStatus;
65
+ icon: IconComponent | undefined;
66
+ /** Swell in a loop. Already resolved against calm and reduced motion. */
67
+ isPulsing: boolean;
68
+ };
69
+
70
+ /**
71
+ * The glyph leading the label: the caller's icon, the status's icon, or a
72
+ * spinner for `loading`. Size and colour come from the badge's
73
+ * `IconDefaultsProvider`, never from here.
74
+ *
75
+ * Hidden from assistive technology — it duplicates the word beside it, and the
76
+ * spinner would otherwise announce itself as a progress bar inside a label.
77
+ *
78
+ * The pulse is a 0 → 1 clock read through a cosine, the shape `Skeleton`'s pulse
79
+ * uses. Its timing sets `ReduceMotion.Never` because the gate is one level up,
80
+ * in `resolveAnimatedBadgeMotion`: under the default policy a `withRepeat(-1)`
81
+ * of a timing the OS has zeroed spins forever.
82
+ */
83
+ export function AnimatedBadgeGlyph({ kind, status, icon, isPulsing }: AnimatedBadgeGlyphProps): ReactElement | null {
84
+ const clock = useSharedValue(0);
85
+
86
+ useEffect(() => {
87
+ if (!isPulsing) {
88
+ cancelAnimation(clock);
89
+ clock.value = 0;
90
+ return;
91
+ }
92
+
93
+ clock.value = 0;
94
+ clock.value = withRepeat(
95
+ withTiming(1, { duration: PULSE_CYCLE_MS, easing: Easing.linear, reduceMotion: ReduceMotion.Never }),
96
+ -1,
97
+ false
98
+ );
99
+ return () => cancelAnimation(clock);
100
+ }, [isPulsing, clock]);
101
+
102
+ const pulseStyle = useAnimatedStyle(() => {
103
+ const swell = (1 - Math.cos(clock.value * 2 * Math.PI)) / 2;
104
+ return {
105
+ opacity: 1 - (1 - PULSE_MIN_OPACITY) * swell,
106
+ transform: [{ scale: 1 + (PULSE_MAX_SCALE - 1) * swell }],
107
+ };
108
+ });
109
+
110
+ if (kind === "none") return null;
111
+
112
+ return (
113
+ <Animated.View accessibilityElementsHidden importantForAccessibility="no-hide-descendants" style={pulseStyle}>
114
+ {pickGlyph(kind, status, icon)}
115
+ </Animated.View>
116
+ );
117
+ }
118
+ AnimatedBadgeGlyph.displayName = "DelacourUI.AnimatedBadge.Glyph";
@@ -0,0 +1,69 @@
1
+ import type { ReactElement } from "react";
2
+ import { type LayoutChangeEvent, View } from "react-native";
3
+ import { Text } from "../text";
4
+ import { TextClassProvider } from "../text/text.context";
5
+ import type { AnimatedBadgeFrame } from "./animated-badge.types";
6
+ import { type AnimatedBadgeSize, MEASURE_CANVAS_WIDTH, resolveAnimatedBadgeSlots } from "./animated-badge.variants";
7
+
8
+ export type AnimatedBadgeMeasureProps = {
9
+ /** The incoming frame — the one the capsule is about to hold. */
10
+ frame: AnimatedBadgeFrame;
11
+ size: AnimatedBadgeSize;
12
+ className: string | undefined;
13
+ labelClassName: string | undefined;
14
+ /** Receives the capsule's width for {@link frame}, border and padding included. */
15
+ onMeasure: (width: number) => void;
16
+ };
17
+
18
+ /**
19
+ * Lays out the incoming content, invisibly, so the capsule can spring to its
20
+ * width before it arrives.
21
+ *
22
+ * A copy of the capsule — the root's own classes, the same row, the same label
23
+ * on one line — on an absolutely positioned canvas wider than any label (see
24
+ * `MEASURE_CANVAS_WIDTH`). The glyph is a box of the icon step rather than the
25
+ * glyph itself: the footprint is all that is measured, and a spinner here would
26
+ * spin for nobody.
27
+ *
28
+ * Hidden from assistive technology, transparent and untouchable — it exists for
29
+ * its `onLayout` and nothing else.
30
+ */
31
+ export function AnimatedBadgeMeasure({
32
+ frame,
33
+ size,
34
+ className,
35
+ labelClassName,
36
+ onMeasure,
37
+ }: AnimatedBadgeMeasureProps): ReactElement {
38
+ const slots = resolveAnimatedBadgeSlots({ status: frame.status, size, className, labelClassName });
39
+
40
+ const handleLayout = (event: LayoutChangeEvent): void => {
41
+ onMeasure(event.nativeEvent.layout.width);
42
+ };
43
+
44
+ return (
45
+ <View
46
+ accessibilityElementsHidden
47
+ className="absolute top-0 left-0 opacity-0"
48
+ importantForAccessibility="no-hide-descendants"
49
+ pointerEvents="none"
50
+ style={{ width: MEASURE_CANVAS_WIDTH }}
51
+ >
52
+ <TextClassProvider value={slots.label}>
53
+ <View className={slots.root} onLayout={handleLayout}>
54
+ <View className={slots.content}>
55
+ {frame.glyph === "none" ? null : <View className={slots.icon} />}
56
+ {frame.text === undefined ? (
57
+ frame.label
58
+ ) : (
59
+ <Text className={slots.label} numberOfLines={1}>
60
+ {frame.text}
61
+ </Text>
62
+ )}
63
+ </View>
64
+ </View>
65
+ </TextClassProvider>
66
+ </View>
67
+ );
68
+ }
69
+ AnimatedBadgeMeasure.displayName = "DelacourUI.AnimatedBadge.Measure";