@zyncat/ui 0.10.0 → 0.12.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 (597) hide show
  1. package/README.md +135 -40
  2. package/dist/alert.css +126 -121
  3. package/dist/alert.js +12 -14
  4. package/dist/alert.js.map +1 -1
  5. package/dist/avatar-group.js.map +1 -1
  6. package/dist/avatar.css +179 -174
  7. package/dist/avatar.js.map +1 -1
  8. package/dist/badge.css +166 -160
  9. package/dist/badge.js +1 -1
  10. package/dist/button.css +272 -246
  11. package/dist/button.js +1 -1
  12. package/dist/checkbox.css +158 -153
  13. package/dist/checkbox.js +2 -2
  14. package/dist/{chunk-UXONUUPI.js → chunk-227ZW4V7.js} +40 -32
  15. package/dist/chunk-227ZW4V7.js.map +1 -0
  16. package/dist/{chunk-2ERBBFZS.js → chunk-3MPF7FZV.js} +2 -2
  17. package/dist/chunk-3MPF7FZV.js.map +1 -0
  18. package/dist/{chunk-OMHQ4U4J.js → chunk-43M6GQ4Q.js} +86 -79
  19. package/dist/chunk-43M6GQ4Q.js.map +1 -0
  20. package/dist/{chunk-7SZCJ7WI.js → chunk-45R4Z5XN.js} +3 -3
  21. package/dist/chunk-45R4Z5XN.js.map +1 -0
  22. package/dist/{chunk-I4XQ4PV2.js → chunk-4BSHB7R3.js} +9 -7
  23. package/dist/chunk-4BSHB7R3.js.map +1 -0
  24. package/dist/{chunk-YGGCQNNU.js → chunk-4C5RZXBT.js} +33 -34
  25. package/dist/chunk-4C5RZXBT.js.map +1 -0
  26. package/dist/{chunk-2QWJ6FAX.js → chunk-5PZ43DCG.js} +31 -15
  27. package/dist/chunk-5PZ43DCG.js.map +1 -0
  28. package/dist/{chunk-S5ZTZANS.js → chunk-7IZJERGA.js} +35 -12
  29. package/dist/chunk-7IZJERGA.js.map +1 -0
  30. package/dist/{chunk-ZCOUPPTI.js → chunk-A5WTZACK.js} +22 -12
  31. package/dist/chunk-A5WTZACK.js.map +1 -0
  32. package/dist/{chunk-64UU4LGU.js → chunk-AADAJL7D.js} +3 -3
  33. package/dist/{chunk-64UU4LGU.js.map → chunk-AADAJL7D.js.map} +1 -1
  34. package/dist/{chunk-FTOAUJL5.js → chunk-CF4QHO4N.js} +21 -11
  35. package/dist/chunk-CF4QHO4N.js.map +1 -0
  36. package/dist/{chunk-WM5J5TDI.js → chunk-CNWTIMIP.js} +13 -17
  37. package/dist/chunk-CNWTIMIP.js.map +1 -0
  38. package/dist/{chunk-356HZMT4.js → chunk-DDRSMHN4.js} +31 -22
  39. package/dist/chunk-DDRSMHN4.js.map +1 -0
  40. package/dist/{chunk-VTJTGVZZ.js → chunk-DMX2F6B4.js} +2 -2
  41. package/dist/chunk-DMX2F6B4.js.map +1 -0
  42. package/dist/{chunk-3SBCBYB7.js → chunk-EAI4POPB.js} +2 -2
  43. package/dist/{chunk-3SBCBYB7.js.map → chunk-EAI4POPB.js.map} +1 -1
  44. package/dist/{chunk-Y7AJQVWJ.js → chunk-EF6RPXU7.js} +17 -15
  45. package/dist/chunk-EF6RPXU7.js.map +1 -0
  46. package/dist/{chunk-K5X2GCXU.js → chunk-FONOS5RN.js} +14 -15
  47. package/dist/chunk-FONOS5RN.js.map +1 -0
  48. package/dist/{chunk-PMECHR3A.js → chunk-FQEHSKEI.js} +2 -2
  49. package/dist/chunk-FQEHSKEI.js.map +1 -0
  50. package/dist/chunk-HDSFWZ7L.js +12 -0
  51. package/dist/chunk-HDSFWZ7L.js.map +1 -0
  52. package/dist/{chunk-2F5PITAO.js → chunk-HY5MPISE.js} +2 -2
  53. package/dist/chunk-HY5MPISE.js.map +1 -0
  54. package/dist/{chunk-QDK66S4G.js → chunk-I45AU6KH.js} +3 -3
  55. package/dist/chunk-I45AU6KH.js.map +1 -0
  56. package/dist/{chunk-YGCVWGUG.js → chunk-IJS7TPGV.js} +153 -46
  57. package/dist/chunk-IJS7TPGV.js.map +1 -0
  58. package/dist/{chunk-62P3KD57.js → chunk-IUQAUBVM.js} +18 -11
  59. package/dist/chunk-IUQAUBVM.js.map +1 -0
  60. package/dist/chunk-JY6A2ZJZ.js +44 -0
  61. package/dist/chunk-JY6A2ZJZ.js.map +1 -0
  62. package/dist/{chunk-XWUWYSCT.js → chunk-M43IOM5C.js} +20 -10
  63. package/dist/chunk-M43IOM5C.js.map +1 -0
  64. package/dist/{chunk-S7B34VGN.js → chunk-OWNMRMPN.js} +3 -3
  65. package/dist/{chunk-S7B34VGN.js.map → chunk-OWNMRMPN.js.map} +1 -1
  66. package/dist/chunk-RFRE4WKX.js +22 -0
  67. package/dist/chunk-RFRE4WKX.js.map +1 -0
  68. package/dist/{chunk-NNXJCLTV.js → chunk-RJFGWJ4W.js} +2 -2
  69. package/dist/chunk-RJFGWJ4W.js.map +1 -0
  70. package/dist/{chunk-NEF5XAHG.js → chunk-TUTXXC3W.js} +4 -4
  71. package/dist/chunk-TUTXXC3W.js.map +1 -0
  72. package/dist/chunk-TVYH4AN7.js +70 -0
  73. package/dist/chunk-TVYH4AN7.js.map +1 -0
  74. package/dist/{chunk-RCONNA7I.js → chunk-VAXCXZ53.js} +34 -22
  75. package/dist/chunk-VAXCXZ53.js.map +1 -0
  76. package/dist/chunk-XNIYSAMJ.js +52 -0
  77. package/dist/chunk-XNIYSAMJ.js.map +1 -0
  78. package/dist/{chunk-CONSWNIV.js → chunk-Y2YA7QRF.js} +6 -6
  79. package/dist/chunk-Y2YA7QRF.js.map +1 -0
  80. package/dist/cli.js +1809 -0
  81. package/dist/collapse.css +70 -61
  82. package/dist/collapse.js +2 -2
  83. package/dist/confetti.css +45 -0
  84. package/dist/confetti.js +540 -0
  85. package/dist/confetti.js.map +1 -0
  86. package/dist/count-badge.js +3 -3
  87. package/dist/count-badge.js.map +1 -1
  88. package/dist/date-field.js +24 -19
  89. package/dist/date-field.js.map +1 -1
  90. package/dist/date-picker.css +563 -559
  91. package/dist/date-range-field.js +58 -41
  92. package/dist/date-range-field.js.map +1 -1
  93. package/dist/datetime-field.js +24 -19
  94. package/dist/datetime-field.js.map +1 -1
  95. package/dist/dialog.css +176 -172
  96. package/dist/dialog.js +30 -19
  97. package/dist/dialog.js.map +1 -1
  98. package/dist/digit-strip.css +65 -0
  99. package/dist/dropdown.css +65 -0
  100. package/dist/dropdown.js +350 -0
  101. package/dist/dropdown.js.map +1 -0
  102. package/dist/emoji-picker.js +713 -0
  103. package/dist/emoji-picker.js.map +1 -0
  104. package/dist/facebook-feed.css +880 -0
  105. package/dist/facebook-feed.js +697 -0
  106. package/dist/facebook-feed.js.map +1 -0
  107. package/dist/flow-field.css +49 -0
  108. package/dist/flow-field.js +269 -0
  109. package/dist/flow-field.js.map +1 -0
  110. package/dist/glide.js +3 -3
  111. package/dist/icon.css +34 -30
  112. package/dist/input.css +296 -318
  113. package/dist/instagram-feed.css +378 -0
  114. package/dist/instagram-feed.js +272 -0
  115. package/dist/instagram-feed.js.map +1 -0
  116. package/dist/lens.css +119 -0
  117. package/dist/lens.js +307 -0
  118. package/dist/lens.js.map +1 -0
  119. package/dist/mcp.js +379 -184
  120. package/dist/menu-surface.css +127 -0
  121. package/dist/modal.css +11 -7
  122. package/dist/modal.js +24 -17
  123. package/dist/modal.js.map +1 -1
  124. package/dist/morphing-text.css +84 -0
  125. package/dist/morphing-text.js +256 -0
  126. package/dist/morphing-text.js.map +1 -0
  127. package/dist/motion-devtools.css +237 -233
  128. package/dist/motion-devtools.js +7 -6
  129. package/dist/motion-devtools.js.map +1 -1
  130. package/dist/motion-tokens.js +1 -1
  131. package/dist/multi-select.js +20 -17
  132. package/dist/multi-select.js.map +1 -1
  133. package/dist/number-field.js +11 -7
  134. package/dist/number-field.js.map +1 -1
  135. package/dist/odometer.css +58 -59
  136. package/dist/odometer.js +109 -0
  137. package/dist/odometer.js.map +1 -0
  138. package/dist/otp-field.js.map +1 -1
  139. package/dist/overlay.css +24 -20
  140. package/dist/pagination.css +42 -38
  141. package/dist/pagination.js +6 -12
  142. package/dist/pagination.js.map +1 -1
  143. package/dist/popover.css +69 -65
  144. package/dist/popover.js +12 -10
  145. package/dist/radio-group.css +275 -276
  146. package/dist/radio-group.js +70 -95
  147. package/dist/radio-group.js.map +1 -1
  148. package/dist/select.css +291 -386
  149. package/dist/select.js +18 -15
  150. package/dist/select.js.map +1 -1
  151. package/dist/sheet.css +47 -23
  152. package/dist/sheet.js +11 -10
  153. package/dist/status-badge.js +3 -3
  154. package/dist/status-badge.js.map +1 -1
  155. package/dist/styles.css +221 -0
  156. package/dist/support-rail.css +421 -0
  157. package/dist/support-rail.js +243 -0
  158. package/dist/support-rail.js.map +1 -0
  159. package/dist/table.css +333 -323
  160. package/dist/table.js +32 -21
  161. package/dist/table.js.map +1 -1
  162. package/dist/tabs.css +163 -156
  163. package/dist/tabs.js +26 -20
  164. package/dist/tabs.js.map +1 -1
  165. package/dist/tag.css +209 -231
  166. package/dist/tag.js +11 -10
  167. package/dist/tag.js.map +1 -1
  168. package/dist/text-field.js +7 -67
  169. package/dist/text-field.js.map +1 -1
  170. package/dist/textarea.css +205 -211
  171. package/dist/textarea.js +12 -12
  172. package/dist/textarea.js.map +1 -1
  173. package/dist/theme.js +69 -0
  174. package/dist/theme.js.map +1 -0
  175. package/dist/tiktok.css +662 -0
  176. package/dist/tiktok.js +494 -0
  177. package/dist/tiktok.js.map +1 -0
  178. package/dist/time-field.js +6 -6
  179. package/dist/time-field.js.map +1 -1
  180. package/dist/toast.css +237 -233
  181. package/dist/toast.js +43 -47
  182. package/dist/toast.js.map +1 -1
  183. package/dist/toggle-tag.js +1 -1
  184. package/dist/toggle-tag.js.map +1 -1
  185. package/dist/toggle.css +139 -135
  186. package/dist/toggle.js.map +1 -1
  187. package/dist/tooltip.css +79 -78
  188. package/dist/tooltip.js +50 -60
  189. package/dist/tooltip.js.map +1 -1
  190. package/dist/trigger.css +13 -0
  191. package/dist/{alert.d.ts → types/components/composites/alert/Alert.d.ts} +13 -15
  192. package/dist/{date-field.d.ts → types/components/composites/date-picker/DateField.d.ts} +4 -10
  193. package/dist/types/components/composites/date-picker/DateRangeField.d.ts +21 -0
  194. package/dist/{datetime-field.d.ts → types/components/composites/date-picker/DateTimeField.d.ts} +4 -10
  195. package/dist/{time-field.d.ts → types/components/composites/date-picker/TimeField.d.ts} +5 -11
  196. package/dist/types/components/composites/date-picker/calendar-panel.d.ts +16 -0
  197. package/dist/types/components/composites/date-picker/date-utils.d.ts +12 -0
  198. package/dist/types/components/composites/date-picker/field-shell.d.ts +46 -0
  199. package/dist/types/components/composites/date-picker/range-panel.d.ts +24 -0
  200. package/dist/types/components/composites/date-picker/time-core.d.ts +14 -0
  201. package/dist/types/components/composites/date-picker/use-day-focus.d.ts +2 -0
  202. package/dist/{dialog.d.ts → types/components/composites/dialog/Dialog.d.ts} +10 -11
  203. package/dist/types/components/composites/dropdown/Dropdown.d.ts +37 -0
  204. package/dist/types/components/composites/dropdown/menu-panel.d.ts +7 -0
  205. package/dist/types/components/composites/dropdown/types.d.ts +71 -0
  206. package/dist/types/components/composites/emoji-picker/EmojiPickerPanel.d.ts +45 -0
  207. package/dist/types/components/composites/emoji-picker/category-icons.d.ts +9 -0
  208. package/dist/types/components/composites/emoji-picker/data.d.ts +33 -0
  209. package/dist/types/components/composites/emoji-picker/dom.d.ts +19 -0
  210. package/dist/types/components/composites/emoji-picker/getEmojiUrl.d.ts +2 -0
  211. package/dist/types/components/composites/emoji-picker/navigation.d.ts +7 -0
  212. package/dist/types/components/composites/emoji-picker/picker.d.ts +20 -0
  213. package/dist/types/components/composites/emoji-picker/react/category-bar.d.ts +6 -0
  214. package/dist/types/components/composites/emoji-picker/react/useEmojiPicker.d.ts +50 -0
  215. package/dist/types/components/composites/emoji-picker/scaffold.d.ts +8 -0
  216. package/dist/types/components/composites/emoji-picker/search.d.ts +1 -0
  217. package/dist/types/components/composites/emoji-picker/types.d.ts +13 -0
  218. package/dist/{modal.d.ts → types/components/composites/modal/Modal.d.ts} +10 -11
  219. package/dist/{pagination.d.ts → types/components/composites/pagination/Pagination.d.ts} +5 -8
  220. package/dist/{popover.d.ts → types/components/composites/popover/Popover.d.ts} +11 -14
  221. package/dist/{multi-select.d.ts → types/components/composites/select/MultiSelect.d.ts} +12 -11
  222. package/dist/{select.d.ts → types/components/composites/select/Select.d.ts} +16 -14
  223. package/dist/types/components/composites/select/core/index.d.ts +4 -0
  224. package/dist/types/components/composites/select/core/menu.d.ts +13 -0
  225. package/dist/types/components/composites/select/core/panel.d.ts +18 -0
  226. package/dist/types/components/composites/select/core/trigger.d.ts +16 -0
  227. package/dist/{types-SGMShK7R.d.ts → types/components/composites/select/core/types.d.ts} +13 -6
  228. package/dist/types/components/composites/select/core/use-listbox.d.ts +42 -0
  229. package/dist/{sheet.d.ts → types/components/composites/sheet/Sheet.d.ts} +10 -11
  230. package/dist/types/components/composites/sheet/use-sheet-drag.d.ts +13 -0
  231. package/dist/{table.d.ts → types/components/composites/table/Table.d.ts} +12 -12
  232. package/dist/{tabs.d.ts → types/components/composites/tabs/Tabs.d.ts} +13 -13
  233. package/dist/types/components/composites/toast/Toast.d.ts +10 -0
  234. package/dist/{toast-store.d.ts → types/components/composites/toast/toast-store.d.ts} +12 -14
  235. package/dist/{tooltip.d.ts → types/components/composites/tooltip/Tooltip.d.ts} +6 -10
  236. package/dist/types/components/composites/tooltip/tooltip-host.d.ts +1 -0
  237. package/dist/types/components/composites/tooltip/tooltip-store.d.ts +29 -0
  238. package/dist/types/components/compound/support-rail/SupportRail.d.ts +41 -0
  239. package/dist/types/components/dev/MotionDevtools.d.ts +24 -0
  240. package/dist/types/components/dev/slowmo-engine.d.ts +27 -0
  241. package/dist/types/components/expressive/confetti/Confetti.d.ts +43 -0
  242. package/dist/types/components/expressive/facebook-feed/FacebookFeed.d.ts +73 -0
  243. package/dist/types/components/expressive/facebook-feed/chrome.d.ts +30 -0
  244. package/dist/types/components/expressive/facebook-feed/icons.d.ts +21 -0
  245. package/dist/types/components/expressive/facebook-feed/post.d.ts +25 -0
  246. package/dist/types/components/expressive/facebook-feed/reel.d.ts +26 -0
  247. package/dist/types/components/expressive/facebook-feed/story.d.ts +20 -0
  248. package/dist/types/components/expressive/flow-field/FlowField.d.ts +23 -0
  249. package/dist/types/components/expressive/instagram-feed/InstagramFeed.d.ts +59 -0
  250. package/dist/types/components/expressive/lens/Lens.d.ts +23 -0
  251. package/dist/types/components/expressive/morphing-text/MorphingText.d.ts +21 -0
  252. package/dist/types/components/expressive/odometer/Odometer.d.ts +21 -0
  253. package/dist/types/components/expressive/tiktok/TikTok.d.ts +85 -0
  254. package/dist/types/components/expressive/tiktok/glyphs.d.ts +40 -0
  255. package/dist/types/components/expressive/typing-lines/TypingLines.d.ts +25 -0
  256. package/dist/types/components/expressive/weight-field/WeightField.d.ts +19 -0
  257. package/dist/types/components/expressive/youtube/YouTube.d.ts +73 -0
  258. package/dist/types/components/expressive/youtube/format.d.ts +2 -0
  259. package/dist/types/components/expressive/youtube/glyphs.d.ts +16 -0
  260. package/dist/types/components/expressive/youtube/media.d.ts +8 -0
  261. package/dist/types/components/expressive/youtube/post.d.ts +19 -0
  262. package/dist/types/components/expressive/youtube/short.d.ts +18 -0
  263. package/dist/types/components/expressive/youtube/video.d.ts +14 -0
  264. package/dist/types/components/internal/collection/collection.d.ts +19 -0
  265. package/dist/types/components/internal/glass/glint.d.ts +1 -0
  266. package/dist/types/components/internal/hooks/use-controllable.d.ts +1 -0
  267. package/dist/types/components/internal/hooks/use-media-query.d.ts +1 -0
  268. package/dist/types/components/internal/hooks/use-scroll-edges.d.ts +10 -0
  269. package/dist/types/components/internal/hooks/use-typeahead.d.ts +5 -0
  270. package/dist/types/components/internal/icon/Icon.d.ts +33 -0
  271. package/dist/types/components/internal/icon/IconSlot.d.ts +7 -0
  272. package/dist/types/components/internal/menu/menu-row.d.ts +11 -0
  273. package/dist/types/components/internal/overlay/focus.d.ts +8 -0
  274. package/dist/types/components/internal/overlay/layer.d.ts +38 -0
  275. package/dist/types/components/internal/overlay/modal.d.ts +18 -0
  276. package/dist/types/components/internal/overlay/position.d.ts +14 -0
  277. package/dist/types/components/internal/support/types.d.ts +15 -0
  278. package/dist/types/components/internal/utils/activation.d.ts +23 -0
  279. package/dist/types/components/internal/utils/cx.d.ts +1 -0
  280. package/dist/types/components/internal/utils/token-px.d.ts +1 -0
  281. package/dist/{avatar.d.ts → types/components/primitives/avatar/Avatar.d.ts} +10 -12
  282. package/dist/{avatar-group.d.ts → types/components/primitives/avatar/AvatarGroup.d.ts} +7 -9
  283. package/dist/{badge.d.ts → types/components/primitives/badge/Badge.d.ts} +8 -10
  284. package/dist/types/components/primitives/badge/CountBadge.d.ts +8 -0
  285. package/dist/types/components/primitives/badge/StatusBadge.d.ts +15 -0
  286. package/dist/types/components/primitives/badge/digit-strip.d.ts +5 -0
  287. package/dist/{button.d.ts → types/components/primitives/button/Button.d.ts} +6 -8
  288. package/dist/{checkbox.d.ts → types/components/primitives/checkbox/Checkbox.d.ts} +6 -8
  289. package/dist/types/components/primitives/checkbox/check-glyph.d.ts +6 -0
  290. package/dist/{collapse.d.ts → types/components/primitives/collapse/Collapse.d.ts} +12 -13
  291. package/dist/types/components/primitives/collapse/collapse.typecheck.d.ts +2 -0
  292. package/dist/{number-field.d.ts → types/components/primitives/input/NumberField.d.ts} +7 -9
  293. package/dist/{otp-field.d.ts → types/components/primitives/input/OtpField.d.ts} +6 -8
  294. package/dist/{text-field.d.ts → types/components/primitives/input/TextField.d.ts} +7 -9
  295. package/dist/types/components/primitives/input/field-chrome.d.ts +45 -0
  296. package/dist/{radio-group.d.ts → types/components/primitives/radio-group/RadioGroup.d.ts} +8 -10
  297. package/dist/{tag.d.ts → types/components/primitives/tag/Tag.d.ts} +9 -12
  298. package/dist/{toggle-tag.d.ts → types/components/primitives/tag/ToggleTag.d.ts} +7 -8
  299. package/dist/{textarea.d.ts → types/components/primitives/textarea/Textarea.d.ts} +7 -9
  300. package/dist/{toggle.d.ts → types/components/primitives/toggle/Toggle.d.ts} +6 -8
  301. package/dist/{dom-props-C0jrllBw.d.ts → types/dom-props.d.ts} +1 -3
  302. package/dist/types/engine/animate.d.ts +30 -0
  303. package/dist/types/engine/drag.d.ts +17 -0
  304. package/dist/types/engine/ease.d.ts +15 -0
  305. package/dist/types/engine/flip.d.ts +18 -0
  306. package/dist/types/engine/index.d.ts +4 -0
  307. package/dist/types/engine/loop.d.ts +9 -0
  308. package/dist/types/motion/element.d.ts +17 -0
  309. package/dist/types/motion/flip.d.ts +4 -0
  310. package/dist/types/motion/glide.d.ts +11 -0
  311. package/dist/types/motion/motion-timing.d.ts +16 -0
  312. package/dist/types/motion/presence-context.d.ts +11 -0
  313. package/dist/types/motion/presence.d.ts +12 -0
  314. package/dist/types/motion/presets.d.ts +6 -0
  315. package/dist/{timing-7JA_zQHP.d.ts → types/motion/timing.d.ts} +9 -9
  316. package/dist/types/motion/use-motion.d.ts +17 -0
  317. package/dist/types/tokens/component-styles.generated.d.ts +262 -0
  318. package/dist/{motion-scale-Canq4stZ.d.ts → types/tokens/motion-scale.d.ts} +4 -4
  319. package/dist/{motion-tokens.d.ts → types/tokens/motion-tokens.d.ts} +9 -9
  320. package/dist/types/tokens/theme-tokens.generated.d.ts +1249 -0
  321. package/dist/types/tokens/theme.d.ts +12 -0
  322. package/dist/typing-lines.css +92 -0
  323. package/dist/typing-lines.js +139 -0
  324. package/dist/typing-lines.js.map +1 -0
  325. package/dist/weight-field.css +84 -0
  326. package/dist/weight-field.js +17 -0
  327. package/dist/weight-field.js.map +1 -0
  328. package/dist/youtube.css +611 -0
  329. package/dist/youtube.js +814 -0
  330. package/dist/youtube.js.map +1 -0
  331. package/package.json +155 -49
  332. package/skills/zyncat-ui/SKILL.md +95 -0
  333. package/skills/zyncat-ui/references/components.md +85 -0
  334. package/skills/zyncat-ui/references/recipes.md +171 -0
  335. package/skills/zyncat-ui/references/theming.md +83 -0
  336. package/src/components/composites/alert/Alert.tsx +13 -11
  337. package/src/components/composites/alert/Alert.usage.md +15 -0
  338. package/src/components/composites/alert/alert.css +126 -121
  339. package/src/components/composites/date-picker/DateField.tsx +7 -2
  340. package/src/components/composites/date-picker/DateField.usage.md +10 -0
  341. package/src/components/composites/date-picker/DateRangeField.tsx +18 -16
  342. package/src/components/composites/date-picker/DateRangeField.usage.md +10 -0
  343. package/src/components/composites/date-picker/DateTimeField.tsx +10 -5
  344. package/src/components/composites/date-picker/DateTimeField.usage.md +12 -0
  345. package/src/components/composites/date-picker/TimeField.tsx +3 -1
  346. package/src/components/composites/date-picker/TimeField.usage.md +12 -0
  347. package/src/components/composites/date-picker/calendar-panel.tsx +15 -10
  348. package/src/components/composites/date-picker/date-picker.css +563 -559
  349. package/src/components/composites/date-picker/field-shell.tsx +9 -3
  350. package/src/components/composites/date-picker/range-panel.tsx +23 -8
  351. package/src/components/composites/date-picker/time-core.tsx +2 -0
  352. package/src/components/composites/dialog/Dialog.tsx +30 -15
  353. package/src/components/composites/dialog/Dialog.usage.md +17 -0
  354. package/src/components/composites/dialog/dialog.css +176 -172
  355. package/src/components/composites/dropdown/Dropdown.tsx +184 -0
  356. package/src/components/composites/dropdown/Dropdown.usage.md +19 -0
  357. package/src/components/composites/dropdown/dropdown.css +65 -0
  358. package/src/components/composites/dropdown/menu-panel.tsx +255 -0
  359. package/src/components/composites/dropdown/types.ts +95 -0
  360. package/src/components/composites/emoji-picker/EmojiPickerPanel.tsx +153 -0
  361. package/src/components/composites/emoji-picker/EmojiPickerPanel.usage.md +26 -0
  362. package/src/components/composites/emoji-picker/category-icons.ts +29 -0
  363. package/src/components/composites/emoji-picker/data.ts +83 -0
  364. package/src/components/composites/emoji-picker/dom.ts +79 -0
  365. package/src/components/composites/emoji-picker/getEmojiUrl.ts +17 -0
  366. package/src/components/composites/emoji-picker/navigation.ts +86 -0
  367. package/src/components/composites/emoji-picker/picker.ts +169 -0
  368. package/src/components/composites/emoji-picker/react/category-bar.tsx +77 -0
  369. package/src/components/composites/emoji-picker/react/useEmojiPicker.ts +139 -0
  370. package/src/components/composites/emoji-picker/scaffold.ts +74 -0
  371. package/src/components/composites/emoji-picker/search.ts +79 -0
  372. package/src/components/composites/emoji-picker/styles.css +221 -0
  373. package/src/components/composites/emoji-picker/types.ts +14 -0
  374. package/src/components/composites/modal/Modal.tsx +24 -13
  375. package/src/components/composites/modal/Modal.usage.md +24 -0
  376. package/src/components/composites/modal/modal.css +11 -7
  377. package/src/components/composites/pagination/Pagination.tsx +6 -11
  378. package/src/components/composites/pagination/Pagination.usage.md +12 -0
  379. package/src/components/composites/pagination/pagination.css +42 -38
  380. package/src/components/composites/popover/Popover.tsx +22 -7
  381. package/src/components/composites/popover/Popover.usage.md +15 -0
  382. package/src/components/composites/popover/popover.css +69 -65
  383. package/src/components/composites/select/MultiSelect.tsx +13 -5
  384. package/src/components/composites/select/MultiSelect.usage.md +12 -0
  385. package/src/components/composites/select/Select.tsx +23 -7
  386. package/src/components/composites/select/Select.usage.md +20 -0
  387. package/src/components/composites/select/core/index.ts +1 -1
  388. package/src/components/composites/select/core/menu.tsx +8 -6
  389. package/src/components/composites/select/core/panel.tsx +25 -26
  390. package/src/components/composites/select/core/trigger.tsx +36 -24
  391. package/src/components/composites/select/core/types.ts +17 -15
  392. package/src/components/composites/select/core/use-listbox.ts +22 -21
  393. package/src/components/composites/select/select.css +291 -386
  394. package/src/components/composites/sheet/Sheet.tsx +28 -18
  395. package/src/components/composites/sheet/Sheet.usage.md +15 -0
  396. package/src/components/composites/sheet/sheet.css +47 -23
  397. package/src/components/composites/sheet/use-sheet-drag.ts +19 -15
  398. package/src/components/composites/table/Table.tsx +17 -6
  399. package/src/components/composites/table/Table.usage.md +19 -0
  400. package/src/components/composites/table/table.css +333 -323
  401. package/src/components/composites/tabs/Tabs.tsx +31 -23
  402. package/src/components/composites/tabs/Tabs.usage.md +13 -0
  403. package/src/components/composites/tabs/tabs.css +163 -156
  404. package/src/components/composites/toast/Toast.tsx +48 -51
  405. package/src/components/composites/toast/Toast.usage.md +23 -0
  406. package/src/components/composites/toast/toast-store.usage.md +16 -0
  407. package/src/components/composites/toast/toast.css +237 -233
  408. package/src/components/composites/tooltip/Tooltip.tsx +13 -8
  409. package/src/components/composites/tooltip/Tooltip.usage.md +14 -0
  410. package/src/components/composites/tooltip/tooltip-host.tsx +29 -61
  411. package/src/components/composites/tooltip/tooltip-store.ts +10 -0
  412. package/src/components/composites/tooltip/tooltip.css +79 -78
  413. package/src/components/compound/support-rail/SupportRail.tsx +343 -0
  414. package/src/components/compound/support-rail/SupportRail.usage.md +18 -0
  415. package/src/components/compound/support-rail/support-rail.css +421 -0
  416. package/src/components/dev/MotionDevtools.tsx +3 -1
  417. package/src/components/dev/MotionDevtools.usage.md +16 -0
  418. package/src/components/dev/motion-devtools.css +237 -233
  419. package/src/components/expressive/confetti/Confetti.tsx +727 -0
  420. package/src/components/expressive/confetti/Confetti.usage.md +18 -0
  421. package/src/components/expressive/confetti/confetti.css +45 -0
  422. package/src/components/expressive/facebook-feed/FacebookFeed.tsx +200 -0
  423. package/src/components/expressive/facebook-feed/FacebookFeed.usage.md +18 -0
  424. package/src/components/expressive/facebook-feed/chrome.tsx +120 -0
  425. package/src/components/expressive/facebook-feed/facebook-feed.css +880 -0
  426. package/src/components/expressive/facebook-feed/icons.tsx +145 -0
  427. package/src/components/expressive/facebook-feed/post.tsx +213 -0
  428. package/src/components/expressive/facebook-feed/reel.tsx +199 -0
  429. package/src/components/expressive/facebook-feed/story.tsx +132 -0
  430. package/src/components/expressive/flow-field/FlowField.tsx +348 -0
  431. package/src/components/expressive/flow-field/FlowField.usage.md +19 -0
  432. package/src/components/expressive/flow-field/flow-field.css +49 -0
  433. package/src/components/expressive/instagram-feed/InstagramFeed.tsx +374 -0
  434. package/src/components/expressive/instagram-feed/InstagramFeed.usage.md +18 -0
  435. package/src/components/expressive/instagram-feed/instagram-feed.css +378 -0
  436. package/src/components/expressive/lens/Lens.tsx +415 -0
  437. package/src/components/expressive/lens/Lens.usage.md +20 -0
  438. package/src/components/expressive/lens/lens.css +119 -0
  439. package/src/components/expressive/morphing-text/MorphingText.tsx +328 -0
  440. package/src/components/expressive/morphing-text/MorphingText.usage.md +19 -0
  441. package/src/components/expressive/morphing-text/morphing-text.css +84 -0
  442. package/src/components/expressive/odometer/Odometer.tsx +158 -0
  443. package/src/components/expressive/odometer/Odometer.usage.md +17 -0
  444. package/src/components/expressive/odometer/odometer.css +61 -0
  445. package/src/components/expressive/tiktok/TikTok.tsx +542 -0
  446. package/src/components/expressive/tiktok/TikTok.usage.md +17 -0
  447. package/src/components/expressive/tiktok/glyphs.tsx +163 -0
  448. package/src/components/expressive/tiktok/tiktok.css +662 -0
  449. package/src/components/expressive/typing-lines/TypingLines.tsx +0 -0
  450. package/src/components/expressive/typing-lines/TypingLines.usage.md +17 -0
  451. package/src/components/expressive/typing-lines/typing-lines.css +92 -0
  452. package/src/components/expressive/weight-field/WeightField.tsx +41 -0
  453. package/src/components/expressive/weight-field/WeightField.usage.md +20 -0
  454. package/src/components/expressive/weight-field/weight-field.css +84 -0
  455. package/src/components/expressive/youtube/YouTube.tsx +192 -0
  456. package/src/components/expressive/youtube/YouTube.usage.md +18 -0
  457. package/src/components/expressive/youtube/format.ts +22 -0
  458. package/src/components/expressive/youtube/glyphs.tsx +235 -0
  459. package/src/components/expressive/youtube/media.tsx +18 -0
  460. package/src/components/expressive/youtube/post.tsx +282 -0
  461. package/src/components/expressive/youtube/short.tsx +212 -0
  462. package/src/components/expressive/youtube/video.tsx +75 -0
  463. package/src/components/expressive/youtube/youtube.css +611 -0
  464. package/src/components/internal/collection/collection.ts +44 -0
  465. package/src/components/internal/glass/glass.css +88 -84
  466. package/src/components/internal/hooks/use-media-query.ts +20 -0
  467. package/src/components/internal/hooks/use-typeahead.ts +28 -0
  468. package/src/components/internal/icon/Icon.tsx +2 -0
  469. package/src/components/internal/icon/IconSlot.tsx +2 -0
  470. package/src/components/internal/icon/icon.css +34 -30
  471. package/src/components/internal/menu/menu-row.tsx +34 -0
  472. package/src/components/internal/menu/menu-surface.css +127 -0
  473. package/src/components/internal/overlay/focus.ts +26 -10
  474. package/src/components/internal/overlay/layer.tsx +50 -19
  475. package/src/components/internal/overlay/modal.tsx +14 -12
  476. package/src/components/internal/overlay/overlay.css +24 -20
  477. package/src/components/internal/overlay/position.ts +19 -9
  478. package/src/components/internal/overlay/trigger.css +13 -0
  479. package/src/components/internal/support/types.ts +16 -0
  480. package/src/components/internal/utils/activation.ts +78 -0
  481. package/src/components/primitives/avatar/Avatar.tsx +2 -0
  482. package/src/components/primitives/avatar/Avatar.usage.md +12 -0
  483. package/src/components/primitives/avatar/AvatarGroup.tsx +3 -1
  484. package/src/components/primitives/avatar/AvatarGroup.usage.md +15 -0
  485. package/src/components/primitives/avatar/avatar.css +179 -174
  486. package/src/components/primitives/badge/Badge.tsx +3 -1
  487. package/src/components/primitives/badge/Badge.usage.md +14 -0
  488. package/src/components/primitives/badge/CountBadge.tsx +2 -2
  489. package/src/components/primitives/badge/CountBadge.usage.md +13 -0
  490. package/src/components/primitives/badge/StatusBadge.tsx +3 -1
  491. package/src/components/primitives/badge/StatusBadge.usage.md +14 -0
  492. package/src/components/primitives/badge/badge.css +166 -160
  493. package/src/components/primitives/badge/digit-strip.css +65 -0
  494. package/src/components/primitives/badge/{odometer.tsx → digit-strip.tsx} +3 -3
  495. package/src/components/primitives/button/Button.tsx +2 -0
  496. package/src/components/primitives/button/Button.usage.md +14 -0
  497. package/src/components/primitives/button/button.css +272 -246
  498. package/src/components/primitives/checkbox/Checkbox.tsx +3 -1
  499. package/src/components/primitives/checkbox/Checkbox.usage.md +12 -0
  500. package/src/components/primitives/checkbox/check-glyph.tsx +1 -0
  501. package/src/components/primitives/checkbox/checkbox.css +158 -153
  502. package/src/components/primitives/collapse/Collapse.tsx +3 -1
  503. package/src/components/primitives/collapse/Collapse.usage.md +17 -0
  504. package/src/components/primitives/collapse/collapse.css +70 -61
  505. package/src/components/primitives/collapse/collapse.typecheck.tsx +2 -0
  506. package/src/components/primitives/input/NumberField.tsx +18 -5
  507. package/src/components/primitives/input/NumberField.usage.md +12 -0
  508. package/src/components/primitives/input/OtpField.tsx +2 -0
  509. package/src/components/primitives/input/OtpField.usage.md +12 -0
  510. package/src/components/primitives/input/TextField.tsx +16 -4
  511. package/src/components/primitives/input/TextField.usage.md +13 -0
  512. package/src/components/primitives/input/field-chrome.tsx +11 -2
  513. package/src/components/primitives/input/input.css +296 -318
  514. package/src/components/primitives/radio-group/RadioGroup.tsx +20 -44
  515. package/src/components/primitives/radio-group/RadioGroup.usage.md +13 -0
  516. package/src/components/primitives/radio-group/radio-group.css +275 -276
  517. package/src/components/primitives/tag/Tag.tsx +10 -6
  518. package/src/components/primitives/tag/Tag.usage.md +14 -0
  519. package/src/components/primitives/tag/ToggleTag.tsx +4 -2
  520. package/src/components/primitives/tag/ToggleTag.usage.md +14 -0
  521. package/src/components/primitives/tag/tag.css +209 -231
  522. package/src/components/primitives/textarea/Textarea.tsx +17 -7
  523. package/src/components/primitives/textarea/Textarea.usage.md +12 -0
  524. package/src/components/primitives/textarea/textarea.css +205 -211
  525. package/src/components/primitives/toggle/Toggle.tsx +3 -1
  526. package/src/components/primitives/toggle/Toggle.usage.md +12 -0
  527. package/src/components/primitives/toggle/toggle.css +139 -135
  528. package/src/engine/animate.ts +40 -13
  529. package/src/engine/ease.ts +1 -0
  530. package/src/engine/flip.ts +32 -15
  531. package/src/engine/index.ts +2 -1
  532. package/src/engine/loop.ts +97 -0
  533. package/src/mcp/server.ts +315 -221
  534. package/src/motion/element.tsx +1 -0
  535. package/src/motion/flip.ts +29 -10
  536. package/src/motion/glide.tsx +11 -14
  537. package/src/motion/glide.usage.md +15 -0
  538. package/src/motion/motion-timing.ts +3 -3
  539. package/src/motion/presence.tsx +38 -21
  540. package/src/motion/presets.ts +13 -0
  541. package/src/motion/timing.ts +1 -0
  542. package/src/motion/use-motion.ts +16 -3
  543. package/src/styles.css +5 -0
  544. package/src/tokens/avatar.css +20 -16
  545. package/src/tokens/color.css +67 -56
  546. package/src/tokens/component-styles.generated.ts +270 -0
  547. package/src/tokens/elevation.css +28 -17
  548. package/src/tokens/fonts.css +1 -1
  549. package/src/tokens/glass.css +19 -15
  550. package/src/tokens/icons.css +8 -4
  551. package/src/tokens/layers.css +9 -4
  552. package/src/tokens/motion-scale.ts +4 -0
  553. package/src/tokens/motion-tokens.ts +42 -12
  554. package/src/tokens/motion-tokens.usage.md +16 -0
  555. package/src/tokens/motion.css +63 -45
  556. package/src/tokens/radius.css +12 -8
  557. package/src/tokens/semantic.css +62 -54
  558. package/src/tokens/spacing.css +25 -21
  559. package/src/tokens/theme-tokens.generated.ts +1278 -0
  560. package/src/tokens/theme.tsx +83 -0
  561. package/src/tokens/theme.usage.md +36 -0
  562. package/src/tokens/typography.css +53 -49
  563. package/dist/chunk-2ERBBFZS.js.map +0 -1
  564. package/dist/chunk-2F5PITAO.js.map +0 -1
  565. package/dist/chunk-2QWJ6FAX.js.map +0 -1
  566. package/dist/chunk-356HZMT4.js.map +0 -1
  567. package/dist/chunk-62P3KD57.js.map +0 -1
  568. package/dist/chunk-7SZCJ7WI.js.map +0 -1
  569. package/dist/chunk-CONSWNIV.js.map +0 -1
  570. package/dist/chunk-FTOAUJL5.js.map +0 -1
  571. package/dist/chunk-I4XQ4PV2.js.map +0 -1
  572. package/dist/chunk-K5X2GCXU.js.map +0 -1
  573. package/dist/chunk-NEF5XAHG.js.map +0 -1
  574. package/dist/chunk-NNXJCLTV.js.map +0 -1
  575. package/dist/chunk-OMHQ4U4J.js.map +0 -1
  576. package/dist/chunk-PMECHR3A.js.map +0 -1
  577. package/dist/chunk-QDK66S4G.js.map +0 -1
  578. package/dist/chunk-RCONNA7I.js.map +0 -1
  579. package/dist/chunk-S5ZTZANS.js.map +0 -1
  580. package/dist/chunk-UXONUUPI.js.map +0 -1
  581. package/dist/chunk-VTJTGVZZ.js.map +0 -1
  582. package/dist/chunk-WM5J5TDI.js.map +0 -1
  583. package/dist/chunk-XWUWYSCT.js.map +0 -1
  584. package/dist/chunk-Y7AJQVWJ.js.map +0 -1
  585. package/dist/chunk-YGCVWGUG.js.map +0 -1
  586. package/dist/chunk-YGGCQNNU.js.map +0 -1
  587. package/dist/chunk-ZCOUPPTI.js.map +0 -1
  588. package/dist/count-badge.d.ts +0 -13
  589. package/dist/date-range-field.d.ts +0 -33
  590. package/dist/field-chrome-CMPOQSLs.d.ts +0 -28
  591. package/dist/field-shell-Cuda-feL.d.ts +0 -24
  592. package/dist/glide.d.ts +0 -15
  593. package/dist/motion-devtools.d.ts +0 -51
  594. package/dist/status-badge.d.ts +0 -19
  595. package/dist/toast.d.ts +0 -12
  596. package/llms.txt +0 -220
  597. package/src/components/primitives/badge/odometer.css +0 -62
package/README.md CHANGED
@@ -3,17 +3,46 @@
3
3
  A premium React design system - modern CSS + a small, closed token vocabulary, applied
4
4
  consistently. Restraint, calm motion, no Tailwind, no CSS-in-JS, no UI libraries.
5
5
 
6
- **React 19 - TypeScript - ships compiled ESM + types.** Import the whole library or a single
7
- component; link one base stylesheet - each component loads its own CSS automatically.
6
+ **React 19 - TypeScript - ships compiled ESM + types.** Import one component per subpath;
7
+ link one base stylesheet - each component loads its own CSS automatically.
8
+
9
+ ## What this is, and who it is for
10
+
11
+ Zyncat UI is built first for my own applications. Every component exists because a real
12
+ product needed it, and the API is the one that made that product simpler - not the one that
13
+ covers the widest set of hypothetical uses. That it also serves as a portfolio piece is a
14
+ side effect, not the goal.
15
+
16
+ That focus is the point. The token vocabulary stays small because one person has to hold it
17
+ in their head; the component set stays narrow because every component is a permanent
18
+ maintenance surface; the motion engine is small because the alternative was a dependency
19
+ with a hundred features I would not use. A design system built to please everyone ends up
20
+ with a settings panel instead of a point of view.
21
+
22
+ **On licensing and openness.** The code here is MIT-licensed and you are welcome to use it.
23
+ It is not, however, run as a community open-source project: there is no public roadmap, no
24
+ support commitment, no issue triage and no contribution process, and none of those are
25
+ planned right now. Development is driven by what my own applications need. Parts of it may
26
+ later move to an open-core or commercial arrangement - that decision has not been made. Use
27
+ it with those expectations, and pin a version.
8
28
 
9
29
  ## Install
10
30
 
31
+ One command, run inside your React project - installing the package is part of it, so there is no
32
+ separate `pnpm add` step:
33
+
11
34
  ```bash
12
- pnpm add @zyncat/ui
13
- # peers (you likely already have them):
14
- pnpm add react react-dom
35
+ pnpm dlx zyncat-ui init
36
+ # or: npx zyncat-ui init · yarn dlx zyncat-ui init · bunx zyncat-ui init
15
37
  ```
16
38
 
39
+ It installs `@zyncat/ui` with your package manager (and React 19, if the project needs it), imports
40
+ the base stylesheet at your app root, installs the agent skill into `.claude/skills/`, registers the
41
+ bundled MCP server in `.mcp.json`, and scaffolds a typed `zyncat.theme.ts`. Every step is idempotent
42
+ and printed as it lands - re-run the command after upgrading to refresh the skill and theme types.
43
+ Non-interactive shells get plain logs and no prompts; pass `--yes` to accept every default and
44
+ `--pm <pnpm|npm|yarn|bun>` to pin the package manager.
45
+
17
46
  | Peer | Range | Used for |
18
47
  | --------------------- | ----- | -------------------------------------------------------------------- |
19
48
  | `react` / `react-dom` | `^19` | components; `createRoot`/`createPortal` for imperative toast/tooltip |
@@ -28,30 +57,58 @@ No bundler config and no `transpilePackages` - the package ships built ESM with
28
57
  directives intact, so Next.js App Router boundaries just work.
29
58
 
30
59
  ```tsx
31
- import { Button, toast } from '@zyncat/ui';
32
- import '@zyncat/ui/styles.css'; // base layer - link once, at the app root
60
+ import { Button } from '@zyncat/ui/button';
61
+ import { toast } from '@zyncat/ui/toast-store';
62
+
63
+ import '@zyncat/ui/styles.css'; // base layer - init adds this at the app root for you
33
64
  ```
34
65
 
35
66
  `styles.css` is the **base layer only** - fonts, design tokens (the `:root` custom
36
- properties) and the shared `glass` utility. Link it exactly once at the app root.
67
+ properties) and the shared `glass` utility. It is linked exactly once at the app root -
68
+ `init` inserts the import above your own stylesheets so yours keep winning the cascade.
37
69
 
38
70
  You never import per-component CSS: every component imports its own stylesheet, so your
39
71
  bundler code-splits and lazy-loads it with the component. Import `@zyncat/ui/dialog` and
40
- only `dialog.css` ships (plus the `overlay`/`icon` styles it reuses, deduped) - not the
41
- other 30 components' CSS.
72
+ only `dialog.css` ships (plus the `overlay`/`icon` styles it reuses, deduped) - not every
73
+ other component's CSS.
74
+
75
+ ## Theme it
42
76
 
43
- ### Import a single component
77
+ ```tsx
78
+ import { defineTheme, ZyncatTheme } from '@zyncat/ui/theme';
79
+
80
+ const base = defineTheme({
81
+ color: { accent: 'oklch(0.58 0.19 292)', accentHover: 'oklch(0.5 0.19 292)' },
82
+ radius: { radiusMd: '0.5rem' },
83
+ components: { odometer: { accent: 'var(--warning)' } },
84
+ });
85
+ const dark = defineTheme({ color: { bgApp: 'oklch(0.19 0.008 198)', textBody: 'oklch(0.92 0.004 198)' } });
86
+
87
+ // once, at the app root
88
+ <ZyncatTheme theme={{ base, dark }} />;
89
+ ```
90
+
91
+ Every token is a typed key, grouped by what it does: hover shows the default, a typo is a
92
+ compile error, and values take any CSS. `base` lands on `:root` and every other key becomes a
93
+ `[data-theme='<key>']` block, so switching themes - globally or for one subtree - is setting
94
+ that attribute. The types are generated from the token stylesheets, so upgrading the package
95
+ surfaces new tokens rather than drifting from them.
44
96
 
45
- Every component is also a subpath export, so you can pull just one:
97
+ `ZyncatTheme` is a plain component that renders a `<style>` element: it server-renders (no
98
+ flash, no client hook), needs no PostCSS plugin, bundler plugin or build step, and adds about
99
+ a kilobyte. Durations you repoint keep their `prefers-reduced-motion` collapse automatically.
100
+
101
+ ### One subpath per component
46
102
 
47
103
  ```tsx
48
104
  import { Button } from '@zyncat/ui/button';
49
105
  import { DateField } from '@zyncat/ui/date-field';
50
106
  ```
51
107
 
52
- The barrel is side-effect-free and tree-shakes, so `import { Button } from '@zyncat/ui'` is
53
- equally lean in a bundler - subpaths help in non-bundled or explicit setups. CSS follows the
54
- same module graph: components you don't use drop their stylesheets too.
108
+ **There is no barrel entry, deliberately.** `import from '@zyncat/ui'` does not resolve.
109
+ A barrel makes it possible for one import to pull in modules - and stylesheets - the app
110
+ never asked for, and no amount of tree-shaking makes that guarantee hold across every
111
+ bundler and every non-bundled setup. Subpaths make it structural instead.
55
112
 
56
113
  ## Components
57
114
 
@@ -61,39 +118,56 @@ same module graph: components you don't use drop their stylesheets too.
61
118
  | Forms | TextField, NumberField, OtpField, Textarea, Checkbox, Toggle, RadioGroup, Select, MultiSelect |
62
119
  | Data | Avatar, AvatarGroup, Tag, ToggleTag, Table, Pagination |
63
120
  | Date, time & tabs | DateField, DateTimeField, DateRangeField, TimeField, Tabs |
64
- | Overlays & feedback | Alert, Toast, Tooltip, Dialog, Popover, Sheet |
121
+ | Overlays & feedback | Alert, Toast, Tooltip, Dialog, Popover, Sheet, Dropdown, EmojiPickerPanel |
122
+ | Expressive | Odometer, TypingLines, Lens, MorphingText, WeightField, FlowField, Confetti |
123
+ | Compound | SupportRail |
124
+ | Replicas | FacebookFeed, InstagramFeed, TikTok, YouTube |
125
+ | Motion & dev | Glide / GlidePill, MotionDevtools |
126
+
127
+ Each is a named export from its own subpath (`@zyncat/ui/<kebab-name>`). Props are documented
128
+ inline in the types; each component also ships a usage doc (`*.usage.md` beside its source) with
129
+ a maintainer-written example.
65
130
 
66
- Each is a named export from the barrel and a subpath (`@zyncat/ui/<kebab-name>`). Props are
67
- documented inline in the types; see [`llms.txt`](./llms.txt) for per-component examples.
131
+ The **Replicas** row is the exception to the token rule: those four reproduce a real platform
132
+ surface, so their metrics are pinned constants and your theme deliberately cannot move them.
133
+ Everything else answers to the token vocabulary.
68
134
 
69
135
  ## For AI coding agents
70
136
 
71
- **MCP server (preferred).** The package bundles a zero-dependency MCP server (stdio) so agents
72
- query the API surface instead of grepping `node_modules`: `list_components` (index + conventions),
73
- `get_component` (usage docs + complete prop types, shared type chunks inlined), `search_api`
74
- (which component owns a prop/type/token), `get_tokens` (the token vocabulary with real values).
75
- Register it in the consuming project - for Claude Code, `.mcp.json` at the project root:
137
+ The same `init` from [Install](#install) is the whole agent setup: it installs the `zyncat-ui`
138
+ agent skill into `./.claude/skills/` (the component map, picker tables, recipes, theming guide -
139
+ the knowledge that should sit in the agent's context) and registers the bundled MCP server in
140
+ `./.mcp.json` (the live truth). Re-run it after upgrading the package so the skill matches the
141
+ installed version.
142
+
143
+ **The MCP server** is zero-dependency (stdio), also exposed as the `zyncat-ui-mcp` bin, and works
144
+ with any MCP client:
76
145
 
77
146
  ```json
78
147
  { "mcpServers": { "zyncat-ui": { "command": "node", "args": ["./node_modules/@zyncat/ui/dist/mcp.js"] } } }
79
148
  ```
80
149
 
81
- Any MCP client works (also exposed as the `zyncat-ui-mcp` bin). The server reads the installed
82
- package's `llms.txt`, `dist/*.d.ts` and `src/tokens/*.css` at call time, so answers always match
83
- the installed version.
150
+ Three tools: `get_component` (batch - the full current API for every component a change touches:
151
+ maintainer usage doc, live docs URL, complete prop types with the shared type chunks inlined;
152
+ an unknown name returns the whole catalog), `search_api` (ranked keyword search across usage
153
+ docs, prop types and tokens), `get_tokens` (the token vocabulary with real values plus the
154
+ theming levels). The server reads the installed package's usage docs, `dist/types/` declarations
155
+ and `src/tokens/*.css` at call time, so answers always match the installed version.
84
156
 
85
157
  Without MCP, the same contract is readable directly:
86
158
 
87
- - **`node_modules/@zyncat/ui/dist/*.d.ts`** - every component's props carry inline TSDoc. This is
88
- the machine-readable source of truth (e.g. `dist/button.d.ts` fully describes `ButtonProps`).
89
- - **`llms.txt`** (package root) - a compact, per-component index: purpose - import - a minimal
90
- example. Cheaper to scan than every `.d.ts`.
159
+ - **Declaration files under `node_modules/@zyncat/ui/dist/types/`** - every component's props carry
160
+ inline TSDoc, and this is the machine-readable source of truth. Each subpath's `types` entry in
161
+ `package.json` points straight at its file: `./button` resolves to
162
+ `dist/types/components/primitives/button/Button.d.ts`, which fully describes `ButtonProps`.
163
+ - **Usage docs** - `node_modules/@zyncat/ui/src/**/*.usage.md`, one per component: purpose, when
164
+ to pick it, a verified example, the live docs URL.
91
165
  - This README.
92
166
 
93
167
  ## Copy-paste instead
94
168
 
95
169
  The tarball also ships `src/`, so you can lift a component straight from
96
- `node_modules/@zyncat/ui/src/components/<name>/` into your project. Components aren't fully
170
+ `node_modules/@zyncat/ui/src/components/<tier>/<name>/` into your project. Components aren't fully
97
171
  self-contained - they share `src/tokens/`, the `motion-tokens` bridge, the internal `icon/`, and a
98
172
  few `*-core` helpers - so copy those alongside. (A shadcn-style registry/CLI could automate this
99
173
  later.)
@@ -108,11 +182,14 @@ your own node - any `ReactNode` (e.g. an `@phosphor-icons/react` element, if you
108
182
  ## What's inside
109
183
 
110
184
  ```
111
- src/ source (also shipped, for copy-paste)
112
- -- index.ts public barrel
185
+ src/ source (also shipped, for reading)
113
186
  -- styles.css base layer: fonts + tokens + glass (link once)
114
- -- tokens/ CSS custom properties + motion-tokens.ts (JS and CSS motion bridge)
115
- -- components/ <domain>/Name.tsx + name.css (each Tsx imports its own CSS -> lazy-loaded)
187
+ -- tokens/ CSS custom properties + the TypeScript readers that mirror them
188
+ -- engine/ the WAAPI motion engine
189
+ -- motion/ the React motion layer: Presence, Motion, presets
190
+ -- components/ primitives/ composites/ compound/ expressive/ internal/ - each Tsx imports its own CSS
191
+ -- mcp/ the bundled MCP server
192
+ skills/ the agent skill `npx zyncat-ui init` installs into a consumer project
116
193
  dist/ compiled ESM + .d.ts - what you import
117
194
  ```
118
195
 
@@ -120,14 +197,32 @@ dist/ compiled ESM + .d.ts - what you import
120
197
 
121
198
  - **Fonts.** `src/tokens/fonts.css` pulls Geist + Geist Mono from Google Fonts via a remote
122
199
  `@import`. Self-host the families to drop the render-blocking network hop.
123
- - **Styling is token-driven.** Re-skin by overriding the CSS custom properties in your own
124
- stylesheet loaded after `@zyncat/ui/styles.css` - never fork the source.
200
+ - **Four ways to override, and you never fork the source.** Load your stylesheet after
201
+ `@zyncat/ui/styles.css`, then take the lowest level that works. **0** - every shipped rule
202
+ sits in `@layer zyncat.components`, and unlayered CSS beats every layer at any specificity,
203
+ so `.btn { border-radius: 0 }` just lands. **1** - repoint the tokens to retheme the system,
204
+ in TypeScript with `defineTheme` (below) or on `:root` in your own CSS; the motion engine
205
+ reads the same values, so animation retimes with them.
206
+ **2** - retune one expressive or compound component through its `--<component>-*` properties.
207
+ **3** - `className` and `style` per instance (`htmlProps` for an overlay's panel).
208
+ [`skills/zyncat-ui/references/theming.md`](./skills/zyncat-ui/references/theming.md) has the
209
+ full vocabulary, and `get_tokens` prints it with live values.
210
+ - **Reduced motion is handled at the token layer.** Every `--duration-*` collapses to 1ms under
211
+ `prefers-reduced-motion`, so components need no per-component media query - but that collapse
212
+ targets `:root`, so repoint durations there and not on a nested scope.
125
213
 
126
214
  ## Develop
127
215
 
128
216
  ```bash
129
217
  pnpm install
130
- pnpm build # tsup - dist/ (ESM + .d.ts)
131
- pnpm typecheck # tsc --noEmit
132
- pnpm format # prettier --write
218
+ pnpm build # tsup - dist/ (ESM + .d.ts)
219
+ pnpm typecheck # tsc --noEmit
220
+ pnpm format # prettier --write
221
+ pnpm check:css # every rendered class is reachable from its own module
222
+ pnpm check:usage # every subpath has a usage doc, and its example props are real
223
+ pnpm check:authoring # docs/authoring + CLAUDE.md still match the code
224
+ pnpm verify # every gate above, in order
133
225
  ```
226
+
227
+ Contributing to this repo? Start at [`CLAUDE.md`](CLAUDE.md), then
228
+ [`docs/authoring/`](docs/authoring/).
package/dist/alert.css CHANGED
@@ -1,132 +1,137 @@
1
- /* alert.css - the persistent in-flow status message: a lit tinted pane per tone. */
1
+ @layer zyncat.tokens, zyncat.components;
2
2
 
3
- .alert-shell {
4
- overflow: hidden;
5
- }
3
+ @layer zyncat.components {
4
+ /* alert.css - the persistent in-flow status message: a lit tinted pane per tone. */
6
5
 
7
- .alert {
8
- /* tone hooks - repointed by [data-tone] below; info is the default */
9
- --alert-hue: var(--info);
10
- --alert-fg: var(--info-text);
11
- --alert-bg: var(--info-subtle);
12
- --alert-wash: var(--accent-wash); /* info's wash = accent (teal) */
6
+ .alert-shell {
7
+ overflow: hidden;
8
+ }
13
9
 
14
- box-sizing: border-box;
15
- display: flex;
16
- align-items: center;
17
- gap: var(--space-3);
18
- padding: var(--space-3) var(--space-4);
19
- /* the lit pane: top-light gradient over the tint + 1px inner highlight (Button's lighting model) */
20
- background: linear-gradient(180deg, color-mix(in oklab, var(--bg-surface) 45%, var(--alert-bg)), var(--alert-bg));
21
- border: var(--border-hairline) solid color-mix(in oklab, var(--alert-hue) 30%, transparent);
22
- border-radius: var(--radius-lg);
23
- box-shadow: inset 0 1px 0 0 rgb(255 255 255 / 0.55);
24
- }
10
+ .alert {
11
+ /* tone hooks - repointed by [data-tone] below; info is the default */
12
+ --alert-hue: var(--info);
13
+ --alert-fg: var(--info-text);
14
+ --alert-bg: var(--info-subtle);
15
+ --alert-wash: var(--accent-wash); /* info's wash = accent (teal) */
16
+ --alert-sheen: rgb(255 255 255 / 0.55);
25
17
 
26
- .alert[data-tone='success'] {
27
- --alert-hue: var(--success);
28
- --alert-fg: var(--success-text);
29
- --alert-bg: var(--success-subtle);
30
- --alert-wash: var(--success-wash);
31
- }
32
- .alert[data-tone='warning'] {
33
- --alert-hue: var(--warning);
34
- --alert-fg: var(--warning-text);
35
- --alert-bg: var(--warning-subtle);
36
- --alert-wash: var(--warning-wash);
37
- }
38
- .alert[data-tone='danger'] {
39
- --alert-hue: var(--danger);
40
- --alert-fg: var(--danger-text);
41
- --alert-bg: var(--danger-subtle);
42
- --alert-wash: var(--danger-wash);
43
- }
18
+ box-sizing: border-box;
19
+ display: flex;
20
+ align-items: center;
21
+ gap: var(--space-3);
22
+ padding: var(--space-3) var(--space-4);
23
+ /* the lit pane: top-light gradient over the tint + 1px inner highlight (Button's lighting model) */
24
+ background: linear-gradient(180deg, color-mix(in oklab, var(--bg-surface) 45%, var(--alert-bg)), var(--alert-bg));
25
+ border: var(--border-hairline) solid color-mix(in oklab, var(--alert-hue) 30%, transparent);
26
+ border-radius: var(--radius-lg);
27
+ box-shadow: inset 0 1px 0 0 var(--alert-sheen);
28
+ }
44
29
 
45
- /* with a description: glyph rides the title line, controls stay centered */
46
- .alert:has(.alert__desc) {
47
- align-items: flex-start;
48
- }
49
- .alert:has(.alert__desc) .alert__action,
50
- .alert:has(.alert__desc) .alert__close {
51
- align-self: center;
52
- }
30
+ .alert[data-tone='success'] {
31
+ --alert-hue: var(--success);
32
+ --alert-fg: var(--success-text);
33
+ --alert-bg: var(--success-subtle);
34
+ --alert-wash: var(--success-wash);
35
+ }
36
+ .alert[data-tone='warning'] {
37
+ --alert-hue: var(--warning);
38
+ --alert-fg: var(--warning-text);
39
+ --alert-bg: var(--warning-subtle);
40
+ --alert-wash: var(--warning-wash);
41
+ }
42
+ .alert[data-tone='danger'] {
43
+ --alert-hue: var(--danger);
44
+ --alert-fg: var(--danger-text);
45
+ --alert-bg: var(--danger-subtle);
46
+ --alert-wash: var(--danger-wash);
47
+ }
53
48
 
54
- .alert--banner {
55
- border-radius: 0;
56
- border-block-start: 0;
57
- border-inline: 0;
58
- padding-inline: var(--space-6);
59
- }
49
+ /* with a description: glyph rides the title line, controls stay centered */
50
+ .alert:has(.alert__desc) {
51
+ align-items: flex-start;
52
+ }
53
+ .alert:has(.alert__desc) .alert__action,
54
+ .alert:has(.alert__desc) .alert__close {
55
+ align-self: center;
56
+ }
60
57
 
61
- /* Glyph - one --leading-body tall so it centers on the title line. */
62
- .alert__icon {
63
- flex: none;
64
- display: grid;
65
- place-items: center;
66
- height: var(--leading-body);
67
- color: var(--alert-hue);
68
- }
58
+ .alert--banner {
59
+ border-radius: 0;
60
+ border-block-start: 0;
61
+ border-inline: 0;
62
+ padding-inline: var(--space-6);
63
+ }
69
64
 
70
- .alert__body {
71
- flex: 1 1 auto;
72
- min-width: 0;
73
- }
74
- .alert__title {
75
- margin: 0;
76
- font: var(--type-label);
77
- color: var(--alert-fg);
78
- text-wrap: pretty;
79
- }
80
- .alert__desc {
81
- margin: var(--space-1) 0 0;
82
- font: var(--type-caption);
83
- color: color-mix(in oklab, var(--alert-fg) 56%, var(--text-body));
84
- text-wrap: pretty;
85
- }
65
+ /* Glyph - one --leading-body tall so it centers on the title line. */
66
+ .alert__icon {
67
+ flex: none;
68
+ display: grid;
69
+ place-items: center;
70
+ height: var(--leading-body);
71
+ color: var(--alert-hue);
72
+ }
86
73
 
87
- /* Action - the system .btn .btn--sm re-skinned to the pane's tone (alert-local chrome, not a global Button variant). */
88
- .alert__action {
89
- flex: none;
90
- color: var(--alert-fg);
91
- background: transparent;
92
- }
93
- .alert__action:hover:not(:disabled) {
94
- color: var(--alert-fg);
95
- background: var(--alert-wash);
96
- }
97
- .alert__action:active:not(:disabled) {
98
- background: color-mix(in oklab, var(--alert-hue) 16%, transparent);
99
- transform: translateY(var(--space-px));
100
- }
101
- .alert[data-tone='danger'] .alert__action {
102
- --btn-ring: var(--ring-danger);
103
- }
74
+ .alert__body {
75
+ flex: 1 1 auto;
76
+ min-width: 0;
77
+ }
78
+ .alert__title {
79
+ margin: 0;
80
+ font: var(--type-label);
81
+ color: var(--alert-fg);
82
+ text-wrap: pretty;
83
+ }
84
+ .alert__desc {
85
+ margin: var(--space-1) 0 0;
86
+ font: var(--type-caption);
87
+ color: color-mix(in oklab, var(--alert-fg) 56%, var(--text-body));
88
+ text-wrap: pretty;
89
+ }
104
90
 
105
- /* Dismiss - always visible (alerts persist; no hover-reveal like toast). */
106
- .alert__close {
107
- flex: none;
108
- appearance: none;
109
- display: grid;
110
- place-items: center;
111
- width: var(--space-6);
112
- height: var(--space-6);
113
- margin: 0;
114
- padding: 0;
115
- border: none;
116
- border-radius: var(--radius-sm);
117
- background: transparent;
118
- color: color-mix(in oklab, var(--alert-fg) 64%, transparent);
119
- cursor: pointer;
120
- transition: var(--transition-control);
121
- }
122
- .alert__close:hover {
123
- background: color-mix(in oklab, var(--alert-fg) 9%, transparent);
124
- color: var(--alert-fg);
125
- }
126
- .alert__close:active {
127
- background: color-mix(in oklab, var(--alert-fg) 14%, transparent);
128
- }
129
- .alert__close:focus-visible {
130
- outline: none;
131
- box-shadow: var(--focus-ring);
91
+ /* Action - the system .btn .btn--sm re-skinned to the pane's tone (alert-local chrome, not a global Button variant). */
92
+ .alert__action {
93
+ flex: none;
94
+ color: var(--alert-fg);
95
+ background: transparent;
96
+ }
97
+ .alert__action:hover:not(:disabled) {
98
+ color: var(--alert-fg);
99
+ background: var(--alert-wash);
100
+ }
101
+ .alert__action:active:not(:disabled) {
102
+ background: color-mix(in oklab, var(--alert-hue) 16%, transparent);
103
+ transform: translateY(var(--space-px));
104
+ }
105
+ .alert[data-tone='danger'] .alert__action {
106
+ --btn-ring: var(--ring-danger);
107
+ }
108
+
109
+ /* Dismiss - always visible (alerts persist; no hover-reveal like toast). */
110
+ .alert__close {
111
+ flex: none;
112
+ appearance: none;
113
+ display: grid;
114
+ place-items: center;
115
+ width: var(--space-6);
116
+ height: var(--space-6);
117
+ margin: 0;
118
+ padding: 0;
119
+ border: none;
120
+ border-radius: var(--radius-sm);
121
+ background: transparent;
122
+ color: color-mix(in oklab, var(--alert-fg) 64%, transparent);
123
+ cursor: pointer;
124
+ transition: var(--transition-control);
125
+ }
126
+ .alert__close:hover {
127
+ background: color-mix(in oklab, var(--alert-fg) 9%, transparent);
128
+ color: var(--alert-fg);
129
+ }
130
+ .alert__close:active {
131
+ background: color-mix(in oklab, var(--alert-fg) 14%, transparent);
132
+ }
133
+ .alert__close:focus-visible {
134
+ outline: none;
135
+ box-shadow: var(--focus-ring);
136
+ }
132
137
  }
package/dist/alert.js CHANGED
@@ -1,14 +1,15 @@
1
- 'use client';import { resolveMotionTiming } from './chunk-NEF5XAHG.js';
2
- import { Presence } from './chunk-356HZMT4.js';
3
- import { Motion } from './chunk-2QWJ6FAX.js';
4
- import './chunk-XWUWYSCT.js';
5
- import './chunk-YGCVWGUG.js';
6
- import { IconSlot } from './chunk-2ERBBFZS.js';
7
- import { Icon } from './chunk-3SBCBYB7.js';
1
+ 'use client';import { popOut } from './chunk-HDSFWZ7L.js';
2
+ import { Presence } from './chunk-DDRSMHN4.js';
3
+ import { resolveMotionTiming } from './chunk-TUTXXC3W.js';
4
+ import { Motion } from './chunk-5PZ43DCG.js';
5
+ import './chunk-M43IOM5C.js';
6
+ import './chunk-IJS7TPGV.js';
7
+ import { IconSlot } from './chunk-3MPF7FZV.js';
8
+ import { Icon } from './chunk-EAI4POPB.js';
8
9
  import { useControllable } from './chunk-MMRIQNEN.js';
9
- import './chunk-S5ZTZANS.js';
10
- import { Button } from './chunk-2F5PITAO.js';
11
- import './chunk-VTJTGVZZ.js';
10
+ import { UIMotion } from './chunk-7IZJERGA.js';
11
+ import { Button } from './chunk-HY5MPISE.js';
12
+ import './chunk-DMX2F6B4.js';
12
13
  import { cx } from './chunk-QGNC7LH5.js';
13
14
  import './alert.css';
14
15
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -56,10 +57,7 @@ function Alert({
56
57
  { height: [0, "auto"], timing: h.open },
57
58
  { opacity: [0, 1], timing: o.open }
58
59
  ],
59
- exit: [
60
- { height: ["auto", 0], timing: h.close },
61
- { opacity: [1, 0], timing: o.close }
62
- ],
60
+ exit: [popOut(UIMotion.scale.floating, o.close)],
63
61
  children: /* @__PURE__ */ jsxs("div", { className: cls, style, "data-tone": tone, role: TONE_ROLE[tone] || "status", ...htmlProps, children: [
64
62
  icon === null ? null : /* @__PURE__ */ jsx("span", { className: "alert__icon", "aria-hidden": "true", children: icon !== void 0 ? /* @__PURE__ */ jsx(IconSlot, { size: "md", children: icon }) : /* @__PURE__ */ jsx(Icon, { name: TONE_GLYPH[tone] || "info", size: "md" }) }),
65
63
  /* @__PURE__ */ jsxs("div", { className: "alert__body", children: [
package/dist/alert.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/composites/alert/Alert.tsx"],"names":[],"mappings":"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","file":"alert.js","sourcesContent":["'use client';\n\nimport './alert.css';\nimport type { CSSProperties, HTMLAttributes, ReactNode } from 'react';\nimport { Presence } from '../../../motion/presence';\nimport { Motion } from '../../../motion/element';\nimport { resolveMotionTiming } from '../../../motion/motion-timing';\nimport type { DisableableAnimation } from '../../../motion/timing';\nimport { Icon, type IconName } from '../../internal/icon/Icon';\nimport { Button } from '../../primitives/button/Button';\nimport { IconSlot } from '../../internal/icon/IconSlot';\nimport { useControllable } from '../../internal/hooks/use-controllable';\nimport type { DataAttributes } from '../../../dom-props';\nimport { cx } from '../../internal/utils/cx';\n\nexport type AlertTone = 'info' | 'success' | 'warning' | 'danger';\n\nexport interface AlertAction {\n /** Sentence-case label, e.g. \"Update billing\". */\n label: string;\n onClick?: () => void;\n}\n\ninterface AlertOwnProps {\n /** Status of the message; info/success are polite, warning/danger assertive. Default 'info'. */\n tone?: AlertTone;\n /** The message - sentence case, ideally one line. */\n title: ReactNode;\n /** Optional description; stays neutral - tone marks the message, not the prose. */\n children?: ReactNode;\n /** One action max, rendered as the system secondary small button. */\n action?: AlertAction;\n /** Renders the always-visible close button. Uncontrolled unless `open` is given. */\n dismissible?: boolean;\n /** Fires on dismiss. With `open` set, the parent owns hiding the alert. */\n onDismiss?: () => void;\n /** Controlled visibility; omit for uncontrolled. Exit eases shut (height collapse). */\n open?: boolean;\n /** App-level strip: square corners, hairline below only. Paint modifier. */\n banner?: boolean;\n /** Override the tone glyph; pass null to render no glyph. */\n icon?: ReactNode | null;\n /** Extra class(es) merged onto the alert. */\n className?: string;\n /** Inline styles merged onto the alert. */\n style?: CSSProperties;\n /** Enter/exit timing - motion tokens only, or `null` to disable (the height collapse snaps).\n * @default height 'slow'/'entrance'; opacity in 'base'/'entrance', out 'fast'/'exit' */\n animation?: DisableableAnimation;\n}\n\nexport interface AlertProps extends AlertOwnProps {\n /** Standard <div> attributes (aria-*, data-*, ...) forwarded to the alert. */\n htmlProps?: Omit<HTMLAttributes<HTMLDivElement>, keyof AlertOwnProps> & DataAttributes;\n}\n\nconst ALERT_HEIGHT_TIMING = {\n open: { duration: 'slow', ease: 'entrance' },\n close: { duration: 'slow', ease: 'entrance' },\n} as const;\nconst ALERT_OPACITY_TIMING = {\n open: { duration: 'base', ease: 'entrance' },\n close: { duration: 'fast', ease: 'exit' },\n} as const;\n\nconst TONE_GLYPH: Record<AlertTone, IconName> = {\n info: 'info',\n success: 'check-circle',\n warning: 'warning',\n danger: 'warning-circle',\n};\nconst TONE_ROLE: Record<AlertTone, string> = { info: 'status', success: 'status', warning: 'alert', danger: 'alert' };\n\nexport function Alert({\n tone = 'info',\n title,\n children = null,\n action = null,\n dismissible = false,\n onDismiss,\n open,\n banner = false,\n icon,\n className = '',\n style,\n htmlProps,\n animation,\n}: AlertProps) {\n const [isOpen, setOpen] = useControllable(open, true, onDismiss);\n const dismiss = () => setOpen(false);\n\n const h = resolveMotionTiming(animation, ALERT_HEIGHT_TIMING);\n const o = resolveMotionTiming(animation, ALERT_OPACITY_TIMING);\n\n const cls = cx('alert', banner && 'alert--banner', className);\n\n return (\n <Presence initial={false}>\n {isOpen && (\n <Motion\n key=\"alert-shell\"\n className=\"alert-shell\"\n animate={[\n { height: [0, 'auto'], timing: h.open },\n { opacity: [0, 1], timing: o.open },\n ]}\n exit={[\n { height: ['auto', 0], timing: h.close },\n { opacity: [1, 0], timing: o.close },\n ]}\n >\n <div className={cls} style={style} data-tone={tone} role={TONE_ROLE[tone] || 'status'} {...htmlProps}>\n {icon === null ? null : (\n <span className=\"alert__icon\" aria-hidden=\"true\">\n {icon !== undefined ? (\n <IconSlot size=\"md\">{icon}</IconSlot>\n ) : (\n <Icon name={TONE_GLYPH[tone] || 'info'} size=\"md\" />\n )}\n </span>\n )}\n <div className=\"alert__body\">\n <p className=\"alert__title\">{title}</p>\n {children != null && <p className=\"alert__desc\">{children}</p>}\n </div>\n {action && (\n <Button variant=\"unstyled\" size=\"sm\" className=\"alert__action\" onClick={action.onClick}>\n {action.label}\n </Button>\n )}\n {dismissible && (\n <button type=\"button\" className=\"alert__close\" aria-label=\"Dismiss\" onClick={dismiss}>\n <Icon name=\"close\" size=\"sm\" />\n </button>\n )}\n </div>\n </Motion>\n )}\n </Presence>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/composites/alert/Alert.tsx"],"names":[],"mappings":"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","file":"alert.js","sourcesContent":["'use client';\n\nimport './alert.css';\n\nimport type { CSSProperties, HTMLAttributes, ReactNode } from 'react';\n\nimport type { DataAttributes } from '../../../dom-props';\nimport { Motion } from '../../../motion/element';\nimport { resolveMotionTiming } from '../../../motion/motion-timing';\nimport { Presence } from '../../../motion/presence';\nimport { popOut } from '../../../motion/presets';\nimport type { DisableableAnimation } from '../../../motion/timing';\nimport { UIMotion } from '../../../tokens/motion-tokens';\nimport { useControllable } from '../../internal/hooks/use-controllable';\nimport { Icon, type IconName } from '../../internal/icon/Icon';\nimport { IconSlot } from '../../internal/icon/IconSlot';\nimport { cx } from '../../internal/utils/cx';\nimport { Button } from '../../primitives/button/Button';\n\nexport type AlertTone = 'info' | 'success' | 'warning' | 'danger';\n\nexport interface AlertAction {\n /** Sentence-case label, e.g. \"Update billing\". */\n label: string;\n onClick?: () => void;\n}\n\ninterface AlertOwnProps {\n /** Status of the message; info/success are polite, warning/danger assertive. Default 'info'. */\n tone?: AlertTone;\n /** The message - sentence case, ideally one line. */\n title: ReactNode;\n /** Optional description; stays neutral - tone marks the message, not the prose. */\n children?: ReactNode;\n /** One action max, rendered as the system secondary small button. */\n action?: AlertAction;\n /** Renders the always-visible close button. Uncontrolled unless `open` is given. */\n dismissible?: boolean;\n /** Fires on dismiss. With `open` set, the parent owns hiding the alert. */\n onDismiss?: () => void;\n /** Controlled visibility; omit for uncontrolled. Exit scales down and fades; the slot it\n * occupied is released when it unmounts, so content below moves up then rather than during. */\n open?: boolean;\n /** App-level strip: square corners, hairline below only. Paint modifier. */\n banner?: boolean;\n /** Override the tone glyph; pass null to render no glyph. */\n icon?: ReactNode | null;\n /** Extra class(es) merged onto the alert. */\n className?: string;\n /** Inline styles merged onto the alert. */\n style?: CSSProperties;\n /** Enter/exit timing - motion tokens only, or `null` to disable (enter and exit snap).\n * @default entrance height 'slow'/'entrance' + opacity 'base'/'entrance'; exit scale + opacity 'fast'/'exit' */\n animation?: DisableableAnimation;\n}\n\nexport interface AlertProps extends AlertOwnProps {\n /** Standard <div> attributes (aria-*, data-*, ...) forwarded to the alert. */\n htmlProps?: Omit<HTMLAttributes<HTMLDivElement>, keyof AlertOwnProps> & DataAttributes;\n}\n\nconst ALERT_HEIGHT_TIMING = {\n open: { duration: 'slow', ease: 'entrance' },\n close: { duration: 'slow', ease: 'entrance' },\n} as const;\nconst ALERT_OPACITY_TIMING = {\n open: { duration: 'base', ease: 'entrance' },\n close: { duration: 'fast', ease: 'exit' },\n} as const;\n\nconst TONE_GLYPH: Record<AlertTone, IconName> = {\n info: 'info',\n success: 'check-circle',\n warning: 'warning',\n danger: 'warning-circle',\n};\nconst TONE_ROLE: Record<AlertTone, string> = { info: 'status', success: 'status', warning: 'alert', danger: 'alert' };\n\nexport function Alert({\n tone = 'info',\n title,\n children = null,\n action = null,\n dismissible = false,\n onDismiss,\n open,\n banner = false,\n icon,\n className = '',\n style,\n htmlProps,\n animation,\n}: AlertProps) {\n const [isOpen, setOpen] = useControllable(open, true, onDismiss);\n const dismiss = () => setOpen(false);\n\n const h = resolveMotionTiming(animation, ALERT_HEIGHT_TIMING);\n const o = resolveMotionTiming(animation, ALERT_OPACITY_TIMING);\n\n const cls = cx('alert', banner && 'alert--banner', className);\n\n return (\n <Presence initial={false}>\n {isOpen && (\n <Motion\n key=\"alert-shell\"\n className=\"alert-shell\"\n animate={[\n { height: [0, 'auto'], timing: h.open },\n { opacity: [0, 1], timing: o.open },\n ]}\n exit={[popOut(UIMotion.scale.floating, o.close)]}\n >\n <div className={cls} style={style} data-tone={tone} role={TONE_ROLE[tone] || 'status'} {...htmlProps}>\n {icon === null ? null : (\n <span className=\"alert__icon\" aria-hidden=\"true\">\n {icon !== undefined ? (\n <IconSlot size=\"md\">{icon}</IconSlot>\n ) : (\n <Icon name={TONE_GLYPH[tone] || 'info'} size=\"md\" />\n )}\n </span>\n )}\n <div className=\"alert__body\">\n <p className=\"alert__title\">{title}</p>\n {children != null && <p className=\"alert__desc\">{children}</p>}\n </div>\n {action && (\n <Button variant=\"unstyled\" size=\"sm\" className=\"alert__action\" onClick={action.onClick}>\n {action.label}\n </Button>\n )}\n {dismissible && (\n <button type=\"button\" className=\"alert__close\" aria-label=\"Dismiss\" onClick={dismiss}>\n <Icon name=\"close\" size=\"sm\" />\n </button>\n )}\n </div>\n </Motion>\n )}\n </Presence>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/primitives/avatar/AvatarGroup.tsx"],"names":[],"mappings":";;;;;AAkCO,SAAS,WAAA,CAAY,EAAE,QAAA,EAAU,GAAA,GAAM,CAAA,EAAG,IAAA,GAAO,IAAA,EAAM,SAAA,GAAY,EAAA,EAAI,KAAA,EAAO,SAAA,EAAU,EAAqB;AAClH,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,OAAA,CAAQ,QAAQ,CAAA;AACvC,EAAA,MAAM,UAAU,GAAA,GAAM,CAAA,GAAI,MAAM,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,GAAI,KAAA;AAChD,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,MAAA,GAAS,OAAA,CAAQ,MAAA;AAExC,EAAA,uBACE,IAAA,CAAC,UAAK,SAAA,EAAW,EAAA,CAAG,gBAAgB,SAAS,CAAA,EAAG,KAAA,EAAe,GAAG,SAAA,EAC/D,QAAA,EAAA;AAAA,IAAA,OAAA,CAAQ,GAAA;AAAA,MAAI,CAAC,KAAA,EAAO,CAAA,KACnB,cAAA,CAAe,KAAK,CAAA,GAChB,YAAA,CAAa,KAAA,EAA8C,EAAE,MAAM,GAAA,EAAK,KAAA,CAAM,GAAA,IAAO,CAAA,EAAG,CAAA,GACxF;AAAA,KACN;AAAA,IACC,QAAA,GAAW,qBACV,GAAA,CAAC,MAAA,EAAA,EAAK,WAAW,CAAA,eAAA,EAAkB,IAAI,qBAAqB,IAAA,EAAK,KAAA,EAAM,cAAY,CAAA,EAAG,QAAQ,SAC5F,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,WAAU,cAAA,EACd,QAAA,kBAAA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kBAAA,EAAmB,QAAA,EAAA;AAAA,MAAA,GAAA;AAAA,MAAE;AAAA,KAAA,EAAS,GAChD,CAAA,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ","file":"avatar-group.js","sourcesContent":["'use client';\n\nimport './avatar.css';\nimport {\n Children,\n cloneElement,\n isValidElement,\n type CSSProperties,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport type { AvatarSize } from './Avatar';\nimport type { DataAttributes } from '../../../dom-props';\nimport { cx } from '../../internal/utils/cx';\n\ninterface AvatarGroupOwnProps {\n /** The `Avatar` elements to stack; each is cloned to force `size`, then sliced to `max`. */\n children: ReactNode;\n /** Max visible avatars before \"+N\" overflow chip. Default 5. */\n max?: number;\n /** Uniform size applied to all children. Default 'md'. */\n size?: AvatarSize;\n /** Extra class(es) merged onto the group wrapper. */\n className?: string;\n /** Inline styles merged onto the group wrapper. */\n style?: CSSProperties;\n}\n\nexport interface AvatarGroupProps extends AvatarGroupOwnProps {\n /** Standard <span> attributes forwarded to the group wrapper. */\n htmlProps?: Omit<HTMLAttributes<HTMLSpanElement>, keyof AvatarGroupOwnProps> & DataAttributes;\n}\n\nexport function AvatarGroup({ children, max = 5, size = 'md', className = '', style, htmlProps }: AvatarGroupProps) {\n const items = Children.toArray(children);\n const visible = max > 0 ? items.slice(0, max) : items;\n const overflow = items.length - visible.length;\n\n return (\n <span className={cx('avatar-group', className)} style={style} {...htmlProps}>\n {visible.map((child, i) =>\n isValidElement(child)\n ? cloneElement(child as ReactElement<{ size?: AvatarSize }>, { size, key: child.key ?? i })\n : child,\n )}\n {overflow > 0 && (\n <span className={`avatar avatar--${size} avatar--overflow`} role=\"img\" aria-label={`${overflow} more`}>\n <span className=\"avatar__face\">\n <span className=\"avatar__initials\">+{overflow}</span>\n </span>\n </span>\n )}\n </span>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/primitives/avatar/AvatarGroup.tsx"],"names":[],"mappings":";;;;;AAoCO,SAAS,WAAA,CAAY,EAAE,QAAA,EAAU,GAAA,GAAM,CAAA,EAAG,IAAA,GAAO,IAAA,EAAM,SAAA,GAAY,EAAA,EAAI,KAAA,EAAO,SAAA,EAAU,EAAqB;AAClH,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,OAAA,CAAQ,QAAQ,CAAA;AACvC,EAAA,MAAM,UAAU,GAAA,GAAM,CAAA,GAAI,MAAM,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,GAAI,KAAA;AAChD,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,MAAA,GAAS,OAAA,CAAQ,MAAA;AAExC,EAAA,uBACE,IAAA,CAAC,UAAK,SAAA,EAAW,EAAA,CAAG,gBAAgB,SAAS,CAAA,EAAG,KAAA,EAAe,GAAG,SAAA,EAC/D,QAAA,EAAA;AAAA,IAAA,OAAA,CAAQ,GAAA;AAAA,MAAI,CAAC,KAAA,EAAO,CAAA,KACnB,cAAA,CAAe,KAAK,CAAA,GAChB,YAAA,CAAa,KAAA,EAA8C,EAAE,MAAM,GAAA,EAAK,KAAA,CAAM,GAAA,IAAO,CAAA,EAAG,CAAA,GACxF;AAAA,KACN;AAAA,IACC,QAAA,GAAW,qBACV,GAAA,CAAC,MAAA,EAAA,EAAK,WAAW,CAAA,eAAA,EAAkB,IAAI,qBAAqB,IAAA,EAAK,KAAA,EAAM,cAAY,CAAA,EAAG,QAAQ,SAC5F,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,WAAU,cAAA,EACd,QAAA,kBAAA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kBAAA,EAAmB,QAAA,EAAA;AAAA,MAAA,GAAA;AAAA,MAAE;AAAA,KAAA,EAAS,GAChD,CAAA,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ","file":"avatar-group.js","sourcesContent":["'use client';\n\nimport './avatar.css';\n\nimport {\n Children,\n cloneElement,\n isValidElement,\n type CSSProperties,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n} from 'react';\n\nimport type { DataAttributes } from '../../../dom-props';\nimport { cx } from '../../internal/utils/cx';\nimport type { AvatarSize } from './Avatar';\n\ninterface AvatarGroupOwnProps {\n /** The `Avatar` elements to stack; each is cloned to force `size`, then sliced to `max`. */\n children: ReactNode;\n /** Max visible avatars before \"+N\" overflow chip. Default 5. */\n max?: number;\n /** Uniform size applied to all children. Default 'md'. */\n size?: AvatarSize;\n /** Extra class(es) merged onto the group wrapper. */\n className?: string;\n /** Inline styles merged onto the group wrapper. */\n style?: CSSProperties;\n}\n\nexport interface AvatarGroupProps extends AvatarGroupOwnProps {\n /** Standard <span> attributes forwarded to the group wrapper. */\n htmlProps?: Omit<HTMLAttributes<HTMLSpanElement>, keyof AvatarGroupOwnProps> & DataAttributes;\n}\n\nexport function AvatarGroup({ children, max = 5, size = 'md', className = '', style, htmlProps }: AvatarGroupProps) {\n const items = Children.toArray(children);\n const visible = max > 0 ? items.slice(0, max) : items;\n const overflow = items.length - visible.length;\n\n return (\n <span className={cx('avatar-group', className)} style={style} {...htmlProps}>\n {visible.map((child, i) =>\n isValidElement(child)\n ? cloneElement(child as ReactElement<{ size?: AvatarSize }>, { size, key: child.key ?? i })\n : child,\n )}\n {overflow > 0 && (\n <span className={`avatar avatar--${size} avatar--overflow`} role=\"img\" aria-label={`${overflow} more`}>\n <span className=\"avatar__face\">\n <span className=\"avatar__initials\">+{overflow}</span>\n </span>\n </span>\n )}\n </span>\n );\n}\n"]}