@zyncat/ui 0.8.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 (334) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +133 -0
  3. package/dist/alert.css +132 -0
  4. package/dist/alert.d.ts +46 -0
  5. package/dist/alert.js +80 -0
  6. package/dist/alert.js.map +1 -0
  7. package/dist/avatar-group.d.ts +24 -0
  8. package/dist/avatar-group.js +23 -0
  9. package/dist/avatar-group.js.map +1 -0
  10. package/dist/avatar.css +200 -0
  11. package/dist/avatar.d.ts +35 -0
  12. package/dist/avatar.js +67 -0
  13. package/dist/avatar.js.map +1 -0
  14. package/dist/badge.css +182 -0
  15. package/dist/badge.d.ts +34 -0
  16. package/dist/badge.js +4 -0
  17. package/dist/badge.js.map +1 -0
  18. package/dist/button.css +269 -0
  19. package/dist/button.d.ts +44 -0
  20. package/dist/button.js +4 -0
  21. package/dist/button.js.map +1 -0
  22. package/dist/checkbox.css +177 -0
  23. package/dist/checkbox.d.ts +35 -0
  24. package/dist/checkbox.js +5 -0
  25. package/dist/checkbox.js.map +1 -0
  26. package/dist/chunk-2ERBBFZS.js +12 -0
  27. package/dist/chunk-2ERBBFZS.js.map +1 -0
  28. package/dist/chunk-2HORSLXJ.js +191 -0
  29. package/dist/chunk-2HORSLXJ.js.map +1 -0
  30. package/dist/chunk-36WVAQKL.js +40 -0
  31. package/dist/chunk-36WVAQKL.js.map +1 -0
  32. package/dist/chunk-3SBCBYB7.js +575 -0
  33. package/dist/chunk-3SBCBYB7.js.map +1 -0
  34. package/dist/chunk-4R2GQO43.js +125 -0
  35. package/dist/chunk-4R2GQO43.js.map +1 -0
  36. package/dist/chunk-64UU4LGU.js +258 -0
  37. package/dist/chunk-64UU4LGU.js.map +1 -0
  38. package/dist/chunk-7SZCJ7WI.js +35 -0
  39. package/dist/chunk-7SZCJ7WI.js.map +1 -0
  40. package/dist/chunk-BIDVNLJO.js +38 -0
  41. package/dist/chunk-BIDVNLJO.js.map +1 -0
  42. package/dist/chunk-CONSWNIV.js +17 -0
  43. package/dist/chunk-CONSWNIV.js.map +1 -0
  44. package/dist/chunk-EQ32F2QJ.js +75 -0
  45. package/dist/chunk-EQ32F2QJ.js.map +1 -0
  46. package/dist/chunk-GY7JOPUQ.js +111 -0
  47. package/dist/chunk-GY7JOPUQ.js.map +1 -0
  48. package/dist/chunk-I4XQ4PV2.js +30 -0
  49. package/dist/chunk-I4XQ4PV2.js.map +1 -0
  50. package/dist/chunk-JSKXZMLH.js +67 -0
  51. package/dist/chunk-JSKXZMLH.js.map +1 -0
  52. package/dist/chunk-L3Q3VDIW.js +295 -0
  53. package/dist/chunk-L3Q3VDIW.js.map +1 -0
  54. package/dist/chunk-LDC3RIYA.js +62 -0
  55. package/dist/chunk-LDC3RIYA.js.map +1 -0
  56. package/dist/chunk-MKIQFK7S.js +43 -0
  57. package/dist/chunk-MKIQFK7S.js.map +1 -0
  58. package/dist/chunk-MMRIQNEN.js +20 -0
  59. package/dist/chunk-MMRIQNEN.js.map +1 -0
  60. package/dist/chunk-MXOPCFWR.js +59 -0
  61. package/dist/chunk-MXOPCFWR.js.map +1 -0
  62. package/dist/chunk-NEF5XAHG.js +17 -0
  63. package/dist/chunk-NEF5XAHG.js.map +1 -0
  64. package/dist/chunk-NNXJCLTV.js +22 -0
  65. package/dist/chunk-NNXJCLTV.js.map +1 -0
  66. package/dist/chunk-O4N2OBTR.js +94 -0
  67. package/dist/chunk-O4N2OBTR.js.map +1 -0
  68. package/dist/chunk-PMECHR3A.js +38 -0
  69. package/dist/chunk-PMECHR3A.js.map +1 -0
  70. package/dist/chunk-QDK66S4G.js +44 -0
  71. package/dist/chunk-QDK66S4G.js.map +1 -0
  72. package/dist/chunk-QGNC7LH5.js +8 -0
  73. package/dist/chunk-QGNC7LH5.js.map +1 -0
  74. package/dist/chunk-QMSJZCK3.js +398 -0
  75. package/dist/chunk-QMSJZCK3.js.map +1 -0
  76. package/dist/chunk-S5ZTZANS.js +57 -0
  77. package/dist/chunk-S5ZTZANS.js.map +1 -0
  78. package/dist/chunk-S7B34VGN.js +14 -0
  79. package/dist/chunk-S7B34VGN.js.map +1 -0
  80. package/dist/chunk-TCUCYFT7.js +25 -0
  81. package/dist/chunk-TCUCYFT7.js.map +1 -0
  82. package/dist/chunk-TYHR4VNM.js +193 -0
  83. package/dist/chunk-TYHR4VNM.js.map +1 -0
  84. package/dist/chunk-U5QQZC3U.js +56 -0
  85. package/dist/chunk-U5QQZC3U.js.map +1 -0
  86. package/dist/chunk-UE63OOVG.js +13 -0
  87. package/dist/chunk-UE63OOVG.js.map +1 -0
  88. package/dist/chunk-VTJTGVZZ.js +22 -0
  89. package/dist/chunk-VTJTGVZZ.js.map +1 -0
  90. package/dist/chunk-W3SHPKSB.js +49 -0
  91. package/dist/chunk-W3SHPKSB.js.map +1 -0
  92. package/dist/chunk-XZAEIQDR.js +188 -0
  93. package/dist/chunk-XZAEIQDR.js.map +1 -0
  94. package/dist/chunk-YGGCQNNU.js +92 -0
  95. package/dist/chunk-YGGCQNNU.js.map +1 -0
  96. package/dist/collapse.css +88 -0
  97. package/dist/collapse.d.ts +46 -0
  98. package/dist/collapse.js +5 -0
  99. package/dist/collapse.js.map +1 -0
  100. package/dist/count-badge.d.ts +13 -0
  101. package/dist/count-badge.js +13 -0
  102. package/dist/count-badge.js.map +1 -0
  103. package/dist/date-field.d.ts +25 -0
  104. package/dist/date-field.js +87 -0
  105. package/dist/date-field.js.map +1 -0
  106. package/dist/date-picker.css +595 -0
  107. package/dist/date-range-field.d.ts +33 -0
  108. package/dist/date-range-field.js +404 -0
  109. package/dist/date-range-field.js.map +1 -0
  110. package/dist/datetime-field.d.ts +29 -0
  111. package/dist/datetime-field.js +155 -0
  112. package/dist/datetime-field.js.map +1 -0
  113. package/dist/dialog.css +180 -0
  114. package/dist/dialog.d.ts +42 -0
  115. package/dist/dialog.js +128 -0
  116. package/dist/dialog.js.map +1 -0
  117. package/dist/dom-props-C0jrllBw.d.ts +5 -0
  118. package/dist/field-chrome-CMPOQSLs.d.ts +28 -0
  119. package/dist/field-shell-Cuda-feL.d.ts +24 -0
  120. package/dist/glide.d.ts +15 -0
  121. package/dist/glide.js +5 -0
  122. package/dist/glide.js.map +1 -0
  123. package/dist/icon.css +33 -0
  124. package/dist/input.css +333 -0
  125. package/dist/mcp.js +359 -0
  126. package/dist/motion-devtools.css +265 -0
  127. package/dist/motion-devtools.d.ts +51 -0
  128. package/dist/motion-devtools.js +354 -0
  129. package/dist/motion-devtools.js.map +1 -0
  130. package/dist/motion-scale-Canq4stZ.d.ts +18 -0
  131. package/dist/motion-tokens.d.ts +28 -0
  132. package/dist/motion-tokens.js +3 -0
  133. package/dist/motion-tokens.js.map +1 -0
  134. package/dist/multi-select.d.ts +44 -0
  135. package/dist/multi-select.js +109 -0
  136. package/dist/multi-select.js.map +1 -0
  137. package/dist/number-field.d.ts +36 -0
  138. package/dist/number-field.js +112 -0
  139. package/dist/number-field.js.map +1 -0
  140. package/dist/odometer.css +62 -0
  141. package/dist/otp-field.d.ts +31 -0
  142. package/dist/otp-field.js +98 -0
  143. package/dist/otp-field.js.map +1 -0
  144. package/dist/overlay.css +23 -0
  145. package/dist/pagination.css +43 -0
  146. package/dist/pagination.d.ts +29 -0
  147. package/dist/pagination.js +107 -0
  148. package/dist/pagination.js.map +1 -0
  149. package/dist/popover.css +69 -0
  150. package/dist/popover.d.ts +35 -0
  151. package/dist/popover.js +15 -0
  152. package/dist/popover.js.map +1 -0
  153. package/dist/radio-group.css +300 -0
  154. package/dist/radio-group.d.ts +52 -0
  155. package/dist/radio-group.js +115 -0
  156. package/dist/radio-group.js.map +1 -0
  157. package/dist/select.css +416 -0
  158. package/dist/select.d.ts +49 -0
  159. package/dist/select.js +99 -0
  160. package/dist/select.js.map +1 -0
  161. package/dist/sheet.css +26 -0
  162. package/dist/sheet.d.ts +31 -0
  163. package/dist/sheet.js +14 -0
  164. package/dist/sheet.js.map +1 -0
  165. package/dist/status-badge.d.ts +19 -0
  166. package/dist/status-badge.js +72 -0
  167. package/dist/status-badge.js.map +1 -0
  168. package/dist/table.css +348 -0
  169. package/dist/table.d.ts +75 -0
  170. package/dist/table.js +262 -0
  171. package/dist/table.js.map +1 -0
  172. package/dist/tabs.css +208 -0
  173. package/dist/tabs.d.ts +71 -0
  174. package/dist/tabs.js +181 -0
  175. package/dist/tabs.js.map +1 -0
  176. package/dist/tag.css +248 -0
  177. package/dist/tag.d.ts +52 -0
  178. package/dist/tag.js +72 -0
  179. package/dist/tag.js.map +1 -0
  180. package/dist/text-field.d.ts +28 -0
  181. package/dist/text-field.js +69 -0
  182. package/dist/text-field.js.map +1 -0
  183. package/dist/textarea.css +219 -0
  184. package/dist/textarea.d.ts +38 -0
  185. package/dist/textarea.js +144 -0
  186. package/dist/textarea.js.map +1 -0
  187. package/dist/time-field.d.ts +28 -0
  188. package/dist/time-field.js +66 -0
  189. package/dist/time-field.js.map +1 -0
  190. package/dist/timing-7JA_zQHP.d.ts +27 -0
  191. package/dist/toast-store.d.ts +86 -0
  192. package/dist/toast-store.js +3 -0
  193. package/dist/toast-store.js.map +1 -0
  194. package/dist/toast.css +257 -0
  195. package/dist/toast.d.ts +12 -0
  196. package/dist/toast.js +310 -0
  197. package/dist/toast.js.map +1 -0
  198. package/dist/toggle-tag.d.ts +34 -0
  199. package/dist/toggle-tag.js +57 -0
  200. package/dist/toggle-tag.js.map +1 -0
  201. package/dist/toggle.css +152 -0
  202. package/dist/toggle.d.ts +31 -0
  203. package/dist/toggle.js +75 -0
  204. package/dist/toggle.js.map +1 -0
  205. package/dist/tooltip.css +86 -0
  206. package/dist/tooltip.d.ts +30 -0
  207. package/dist/tooltip.js +268 -0
  208. package/dist/tooltip.js.map +1 -0
  209. package/dist/types-SGMShK7R.d.ts +22 -0
  210. package/llms.txt +196 -0
  211. package/next.d.mts +7 -0
  212. package/next.mjs +59 -0
  213. package/package.json +257 -0
  214. package/src/components/composites/alert/Alert.tsx +141 -0
  215. package/src/components/composites/alert/alert.css +132 -0
  216. package/src/components/composites/date-picker/DateField.tsx +80 -0
  217. package/src/components/composites/date-picker/DateRangeField.tsx +110 -0
  218. package/src/components/composites/date-picker/DateTimeField.tsx +162 -0
  219. package/src/components/composites/date-picker/TimeField.tsx +78 -0
  220. package/src/components/composites/date-picker/calendar-panel.tsx +216 -0
  221. package/src/components/composites/date-picker/date-picker.css +595 -0
  222. package/src/components/composites/date-picker/date-utils.ts +56 -0
  223. package/src/components/composites/date-picker/field-shell.tsx +85 -0
  224. package/src/components/composites/date-picker/range-panel.tsx +363 -0
  225. package/src/components/composites/date-picker/time-core.tsx +290 -0
  226. package/src/components/composites/date-picker/use-day-focus.ts +35 -0
  227. package/src/components/composites/dialog/Dialog.tsx +198 -0
  228. package/src/components/composites/dialog/dialog.css +180 -0
  229. package/src/components/composites/pagination/Pagination.tsx +131 -0
  230. package/src/components/composites/pagination/pagination.css +43 -0
  231. package/src/components/composites/popover/Popover.tsx +141 -0
  232. package/src/components/composites/popover/popover.css +69 -0
  233. package/src/components/composites/select/MultiSelect.tsx +133 -0
  234. package/src/components/composites/select/Select.tsx +122 -0
  235. package/src/components/composites/select/core/index.ts +4 -0
  236. package/src/components/composites/select/core/menu.tsx +100 -0
  237. package/src/components/composites/select/core/panel.tsx +154 -0
  238. package/src/components/composites/select/core/trigger.tsx +74 -0
  239. package/src/components/composites/select/core/types.ts +39 -0
  240. package/src/components/composites/select/core/use-listbox.ts +182 -0
  241. package/src/components/composites/select/select.css +416 -0
  242. package/src/components/composites/sheet/Sheet.tsx +135 -0
  243. package/src/components/composites/sheet/sheet.css +26 -0
  244. package/src/components/composites/sheet/use-sheet-drag.ts +126 -0
  245. package/src/components/composites/table/Table.tsx +377 -0
  246. package/src/components/composites/table/table.css +348 -0
  247. package/src/components/composites/tabs/Tabs.tsx +278 -0
  248. package/src/components/composites/tabs/tabs.css +208 -0
  249. package/src/components/composites/toast/Toast.tsx +380 -0
  250. package/src/components/composites/toast/toast-store.ts +295 -0
  251. package/src/components/composites/toast/toast.css +257 -0
  252. package/src/components/composites/tooltip/Tooltip.tsx +110 -0
  253. package/src/components/composites/tooltip/tooltip-host.tsx +184 -0
  254. package/src/components/composites/tooltip/tooltip-store.ts +81 -0
  255. package/src/components/composites/tooltip/tooltip.css +86 -0
  256. package/src/components/dev/MotionDevtools.tsx +200 -0
  257. package/src/components/dev/motion-devtools.css +265 -0
  258. package/src/components/dev/slowmo-engine.ts +230 -0
  259. package/src/components/internal/glass/glass.css +100 -0
  260. package/src/components/internal/glass/glint.ts +9 -0
  261. package/src/components/internal/hooks/use-controllable.ts +21 -0
  262. package/src/components/internal/hooks/use-scroll-edges.ts +46 -0
  263. package/src/components/internal/icon/Icon.tsx +66 -0
  264. package/src/components/internal/icon/IconSlot.tsx +10 -0
  265. package/src/components/internal/icon/icon.css +33 -0
  266. package/src/components/internal/overlay/focus.ts +68 -0
  267. package/src/components/internal/overlay/layer.tsx +149 -0
  268. package/src/components/internal/overlay/modal.tsx +141 -0
  269. package/src/components/internal/overlay/overlay.css +23 -0
  270. package/src/components/internal/overlay/position.ts +103 -0
  271. package/src/components/internal/utils/cx.ts +3 -0
  272. package/src/components/internal/utils/token-px.ts +8 -0
  273. package/src/components/primitives/avatar/Avatar.tsx +120 -0
  274. package/src/components/primitives/avatar/AvatarGroup.tsx +56 -0
  275. package/src/components/primitives/avatar/avatar.css +200 -0
  276. package/src/components/primitives/badge/Badge.tsx +75 -0
  277. package/src/components/primitives/badge/CountBadge.tsx +20 -0
  278. package/src/components/primitives/badge/StatusBadge.tsx +111 -0
  279. package/src/components/primitives/badge/badge.css +182 -0
  280. package/src/components/primitives/badge/odometer.css +62 -0
  281. package/src/components/primitives/badge/odometer.tsx +36 -0
  282. package/src/components/primitives/button/Button.tsx +102 -0
  283. package/src/components/primitives/button/button.css +269 -0
  284. package/src/components/primitives/checkbox/Checkbox.tsx +76 -0
  285. package/src/components/primitives/checkbox/check-glyph.tsx +28 -0
  286. package/src/components/primitives/checkbox/checkbox.css +177 -0
  287. package/src/components/primitives/collapse/Collapse.tsx +86 -0
  288. package/src/components/primitives/collapse/collapse.css +88 -0
  289. package/src/components/primitives/collapse/collapse.typecheck.tsx +29 -0
  290. package/src/components/primitives/input/NumberField.tsx +139 -0
  291. package/src/components/primitives/input/OtpField.tsx +134 -0
  292. package/src/components/primitives/input/TextField.tsx +110 -0
  293. package/src/components/primitives/input/field-chrome.tsx +83 -0
  294. package/src/components/primitives/input/input.css +333 -0
  295. package/src/components/primitives/radio-group/RadioGroup.tsx +183 -0
  296. package/src/components/primitives/radio-group/radio-group.css +300 -0
  297. package/src/components/primitives/tag/Tag.tsx +143 -0
  298. package/src/components/primitives/tag/ToggleTag.tsx +97 -0
  299. package/src/components/primitives/tag/tag.css +248 -0
  300. package/src/components/primitives/textarea/Textarea.tsx +190 -0
  301. package/src/components/primitives/textarea/textarea.css +219 -0
  302. package/src/components/primitives/toggle/Toggle.tsx +105 -0
  303. package/src/components/primitives/toggle/toggle.css +152 -0
  304. package/src/css.d.ts +1 -0
  305. package/src/dom-props.ts +1 -0
  306. package/src/engine/animate.ts +141 -0
  307. package/src/engine/drag.ts +53 -0
  308. package/src/engine/ease.ts +155 -0
  309. package/src/engine/flip.ts +59 -0
  310. package/src/engine/index.ts +13 -0
  311. package/src/mcp/server.ts +420 -0
  312. package/src/motion/element.tsx +53 -0
  313. package/src/motion/flip.tsx +87 -0
  314. package/src/motion/glide.tsx +47 -0
  315. package/src/motion/motion-timing.ts +33 -0
  316. package/src/motion/presence-context.ts +18 -0
  317. package/src/motion/presence.tsx +91 -0
  318. package/src/motion/timing.ts +49 -0
  319. package/src/motion/use-motion.ts +64 -0
  320. package/src/styles.css +26 -0
  321. package/src/tokens/avatar.css +20 -0
  322. package/src/tokens/color.css +58 -0
  323. package/src/tokens/elevation.css +22 -0
  324. package/src/tokens/fonts.css +3 -0
  325. package/src/tokens/glass.css +20 -0
  326. package/src/tokens/icons.css +7 -0
  327. package/src/tokens/layers.css +6 -0
  328. package/src/tokens/motion-scale.ts +17 -0
  329. package/src/tokens/motion-tokens.ts +92 -0
  330. package/src/tokens/motion.css +49 -0
  331. package/src/tokens/radius.css +11 -0
  332. package/src/tokens/semantic.css +65 -0
  333. package/src/tokens/spacing.css +26 -0
  334. package/src/tokens/typography.css +52 -0
@@ -0,0 +1,200 @@
1
+ /* Avatar (image - initials - icon) + AvatarGroup - face/status structure, token sizes, 6 identity slots. */
2
+
3
+ .avatar {
4
+ --avatar-size: 2rem;
5
+ --avatar-bg: var(--bg-muted);
6
+ --avatar-fg: var(--text-muted);
7
+ /* --avatar-ring: injected by .avatar-group, cascades to .avatar__face */
8
+
9
+ position: relative;
10
+ display: inline-flex;
11
+ flex: none;
12
+ vertical-align: middle;
13
+ width: var(--avatar-size);
14
+ height: var(--avatar-size);
15
+ }
16
+
17
+ .avatar__face {
18
+ width: 100%;
19
+ height: 100%;
20
+ border-radius: var(--radius-full);
21
+ overflow: hidden;
22
+
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+
27
+ background: var(--avatar-bg);
28
+ color: var(--avatar-fg);
29
+
30
+ /* sheen from top, shade from bottom over the slot tint; an image child paints over both (section B3 gradient exception) */
31
+ background:
32
+ linear-gradient(to bottom, var(--avatar-sheen), transparent 55%),
33
+ linear-gradient(to top, var(--avatar-shade), transparent 45%), var(--avatar-bg);
34
+
35
+ /* Crisp 1px edge-catch + optional group separator ring via cascade */
36
+ box-shadow:
37
+ inset 0 1px 0 0 oklch(1 0 0 / 0.5),
38
+ var(--avatar-ring, none);
39
+
40
+ /* keyline keyed to the slot's own hue (fg at low alpha), not uniform black; outline paints above children so it rings photos too */
41
+ outline: var(--border-hairline) solid color-mix(in oklch, var(--avatar-fg) 18%, transparent);
42
+ outline-offset: -1px;
43
+
44
+ transition: box-shadow var(--duration-fast) var(--ease-standard);
45
+ }
46
+
47
+ .avatar__img {
48
+ display: block;
49
+ width: 100%;
50
+ height: 100%;
51
+ object-fit: cover;
52
+ }
53
+
54
+ /* lettermark, ratio-sized (section A7 exception); text-box trim = true optical centering; negative margin returns the trailing --tracking-caps so the pair stays centered */
55
+ .avatar__initials {
56
+ font-family: var(--font-sans);
57
+ font-weight: var(--weight-semibold);
58
+ font-size: calc(var(--avatar-size) * 0.42);
59
+ line-height: 1;
60
+ text-box: trim-both cap alphabetic;
61
+ letter-spacing: var(--tracking-caps);
62
+ margin-right: calc(-1 * var(--tracking-caps));
63
+ text-transform: uppercase;
64
+ user-select: none;
65
+ -webkit-user-select: none;
66
+ }
67
+
68
+ .avatar__icon {
69
+ display: flex;
70
+ align-items: center;
71
+ justify-content: center;
72
+ width: 56%;
73
+ height: 56%;
74
+ opacity: 0.5;
75
+ }
76
+ .avatar__icon svg {
77
+ display: block;
78
+ width: 100%;
79
+ height: 100%;
80
+ }
81
+
82
+ .avatar--xs {
83
+ --avatar-size: 1.25rem;
84
+ }
85
+ .avatar--sm {
86
+ --avatar-size: 1.5rem;
87
+ }
88
+ .avatar--lg {
89
+ --avatar-size: 2.5rem;
90
+ }
91
+ .avatar--xl {
92
+ --avatar-size: 3rem;
93
+ }
94
+
95
+ /* square - radius scales with size (concentric nesting) */
96
+ .avatar--square .avatar__face {
97
+ border-radius: var(--radius-md);
98
+ }
99
+
100
+ .avatar--square.avatar--lg .avatar__face,
101
+ .avatar--square.avatar--xl .avatar__face {
102
+ border-radius: var(--radius-lg);
103
+ }
104
+
105
+ /* data-palette 1-6: identity slots (tokens/avatar.css); no attr = neutral; identity colouring, never status */
106
+
107
+ .avatar[data-palette='1'] {
108
+ --avatar-bg: var(--avatar-1-bg);
109
+ --avatar-fg: var(--avatar-1-fg);
110
+ }
111
+ .avatar[data-palette='2'] {
112
+ --avatar-bg: var(--avatar-2-bg);
113
+ --avatar-fg: var(--avatar-2-fg);
114
+ }
115
+ .avatar[data-palette='3'] {
116
+ --avatar-bg: var(--avatar-3-bg);
117
+ --avatar-fg: var(--avatar-3-fg);
118
+ }
119
+ .avatar[data-palette='4'] {
120
+ --avatar-bg: var(--avatar-4-bg);
121
+ --avatar-fg: var(--avatar-4-fg);
122
+ }
123
+ .avatar[data-palette='5'] {
124
+ --avatar-bg: var(--avatar-5-bg);
125
+ --avatar-fg: var(--avatar-5-fg);
126
+ }
127
+ .avatar[data-palette='6'] {
128
+ --avatar-bg: var(--avatar-6-bg);
129
+ --avatar-fg: var(--avatar-6-fg);
130
+ }
131
+
132
+ /* status dot lives outside .avatar__face (which clips) so it's never cut; ~27% of size, min 6px */
133
+
134
+ .avatar__status {
135
+ position: absolute;
136
+ bottom: 0;
137
+ right: 0;
138
+
139
+ width: calc(var(--avatar-size) * 0.275);
140
+ height: calc(var(--avatar-size) * 0.275);
141
+ min-width: 6px;
142
+ min-height: 6px;
143
+
144
+ border-radius: var(--radius-full);
145
+ box-shadow: 0 0 0 2px var(--bg-surface);
146
+ transition: background-color var(--duration-fast) var(--ease-standard);
147
+ }
148
+
149
+ .avatar__status--online {
150
+ background: var(--success);
151
+ }
152
+ .avatar__status--away {
153
+ background: var(--warning);
154
+ }
155
+ .avatar__status--busy {
156
+ background: var(--danger);
157
+ }
158
+ .avatar__status--offline {
159
+ background: var(--border-strong);
160
+ }
161
+
162
+ .avatar-group {
163
+ display: inline-flex;
164
+ align-items: center;
165
+ }
166
+
167
+ /* inject --avatar-ring on group children - cascades to .avatar__face */
168
+ .avatar-group > .avatar {
169
+ --avatar-ring: 0 0 0 2px var(--bg-surface);
170
+ }
171
+
172
+ .avatar-group > .avatar + .avatar {
173
+ margin-left: calc(var(--avatar-size) * -0.3);
174
+ transition: margin-left var(--duration-base) var(--ease-entrance);
175
+ }
176
+
177
+ .avatar-group:hover > .avatar + .avatar {
178
+ margin-left: var(--space-1);
179
+ }
180
+
181
+ /* "+N" chip - mono numerals, tracking off (mono is already spaced), smaller ratio to fit "+12" */
182
+ .avatar--overflow .avatar__initials {
183
+ font-family: var(--font-mono);
184
+ font-variant-numeric: tabular-nums;
185
+ font-size: calc(var(--avatar-size) * 0.36);
186
+ letter-spacing: var(--tracking-normal);
187
+ margin-right: 0;
188
+ }
189
+
190
+ @media (prefers-reduced-motion: reduce) {
191
+ .avatar__face {
192
+ transition: none;
193
+ }
194
+ .avatar__status {
195
+ transition: none;
196
+ }
197
+ .avatar-group > .avatar + .avatar {
198
+ transition: none;
199
+ }
200
+ }
@@ -0,0 +1,35 @@
1
+ import * as react from 'react';
2
+ import { ReactNode, CSSProperties, HTMLAttributes } from 'react';
3
+ import { D as DataAttributes } from './dom-props-C0jrllBw.js';
4
+
5
+ type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
6
+ type AvatarShape = 'circle' | 'square';
7
+ type AvatarStatus = 'online' | 'away' | 'busy' | 'offline';
8
+ type AvatarPaletteIndex = 1 | 2 | 3 | 4 | 5 | 6;
9
+ interface AvatarOwnProps {
10
+ /** Image URL. Falls back to initials / icon / silhouette if absent or fails. */
11
+ src?: string | null;
12
+ /** Display name - drives initials generation, palette hash, and aria-label. */
13
+ name?: string | null;
14
+ /** Content override - any React node (e.g. <Icon name="globe" />). */
15
+ icon?: ReactNode | null;
16
+ /** 'circle' for people; 'square' for channels / brand pages. Default 'circle'. */
17
+ shape?: AvatarShape;
18
+ /** Size step. Default 'md' (32 px). */
19
+ size?: AvatarSize;
20
+ /** Presence indicator dot at bottom-right. Default null (hidden). */
21
+ status?: AvatarStatus | null;
22
+ /** Override identity slot 1-6 (blue - violet - plum - rose - clay - moss); auto from name hash when null, neutral when anonymous. */
23
+ paletteIndex?: AvatarPaletteIndex | null;
24
+ /** Extra class(es) merged onto the root. */
25
+ className?: string;
26
+ /** Inline styles merged onto the root. */
27
+ style?: CSSProperties;
28
+ }
29
+ interface AvatarProps extends AvatarOwnProps {
30
+ /** Standard <span> attributes (onClick, title, data-*, ...) forwarded to the root. */
31
+ htmlProps?: Omit<HTMLAttributes<HTMLSpanElement>, keyof AvatarOwnProps> & DataAttributes;
32
+ }
33
+ declare function Avatar({ src, name, icon, shape, size, status, paletteIndex, className, style, htmlProps, }: AvatarProps): react.JSX.Element;
34
+
35
+ export { Avatar, type AvatarPaletteIndex, type AvatarProps, type AvatarShape, type AvatarSize, type AvatarStatus };
package/dist/avatar.js ADDED
@@ -0,0 +1,67 @@
1
+ 'use client';import { cx } from './chunk-QGNC7LH5.js';
2
+ import './avatar.css';
3
+ import { useState } from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var PALETTE_SLOTS = 6;
7
+ function hashName(str) {
8
+ let h = 0;
9
+ for (let i = 0; i < str.length; i++) h = (h << 5) - h + str.charCodeAt(i) | 0;
10
+ return Math.abs(h) % PALETTE_SLOTS + 1;
11
+ }
12
+ function initialsOf(name, max) {
13
+ if (!name) return "";
14
+ const parts = name.trim().split(/\s+/).filter(Boolean);
15
+ if (parts.length === 0) return "";
16
+ if (parts.length === 1 || max === 1) return parts[0][0].toUpperCase();
17
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
18
+ }
19
+ function Silhouette() {
20
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [
21
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "8.5", r: "3.8", fill: "currentColor" }),
22
+ /* @__PURE__ */ jsx("path", { d: "M4 20.5C4 16.1 7.6 13 12 13s8 3.1 8 7.5", fill: "currentColor", opacity: "0.65" })
23
+ ] });
24
+ }
25
+ function Avatar({
26
+ src = null,
27
+ name = null,
28
+ icon = null,
29
+ shape = "circle",
30
+ size = "md",
31
+ status = null,
32
+ paletteIndex = null,
33
+ className = "",
34
+ style = {},
35
+ htmlProps
36
+ }) {
37
+ const [imgError, setImgError] = useState(false);
38
+ const showImg = Boolean(src) && !imgError;
39
+ const maxInits = size === "xs" ? 1 : 2;
40
+ const inits = initialsOf(name, maxInits);
41
+ const slot = paletteIndex ?? (name ? hashName(name) : null);
42
+ const cls = cx("avatar", size !== "md" && `avatar--${size}`, shape === "square" && "avatar--square", className);
43
+ return /* @__PURE__ */ jsxs(
44
+ "span",
45
+ {
46
+ className: cls,
47
+ role: name ? "img" : void 0,
48
+ "aria-label": name || void 0,
49
+ "data-palette": !showImg && slot != null ? slot : void 0,
50
+ style,
51
+ ...htmlProps,
52
+ children: [
53
+ /* @__PURE__ */ jsxs("span", { className: "avatar__face", children: [
54
+ showImg && /* @__PURE__ */ jsx("img", { className: "avatar__img", src, alt: name || "", onError: () => setImgError(true), draggable: false }),
55
+ !showImg && icon && /* @__PURE__ */ jsx("span", { className: "avatar__icon", "aria-hidden": "true", children: icon }),
56
+ !showImg && !icon && inits && /* @__PURE__ */ jsx("span", { className: "avatar_initialsOf", "aria-hidden": "true", children: inits }),
57
+ !showImg && !icon && !inits && /* @__PURE__ */ jsx("span", { className: "avatar__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx(Silhouette, {}) })
58
+ ] }),
59
+ status && /* @__PURE__ */ jsx("span", { className: `avatar__status avatar__status--${status}`, role: "img", "aria-label": status, title: status })
60
+ ]
61
+ }
62
+ );
63
+ }
64
+
65
+ export { Avatar };
66
+ //# sourceMappingURL=avatar.js.map
67
+ //# sourceMappingURL=avatar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/primitives/avatar/Avatar.tsx"],"names":[],"mappings":"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","file":"avatar.js","sourcesContent":["'use client';\n\nimport './avatar.css';\nimport { useState, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react';\nimport type { DataAttributes } from '../../../dom-props';\nimport { cx } from '../../internal/utils/cx';\n\nexport type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\nexport type AvatarShape = 'circle' | 'square';\nexport type AvatarStatus = 'online' | 'away' | 'busy' | 'offline';\nexport type AvatarPaletteIndex = 1 | 2 | 3 | 4 | 5 | 6;\n\ninterface AvatarOwnProps {\n /** Image URL. Falls back to initials / icon / silhouette if absent or fails. */\n src?: string | null;\n /** Display name - drives initials generation, palette hash, and aria-label. */\n name?: string | null;\n /** Content override - any React node (e.g. <Icon name=\"globe\" />). */\n icon?: ReactNode | null;\n /** 'circle' for people; 'square' for channels / brand pages. Default 'circle'. */\n shape?: AvatarShape;\n /** Size step. Default 'md' (32 px). */\n size?: AvatarSize;\n /** Presence indicator dot at bottom-right. Default null (hidden). */\n status?: AvatarStatus | null;\n /** Override identity slot 1-6 (blue - violet - plum - rose - clay - moss); auto from name hash when null, neutral when anonymous. */\n paletteIndex?: AvatarPaletteIndex | null;\n /** Extra class(es) merged onto the root. */\n className?: string;\n /** Inline styles merged onto the root. */\n style?: CSSProperties;\n}\n\nexport interface AvatarProps extends AvatarOwnProps {\n /** Standard <span> attributes (onClick, title, data-*, ...) forwarded to the root. */\n htmlProps?: Omit<HTMLAttributes<HTMLSpanElement>, keyof AvatarOwnProps> & DataAttributes;\n}\n\nconst PALETTE_SLOTS = 6;\n\nfunction hashName(str: string) {\n let h = 0;\n for (let i = 0; i < str.length; i++) h = ((h << 5) - h + str.charCodeAt(i)) | 0;\n return (Math.abs(h) % PALETTE_SLOTS) + 1;\n}\n\nfunction initialsOf(name: string | null, max: number) {\n if (!name) return '';\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return '';\n if (parts.length === 1 || max === 1) return parts[0][0].toUpperCase();\n return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();\n}\n\nfunction Silhouette() {\n return (\n <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"8.5\" r=\"3.8\" fill=\"currentColor\" />\n <path d=\"M4 20.5C4 16.1 7.6 13 12 13s8 3.1 8 7.5\" fill=\"currentColor\" opacity=\"0.65\" />\n </svg>\n );\n}\n\nexport function Avatar({\n src = null,\n name = null,\n icon = null,\n shape = 'circle',\n size = 'md',\n status = null,\n paletteIndex = null,\n className = '',\n style = {},\n htmlProps,\n}: AvatarProps) {\n const [imgError, setImgError] = useState(false);\n const showImg = Boolean(src) && !imgError;\n\n const maxInits = size === 'xs' ? 1 : 2;\n const inits = initialsOf(name, maxInits);\n const slot = paletteIndex ?? (name ? hashName(name) : null);\n\n const cls = cx('avatar', size !== 'md' && `avatar--${size}`, shape === 'square' && 'avatar--square', className);\n\n return (\n <span\n className={cls}\n role={name ? 'img' : undefined}\n aria-label={name || undefined}\n data-palette={!showImg && slot != null ? slot : undefined}\n style={style}\n {...htmlProps}\n >\n <span className=\"avatar__face\">\n {showImg && (\n <img className=\"avatar__img\" src={src} alt={name || ''} onError={() => setImgError(true)} draggable={false} />\n )}\n {!showImg && icon && (\n <span className=\"avatar__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n {!showImg && !icon && inits && (\n <span className=\"avatar_initialsOf\" aria-hidden=\"true\">\n {inits}\n </span>\n )}\n {!showImg && !icon && !inits && (\n <span className=\"avatar__icon\" aria-hidden=\"true\">\n <Silhouette />\n </span>\n )}\n </span>\n\n {status && (\n <span className={`avatar__status avatar__status--${status}`} role=\"img\" aria-label={status} title={status} />\n )}\n </span>\n );\n}\n"]}
package/dist/badge.css ADDED
@@ -0,0 +1,182 @@
1
+ /* Badge / status pill - shape, tones, dot, status morph. */
2
+
3
+ .badge {
4
+ /* wire the tone vars into the glass surface hooks */
5
+ --glass-fg: var(--badge-fg);
6
+ --glass-tint: var(--badge-tint);
7
+
8
+ display: inline-flex;
9
+ align-items: center;
10
+ gap: var(--space-1);
11
+ padding-block: var(--space-1);
12
+ padding-inline: var(--space-2);
13
+ border-radius: var(--radius-sm);
14
+
15
+ font-family: var(--font-mono);
16
+ font-size: var(--size-micro);
17
+ line-height: var(--leading-micro);
18
+ font-weight: var(--weight-medium);
19
+ font-variant-numeric: tabular-nums;
20
+ letter-spacing: 0;
21
+ white-space: nowrap;
22
+ vertical-align: middle;
23
+ color: var(--badge-fg);
24
+ user-select: none;
25
+ -webkit-user-select: none;
26
+ }
27
+
28
+ .badge--sm {
29
+ padding-block: var(--space-px);
30
+ gap: var(--space-px);
31
+ }
32
+
33
+ .badge--pill {
34
+ border-radius: var(--radius-full);
35
+ }
36
+
37
+ .badge__dot {
38
+ position: relative;
39
+ width: 0.5em;
40
+ height: 0.5em;
41
+ flex: none;
42
+ border-radius: var(--radius-full);
43
+ background: var(--badge-dot, var(--badge-fg));
44
+ /* hue cross-fades as the status morphs */
45
+ transition: background-color var(--duration-base) var(--ease-standard);
46
+ }
47
+ .badge__dot--live::after {
48
+ content: '';
49
+ position: absolute;
50
+ inset: 0;
51
+ border-radius: inherit;
52
+ background: inherit;
53
+ animation: badge-pulse var(--duration-pulse) var(--ease-entrance) infinite;
54
+ }
55
+ @keyframes badge-pulse {
56
+ 0% {
57
+ transform: scale(1);
58
+ opacity: 0.5;
59
+ }
60
+ 70% {
61
+ transform: scale(2.6);
62
+ opacity: 0;
63
+ }
64
+ 100% {
65
+ transform: scale(2.6);
66
+ opacity: 0;
67
+ }
68
+ }
69
+
70
+ .badge__icon {
71
+ display: inline-flex;
72
+ flex: none;
73
+ width: 1em;
74
+ height: 1em;
75
+ margin-left: calc(var(--space-px) * -1);
76
+ }
77
+ .badge__icon svg {
78
+ display: block;
79
+ width: 100%;
80
+ height: 100%;
81
+ }
82
+
83
+ .badge--neutral {
84
+ --badge-fg: var(--text-muted);
85
+ --badge-tint: var(--glass-tint-neutral);
86
+ --badge-dot: var(--gray-500);
87
+ }
88
+ .badge--info {
89
+ --badge-fg: var(--info-text);
90
+ --badge-tint: var(--glass-tint-info);
91
+ --badge-dot: var(--info);
92
+ }
93
+ .badge--success {
94
+ --badge-fg: var(--success-text);
95
+ --badge-tint: var(--glass-tint-success);
96
+ --badge-dot: var(--success);
97
+ }
98
+ .badge--warning {
99
+ --badge-fg: var(--warning-text);
100
+ --badge-tint: var(--glass-tint-warning);
101
+ --badge-dot: var(--warning);
102
+ }
103
+ .badge--danger {
104
+ --badge-fg: var(--danger-text);
105
+ --badge-tint: var(--glass-tint-danger);
106
+ --badge-dot: var(--danger);
107
+ }
108
+
109
+ /* Outline variant - deliberately NOT glass: a flat, engraved hairline chip. */
110
+ .badge--outline {
111
+ position: relative;
112
+ isolation: isolate;
113
+ background: color-mix(in oklab, var(--badge-fg) 6%, transparent);
114
+ box-shadow:
115
+ inset 0 0 0 var(--border-hairline) color-mix(in oklab, var(--badge-fg) 30%, transparent),
116
+ inset 0 1px 0 0 rgb(255 255 255 / 0.5),
117
+ var(--shadow-xs);
118
+ transition:
119
+ transform var(--duration-base) var(--ease-standard),
120
+ box-shadow var(--duration-base) var(--ease-standard),
121
+ background-color var(--duration-fast) var(--ease-standard);
122
+ }
123
+ .badge--outline .badge__dot {
124
+ box-shadow: 0 0 0 2.5px color-mix(in oklab, var(--badge-dot) 16%, transparent);
125
+ }
126
+ .badge--outline:hover {
127
+ transform: translateY(calc(var(--space-px) * -1));
128
+ box-shadow:
129
+ inset 0 0 0 var(--border-hairline) color-mix(in oklab, var(--badge-fg) 42%, transparent),
130
+ inset 0 1px 0 0 rgb(255 255 255 / 0.6),
131
+ var(--shadow-sm);
132
+ }
133
+
134
+ /* Status morph - a clipped one-cell grid stack: the ghost measures the next width, the box eases, words roll; shrink mirrors grow. */
135
+ .badge__morph {
136
+ position: relative;
137
+ display: inline-grid;
138
+ align-items: center;
139
+ justify-items: start;
140
+ overflow: hidden;
141
+ transition: width var(--duration-base) var(--ease-entrance);
142
+ }
143
+ .badge__morph > * {
144
+ grid-area: 1 / 1;
145
+ }
146
+ .badge__ghost {
147
+ visibility: hidden;
148
+ pointer-events: none;
149
+ }
150
+ .badge__word {
151
+ display: inline-block;
152
+ transition:
153
+ transform var(--duration-base) var(--ease-entrance),
154
+ opacity var(--duration-base) var(--ease-standard);
155
+ }
156
+ .badge__word--out {
157
+ transform: translateY(-52%);
158
+ opacity: 0;
159
+ }
160
+ .badge__word--in {
161
+ transform: translateY(52%);
162
+ opacity: 0;
163
+ transition: none;
164
+ }
165
+
166
+ @media (prefers-reduced-motion: reduce) {
167
+ .badge--outline {
168
+ transition: none;
169
+ }
170
+ .badge--outline:hover {
171
+ transform: none;
172
+ }
173
+ .badge__dot--live::after {
174
+ animation: none;
175
+ }
176
+ .badge__morph {
177
+ transition: none;
178
+ }
179
+ .badge__word {
180
+ transition: none;
181
+ }
182
+ }
@@ -0,0 +1,34 @@
1
+ import * as react from 'react';
2
+ import { ReactNode, CSSProperties, HTMLAttributes } from 'react';
3
+ import { D as DataAttributes } from './dom-props-C0jrllBw.js';
4
+
5
+ type BadgeTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
6
+ interface BadgeOwnProps {
7
+ /** Status hue. @default 'neutral' */
8
+ tone?: BadgeTone;
9
+ /** Surface. @default 'glass' */
10
+ variant?: 'glass' | 'outline';
11
+ /** @default 'md' */
12
+ size?: 'sm' | 'md';
13
+ /** Leading status dot. */
14
+ dot?: boolean;
15
+ /** Dot pulses (implies dot) - for in-progress status. */
16
+ live?: boolean;
17
+ /** Fully-rounded shape. */
18
+ pill?: boolean;
19
+ /** Optional leading <Icon> (overrides dot if both set). */
20
+ icon?: ReactNode;
21
+ /** Extra class(es) merged onto the chip. */
22
+ className?: string;
23
+ /** Inline styles merged onto the chip. */
24
+ style?: CSSProperties;
25
+ /** Chip label. */
26
+ children?: ReactNode;
27
+ }
28
+ interface BadgeProps extends BadgeOwnProps {
29
+ /** Standard <span> attributes (aria-*, data-*, title, ...) forwarded to the chip. */
30
+ htmlProps?: Omit<HTMLAttributes<HTMLSpanElement>, keyof BadgeOwnProps> & DataAttributes;
31
+ }
32
+ declare function Badge({ tone, variant, size, dot, live, pill, icon, className, style, children, htmlProps, }: BadgeProps): react.JSX.Element;
33
+
34
+ export { Badge, type BadgeProps, type BadgeTone };
package/dist/badge.js ADDED
@@ -0,0 +1,4 @@
1
+ 'use client';export { Badge } from './chunk-PMECHR3A.js';
2
+ import './chunk-QGNC7LH5.js';
3
+ //# sourceMappingURL=badge.js.map
4
+ //# sourceMappingURL=badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"badge.js"}