@yewdiel21/motion-kit 0.10.0 → 0.15.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 (459) hide show
  1. package/README.md +81 -0
  2. package/bin/motion-kit.mjs +3 -3
  3. package/dist/auto/index.d.ts +56 -3
  4. package/dist/auto/index.js +107 -3
  5. package/dist/auto/index.js.map +1 -1
  6. package/dist/{chunk-XAKC2QY7.js → chunk-6IRJYXJU.js} +3 -28
  7. package/dist/chunk-6IRJYXJU.js.map +1 -0
  8. package/dist/chunk-A6QQCF6V.js +21333 -0
  9. package/dist/chunk-A6QQCF6V.js.map +1 -0
  10. package/dist/chunk-JXRS3OEA.js +3638 -0
  11. package/dist/chunk-JXRS3OEA.js.map +1 -0
  12. package/dist/chunk-QP4QJOEN.js +72 -0
  13. package/dist/chunk-QP4QJOEN.js.map +1 -0
  14. package/dist/css/components/activity-feed.css +240 -0
  15. package/dist/css/components/add-to-cart.css +72 -0
  16. package/dist/css/components/attachment.css +266 -0
  17. package/dist/css/components/bidirectional-slider.css +168 -0
  18. package/dist/css/components/breadcrumb.css +110 -0
  19. package/dist/css/components/chart-tooltip.css +168 -0
  20. package/dist/css/components/chart.css +296 -0
  21. package/dist/css/components/code-block.css +264 -0
  22. package/dist/css/components/color-area.css +82 -0
  23. package/dist/css/components/color-field.css +67 -0
  24. package/dist/css/components/color-picker.css +131 -0
  25. package/dist/css/components/color-slider.css +113 -0
  26. package/dist/css/components/command-search.css +252 -0
  27. package/dist/css/components/context-menu.css +23 -0
  28. package/dist/css/components/credit-card.css +288 -0
  29. package/dist/css/components/data-table.css +686 -0
  30. package/dist/css/components/date-range-picker.css +168 -0
  31. package/dist/css/components/date-time-picker.css +178 -0
  32. package/dist/css/components/drawer.css +58 -0
  33. package/dist/css/components/editable-table.css +201 -0
  34. package/dist/css/components/empty-state.css +61 -0
  35. package/dist/css/components/file-explorer.css +633 -0
  36. package/dist/css/components/filter-builder.css +227 -0
  37. package/dist/css/components/heatmap-chart.css +391 -0
  38. package/dist/css/components/hold-confirm.css +87 -0
  39. package/dist/css/components/hover-card.css +19 -7
  40. package/dist/css/components/image-preview.css +283 -0
  41. package/dist/css/components/json-viewer.css +304 -0
  42. package/dist/css/components/like-button.css +78 -0
  43. package/dist/css/components/link-preview.css +275 -0
  44. package/dist/css/components/loading-button.css +77 -0
  45. package/dist/css/components/multi-select.css +267 -0
  46. package/dist/css/components/nav.css +102 -102
  47. package/dist/css/components/notification-bell.css +127 -0
  48. package/dist/css/components/orbit-menu.css +130 -0
  49. package/dist/css/components/pagination.css +10 -5
  50. package/dist/css/components/password-strength.css +183 -0
  51. package/dist/css/components/pie-chart.css +390 -0
  52. package/dist/css/components/pill-button.css +135 -0
  53. package/dist/css/components/popover.css +25 -0
  54. package/dist/css/components/progress.css +140 -0
  55. package/dist/css/components/questionnaire.css +217 -0
  56. package/dist/css/components/radar-chart.css +370 -0
  57. package/dist/css/components/radial-chart.css +398 -0
  58. package/dist/css/components/range-calendar.css +186 -0
  59. package/dist/css/components/range-slider.css +192 -0
  60. package/dist/css/components/resizable-panel.css +243 -0
  61. package/dist/css/components/rich-text-editor.css +284 -0
  62. package/dist/css/components/sankey-chart.css +358 -0
  63. package/dist/css/components/scratch-card.css +75 -0
  64. package/dist/css/components/scroll-island.css +111 -0
  65. package/dist/css/components/select.css +136 -0
  66. package/dist/css/components/skeleton.css +108 -0
  67. package/dist/css/components/split-view.css +19 -0
  68. package/dist/css/components/star-rating.css +80 -0
  69. package/dist/css/components/stat-card.css +164 -0
  70. package/dist/css/components/swipe-actions.css +105 -0
  71. package/dist/css/components/tag-input.css +244 -0
  72. package/dist/css/components/time-field.css +88 -0
  73. package/dist/css/components/timeline.css +219 -0
  74. package/dist/css/components/toolbar.css +122 -0
  75. package/dist/css/components/tooltip.css +79 -0
  76. package/dist/css/components/tree-view.css +289 -0
  77. package/dist/css/components/virtual-list.css +195 -0
  78. package/dist/css/components/voice-dots.css +70 -0
  79. package/dist/css/tokens.css +185 -181
  80. package/dist/elements/index.d.ts +849 -7
  81. package/dist/elements/index.js +1642 -8
  82. package/dist/elements/index.js.map +1 -1
  83. package/dist/{engine-GDGwQnJE.d.ts → engine-5zRIssTO.d.ts} +11 -1
  84. package/dist/engine-QECQnGz1.d.ts +33 -0
  85. package/dist/index.css +10890 -311
  86. package/dist/index.d.ts +89 -5
  87. package/dist/index.js +273 -9
  88. package/dist/index.js.map +1 -1
  89. package/dist/react/index.d.ts +686 -24
  90. package/dist/react/index.js +2345 -9
  91. package/dist/react/index.js.map +1 -1
  92. package/dist/{reduced-BmBzKH94.d.ts → reduced-6X_bns60.d.ts} +9 -2
  93. package/dist/reveal-BfyKKsw4.d.ts +2474 -0
  94. package/dist/store-CA2Qcun_.d.ts +453 -0
  95. package/package.json +9 -16
  96. package/registry.json +1096 -543
  97. package/src/auto/auto-init.ts +104 -0
  98. package/src/components/activity-feed/README.md +56 -0
  99. package/src/components/activity-feed/activity-feed.css +239 -0
  100. package/src/components/activity-feed/element.ts +36 -0
  101. package/src/components/activity-feed/engine.ts +351 -0
  102. package/src/components/activity-feed/react.tsx +32 -0
  103. package/src/components/add-to-cart/README.md +34 -0
  104. package/src/components/add-to-cart/add-to-cart.css +71 -0
  105. package/src/components/add-to-cart/element.ts +20 -0
  106. package/src/components/add-to-cart/engine.ts +206 -0
  107. package/src/components/add-to-cart/react.tsx +29 -0
  108. package/src/components/attachment/README.md +27 -0
  109. package/src/components/attachment/attachment.css +265 -0
  110. package/src/components/attachment/element.ts +50 -0
  111. package/src/components/attachment/engine.ts +469 -0
  112. package/src/components/attachment/react.tsx +65 -0
  113. package/src/components/bidirectional-slider/README.md +46 -0
  114. package/src/components/bidirectional-slider/bidirectional-slider.css +167 -0
  115. package/src/components/bidirectional-slider/element.ts +42 -0
  116. package/src/components/bidirectional-slider/engine.ts +289 -0
  117. package/src/components/bidirectional-slider/react.tsx +45 -0
  118. package/src/components/breadcrumb/README.md +38 -0
  119. package/src/components/breadcrumb/breadcrumb.css +109 -0
  120. package/src/components/breadcrumb/element.ts +27 -0
  121. package/src/components/breadcrumb/engine.ts +249 -0
  122. package/src/components/breadcrumb/react.tsx +30 -0
  123. package/src/components/chart/README.md +34 -0
  124. package/src/components/chart/chart.css +295 -0
  125. package/src/components/chart/element.ts +43 -0
  126. package/src/components/chart/engine.ts +838 -0
  127. package/src/components/chart/parts.ts +237 -0
  128. package/src/components/chart/react.tsx +50 -0
  129. package/src/components/chart/use-chart.ts +55 -0
  130. package/src/components/chart-tooltip/README.md +53 -0
  131. package/src/components/chart-tooltip/chart-tooltip.css +167 -0
  132. package/src/components/chart-tooltip/element.ts +37 -0
  133. package/src/components/chart-tooltip/engine.ts +442 -0
  134. package/src/components/chart-tooltip/react.tsx +47 -0
  135. package/src/components/code-block/README.md +19 -0
  136. package/src/components/code-block/code-block.css +263 -0
  137. package/src/components/code-block/element.ts +34 -0
  138. package/src/components/code-block/engine.ts +254 -0
  139. package/src/components/code-block/highlight.ts +244 -0
  140. package/src/components/code-block/react.tsx +94 -0
  141. package/src/components/color-area/README.md +50 -0
  142. package/src/components/color-area/color-area.css +81 -0
  143. package/src/components/color-area/element.ts +26 -0
  144. package/src/components/color-area/engine.ts +246 -0
  145. package/src/components/color-area/react.tsx +42 -0
  146. package/src/components/color-field/README.md +43 -0
  147. package/src/components/color-field/color-field.css +66 -0
  148. package/src/components/color-field/element.ts +26 -0
  149. package/src/components/color-field/engine.ts +174 -0
  150. package/src/components/color-field/react.tsx +42 -0
  151. package/src/components/color-picker/README.md +45 -0
  152. package/src/components/color-picker/color-picker.css +130 -0
  153. package/src/components/color-picker/element.ts +45 -0
  154. package/src/components/color-picker/engine.ts +314 -0
  155. package/src/components/color-picker/react.tsx +47 -0
  156. package/src/components/color-slider/README.md +55 -0
  157. package/src/components/color-slider/color-slider.css +112 -0
  158. package/src/components/color-slider/element.ts +26 -0
  159. package/src/components/color-slider/engine.ts +234 -0
  160. package/src/components/color-slider/react.tsx +45 -0
  161. package/src/components/command-search/README.md +15 -0
  162. package/src/components/command-search/command-search.css +251 -0
  163. package/src/components/command-search/element.ts +36 -0
  164. package/src/components/command-search/engine.ts +356 -0
  165. package/src/components/command-search/match.ts +53 -0
  166. package/src/components/command-search/react.tsx +66 -0
  167. package/src/components/context-menu/README.md +31 -0
  168. package/src/components/context-menu/context-menu.css +22 -0
  169. package/src/components/context-menu/element.ts +40 -0
  170. package/src/components/context-menu/engine.ts +153 -0
  171. package/src/components/context-menu/react.tsx +57 -0
  172. package/src/components/credit-card/README.md +20 -0
  173. package/src/components/credit-card/card.ts +77 -0
  174. package/src/components/credit-card/credit-card.css +287 -0
  175. package/src/components/credit-card/element.ts +33 -0
  176. package/src/components/credit-card/engine.ts +410 -0
  177. package/src/components/credit-card/react.tsx +36 -0
  178. package/src/components/data-table/README.md +83 -0
  179. package/src/components/data-table/data-table.css +685 -0
  180. package/src/components/data-table/element.ts +54 -0
  181. package/src/components/data-table/engine.ts +1111 -0
  182. package/src/components/data-table/react.tsx +94 -0
  183. package/src/components/date-range-picker/README.md +51 -0
  184. package/src/components/date-range-picker/date-range-picker.css +167 -0
  185. package/src/components/date-range-picker/element.ts +52 -0
  186. package/src/components/date-range-picker/engine.ts +352 -0
  187. package/src/components/date-range-picker/react.tsx +57 -0
  188. package/src/components/date-time-picker/README.md +48 -0
  189. package/src/components/date-time-picker/date-time-picker.css +177 -0
  190. package/src/components/date-time-picker/element.ts +47 -0
  191. package/src/components/date-time-picker/engine.ts +350 -0
  192. package/src/components/date-time-picker/react.tsx +54 -0
  193. package/src/components/dialog/README.md +103 -102
  194. package/src/components/dialog/element.ts +123 -118
  195. package/src/components/dialog/engine.ts +449 -432
  196. package/src/components/drawer/README.md +28 -0
  197. package/src/components/drawer/drawer.css +57 -0
  198. package/src/components/drawer/element.ts +21 -0
  199. package/src/components/drawer/engine.ts +56 -0
  200. package/src/components/drawer/react.tsx +85 -0
  201. package/src/components/editable-table/README.md +67 -0
  202. package/src/components/editable-table/editable-table.css +200 -0
  203. package/src/components/editable-table/element.ts +45 -0
  204. package/src/components/editable-table/engine.ts +831 -0
  205. package/src/components/editable-table/react.tsx +79 -0
  206. package/src/components/empty-state/README.md +41 -0
  207. package/src/components/empty-state/element.ts +23 -0
  208. package/src/components/empty-state/empty-state.css +60 -0
  209. package/src/components/empty-state/engine.ts +232 -0
  210. package/src/components/empty-state/react.tsx +34 -0
  211. package/src/components/file-explorer/README.md +67 -0
  212. package/src/components/file-explorer/element.ts +39 -0
  213. package/src/components/file-explorer/engine.ts +1307 -0
  214. package/src/components/file-explorer/file-explorer.css +632 -0
  215. package/src/components/file-explorer/react.tsx +77 -0
  216. package/src/components/filter-builder/README.md +47 -0
  217. package/src/components/filter-builder/element.ts +34 -0
  218. package/src/components/filter-builder/engine.ts +396 -0
  219. package/src/components/filter-builder/filter-builder.css +226 -0
  220. package/src/components/filter-builder/react.tsx +36 -0
  221. package/src/components/heatmap-chart/README.md +48 -0
  222. package/src/components/heatmap-chart/element.ts +21 -0
  223. package/src/components/heatmap-chart/engine.ts +281 -0
  224. package/src/components/heatmap-chart/heatmap-chart.css +93 -0
  225. package/src/components/heatmap-chart/react.tsx +14 -0
  226. package/src/components/hold-confirm/README.md +13 -0
  227. package/src/components/hold-confirm/element.ts +24 -0
  228. package/src/components/hold-confirm/engine.ts +216 -0
  229. package/src/components/hold-confirm/hold-confirm.css +86 -0
  230. package/src/components/hold-confirm/react.tsx +28 -0
  231. package/src/components/hover-card/README.md +6 -2
  232. package/src/components/hover-card/engine.ts +98 -7
  233. package/src/components/hover-card/hover-card.css +19 -7
  234. package/src/components/image-preview/README.md +16 -0
  235. package/src/components/image-preview/element.ts +26 -0
  236. package/src/components/image-preview/engine.ts +405 -0
  237. package/src/components/image-preview/image-preview.css +282 -0
  238. package/src/components/image-preview/react.tsx +43 -0
  239. package/src/components/json-viewer/README.md +56 -0
  240. package/src/components/json-viewer/element.ts +37 -0
  241. package/src/components/json-viewer/engine.ts +449 -0
  242. package/src/components/json-viewer/json-viewer.css +303 -0
  243. package/src/components/json-viewer/react.tsx +56 -0
  244. package/src/components/like-button/README.md +13 -0
  245. package/src/components/like-button/element.ts +47 -0
  246. package/src/components/like-button/engine.ts +145 -0
  247. package/src/components/like-button/like-button.css +77 -0
  248. package/src/components/like-button/react.tsx +39 -0
  249. package/src/components/link-preview/README.md +19 -0
  250. package/src/components/link-preview/element.ts +29 -0
  251. package/src/components/link-preview/engine.ts +192 -0
  252. package/src/components/link-preview/link-preview.css +274 -0
  253. package/src/components/link-preview/react.tsx +101 -0
  254. package/src/components/loading-button/README.md +45 -0
  255. package/src/components/loading-button/element.ts +34 -0
  256. package/src/components/loading-button/engine.ts +201 -0
  257. package/src/components/loading-button/loading-button.css +76 -0
  258. package/src/components/loading-button/react.tsx +43 -0
  259. package/src/components/multi-select/README.md +48 -0
  260. package/src/components/multi-select/element.ts +28 -0
  261. package/src/components/multi-select/engine.ts +294 -0
  262. package/src/components/multi-select/multi-select.css +266 -0
  263. package/src/components/multi-select/react.tsx +39 -0
  264. package/src/components/nav/README.md +12 -10
  265. package/src/components/nav/element.ts +5 -5
  266. package/src/components/nav/engine.ts +21 -14
  267. package/src/components/nav/nav.css +102 -102
  268. package/src/components/nav/react.tsx +4 -4
  269. package/src/components/notification-bell/README.md +14 -0
  270. package/src/components/notification-bell/element.ts +48 -0
  271. package/src/components/notification-bell/engine.ts +202 -0
  272. package/src/components/notification-bell/notification-bell.css +126 -0
  273. package/src/components/notification-bell/react.tsx +57 -0
  274. package/src/components/orbit-menu/README.md +46 -0
  275. package/src/components/orbit-menu/element.ts +27 -0
  276. package/src/components/orbit-menu/engine.ts +179 -0
  277. package/src/components/orbit-menu/orbit-menu.css +129 -0
  278. package/src/components/orbit-menu/react.tsx +44 -0
  279. package/src/components/pagination/README.md +1 -1
  280. package/src/components/pagination/engine.ts +50 -4
  281. package/src/components/pagination/pagination.css +10 -5
  282. package/src/components/password-strength/README.md +17 -0
  283. package/src/components/password-strength/element.ts +22 -0
  284. package/src/components/password-strength/engine.ts +212 -0
  285. package/src/components/password-strength/password-strength.css +182 -0
  286. package/src/components/password-strength/react.tsx +36 -0
  287. package/src/components/password-strength/score.ts +62 -0
  288. package/src/components/pie-chart/README.md +48 -0
  289. package/src/components/pie-chart/element.ts +30 -0
  290. package/src/components/pie-chart/engine.ts +283 -0
  291. package/src/components/pie-chart/pie-chart.css +92 -0
  292. package/src/components/pie-chart/react.tsx +14 -0
  293. package/src/components/pill-button/README.md +46 -0
  294. package/src/components/pill-button/element.ts +16 -0
  295. package/src/components/pill-button/engine.ts +77 -0
  296. package/src/components/pill-button/pill-button.css +134 -0
  297. package/src/components/pill-button/react.tsx +32 -0
  298. package/src/components/popover/README.md +44 -0
  299. package/src/components/popover/element.ts +31 -0
  300. package/src/components/popover/engine.ts +114 -0
  301. package/src/components/popover/popover.css +24 -0
  302. package/src/components/popover/react.tsx +50 -0
  303. package/src/components/progress/README.md +17 -0
  304. package/src/components/progress/element.ts +30 -0
  305. package/src/components/progress/engine.ts +173 -0
  306. package/src/components/progress/progress.css +139 -0
  307. package/src/components/progress/react.tsx +35 -0
  308. package/src/components/questionnaire/README.md +32 -0
  309. package/src/components/questionnaire/element.ts +118 -0
  310. package/src/components/questionnaire/engine.ts +255 -0
  311. package/src/components/questionnaire/questionnaire.css +216 -0
  312. package/src/components/questionnaire/react.tsx +140 -0
  313. package/src/components/radar-chart/README.md +48 -0
  314. package/src/components/radar-chart/element.ts +30 -0
  315. package/src/components/radar-chart/engine.ts +327 -0
  316. package/src/components/radar-chart/radar-chart.css +72 -0
  317. package/src/components/radar-chart/react.tsx +14 -0
  318. package/src/components/radial-chart/README.md +48 -0
  319. package/src/components/radial-chart/element.ts +30 -0
  320. package/src/components/radial-chart/engine.ts +290 -0
  321. package/src/components/radial-chart/radial-chart.css +100 -0
  322. package/src/components/radial-chart/react.tsx +14 -0
  323. package/src/components/range-calendar/README.md +58 -0
  324. package/src/components/range-calendar/element.ts +42 -0
  325. package/src/components/range-calendar/engine.ts +390 -0
  326. package/src/components/range-calendar/range-calendar.css +185 -0
  327. package/src/components/range-calendar/react.tsx +56 -0
  328. package/src/components/range-slider/README.md +23 -0
  329. package/src/components/range-slider/element.ts +53 -0
  330. package/src/components/range-slider/engine.ts +316 -0
  331. package/src/components/range-slider/range-slider.css +191 -0
  332. package/src/components/range-slider/react.tsx +66 -0
  333. package/src/components/resizable-panel/README.md +61 -0
  334. package/src/components/resizable-panel/element.ts +36 -0
  335. package/src/components/resizable-panel/engine.ts +551 -0
  336. package/src/components/resizable-panel/react.tsx +74 -0
  337. package/src/components/resizable-panel/resizable-panel.css +242 -0
  338. package/src/components/rich-text-editor/README.md +57 -0
  339. package/src/components/rich-text-editor/element.ts +34 -0
  340. package/src/components/rich-text-editor/engine.ts +673 -0
  341. package/src/components/rich-text-editor/react.tsx +60 -0
  342. package/src/components/rich-text-editor/rich-text-editor.css +283 -0
  343. package/src/components/sankey-chart/README.md +48 -0
  344. package/src/components/sankey-chart/element.ts +31 -0
  345. package/src/components/sankey-chart/engine.ts +401 -0
  346. package/src/components/sankey-chart/react.tsx +14 -0
  347. package/src/components/sankey-chart/sankey-chart.css +60 -0
  348. package/src/components/scratch-card/README.md +15 -0
  349. package/src/components/scratch-card/element.ts +30 -0
  350. package/src/components/scratch-card/engine.ts +257 -0
  351. package/src/components/scratch-card/react.tsx +40 -0
  352. package/src/components/scratch-card/scratch-card.css +74 -0
  353. package/src/components/scroll-island/README.md +34 -0
  354. package/src/components/scroll-island/element.ts +16 -0
  355. package/src/components/scroll-island/engine.ts +252 -0
  356. package/src/components/scroll-island/react.tsx +26 -0
  357. package/src/components/scroll-island/scroll-island.css +110 -0
  358. package/src/components/select/README.md +34 -0
  359. package/src/components/select/element.ts +26 -0
  360. package/src/components/select/engine.ts +267 -0
  361. package/src/components/select/react.tsx +33 -0
  362. package/src/components/select/select.css +135 -0
  363. package/src/components/skeleton/README.md +15 -0
  364. package/src/components/skeleton/element.ts +32 -0
  365. package/src/components/skeleton/engine.ts +104 -0
  366. package/src/components/skeleton/react.tsx +41 -0
  367. package/src/components/skeleton/skeleton.css +107 -0
  368. package/src/components/split-view/README.md +50 -0
  369. package/src/components/split-view/element.ts +34 -0
  370. package/src/components/split-view/engine.ts +114 -0
  371. package/src/components/split-view/react.tsx +63 -0
  372. package/src/components/split-view/split-view.css +18 -0
  373. package/src/components/star-rating/README.md +14 -0
  374. package/src/components/star-rating/element.ts +26 -0
  375. package/src/components/star-rating/engine.ts +217 -0
  376. package/src/components/star-rating/react.tsx +33 -0
  377. package/src/components/star-rating/star-rating.css +79 -0
  378. package/src/components/stat-card/README.md +42 -0
  379. package/src/components/stat-card/element.ts +40 -0
  380. package/src/components/stat-card/engine.ts +283 -0
  381. package/src/components/stat-card/react.tsx +36 -0
  382. package/src/components/stat-card/stat-card.css +163 -0
  383. package/src/components/swipe-actions/README.md +19 -0
  384. package/src/components/swipe-actions/element.ts +26 -0
  385. package/src/components/swipe-actions/engine.ts +260 -0
  386. package/src/components/swipe-actions/react.tsx +80 -0
  387. package/src/components/swipe-actions/swipe-actions.css +104 -0
  388. package/src/components/tag-input/README.md +42 -0
  389. package/src/components/tag-input/element.ts +39 -0
  390. package/src/components/tag-input/engine.ts +313 -0
  391. package/src/components/tag-input/react.tsx +54 -0
  392. package/src/components/tag-input/tag-input.css +243 -0
  393. package/src/components/time-field/README.md +54 -0
  394. package/src/components/time-field/element.ts +38 -0
  395. package/src/components/time-field/engine.ts +110 -0
  396. package/src/components/time-field/react.tsx +45 -0
  397. package/src/components/time-field/time-field.css +87 -0
  398. package/src/components/timeline/README.md +57 -0
  399. package/src/components/timeline/element.ts +31 -0
  400. package/src/components/timeline/engine.ts +300 -0
  401. package/src/components/timeline/react.tsx +59 -0
  402. package/src/components/timeline/timeline.css +218 -0
  403. package/src/components/toolbar/README.md +46 -0
  404. package/src/components/toolbar/element.ts +30 -0
  405. package/src/components/toolbar/engine.ts +230 -0
  406. package/src/components/toolbar/react.tsx +34 -0
  407. package/src/components/toolbar/toolbar.css +121 -0
  408. package/src/components/tooltip/README.md +46 -0
  409. package/src/components/tooltip/element.ts +22 -0
  410. package/src/components/tooltip/engine.ts +288 -0
  411. package/src/components/tooltip/react.tsx +30 -0
  412. package/src/components/tooltip/tooltip.css +78 -0
  413. package/src/components/tree-view/README.md +61 -0
  414. package/src/components/tree-view/element.ts +32 -0
  415. package/src/components/tree-view/engine.ts +743 -0
  416. package/src/components/tree-view/react.tsx +82 -0
  417. package/src/components/tree-view/tree-view.css +288 -0
  418. package/src/components/virtual-list/README.md +81 -0
  419. package/src/components/virtual-list/element.ts +42 -0
  420. package/src/components/virtual-list/engine.ts +678 -0
  421. package/src/components/virtual-list/react.tsx +101 -0
  422. package/src/components/virtual-list/virtual-list.css +194 -0
  423. package/src/components/voice-dots/README.md +48 -0
  424. package/src/components/voice-dots/element.ts +45 -0
  425. package/src/components/voice-dots/engine.ts +243 -0
  426. package/src/components/voice-dots/react.tsx +52 -0
  427. package/src/components/voice-dots/voice-dots.css +69 -0
  428. package/src/core/chips.ts +196 -0
  429. package/src/core/color.ts +304 -0
  430. package/src/core/date-range.ts +67 -0
  431. package/src/core/dates.ts +11 -1
  432. package/src/core/files.ts +107 -0
  433. package/src/core/filter.ts +229 -0
  434. package/src/core/gsap.ts +80 -65
  435. package/src/core/listbox.ts +332 -0
  436. package/src/core/mark.ts +29 -0
  437. package/src/core/position.ts +89 -0
  438. package/src/core/relative-time.ts +77 -0
  439. package/src/core/segment-field.ts +373 -0
  440. package/src/core/segments.ts +153 -0
  441. package/src/core/tree.ts +116 -0
  442. package/src/core/virtual.ts +79 -0
  443. package/src/css/tokens.css +186 -182
  444. package/src/elements/index.ts +186 -0
  445. package/src/index.ts +88 -0
  446. package/src/motion/liquid.ts +14 -4
  447. package/src/motion/micro.ts +248 -0
  448. package/src/motion/sheet.ts +88 -65
  449. package/src/motion/surface.ts +9 -0
  450. package/src/react/index.ts +71 -1
  451. package/dist/chunk-IKQ5FODN.js +0 -1617
  452. package/dist/chunk-IKQ5FODN.js.map +0 -1
  453. package/dist/chunk-J6OCFNGU.js +0 -177
  454. package/dist/chunk-J6OCFNGU.js.map +0 -1
  455. package/dist/chunk-TFNRIZHU.js +0 -3977
  456. package/dist/chunk-TFNRIZHU.js.map +0 -1
  457. package/dist/chunk-XAKC2QY7.js.map +0 -1
  458. package/dist/reveal-jsX-uwUz.d.ts +0 -625
  459. package/dist/store-DYb3tTsZ.d.ts +0 -195
@@ -0,0 +1,32 @@
1
+ 'use client';
2
+ import { useRef, type ButtonHTMLAttributes, type ReactNode } from 'react';
3
+ import { useIsomorphicLayoutEffect } from '../../react/use-recipe';
4
+ import { createPillButton, PILL_ARROW } from './engine';
5
+
6
+ export interface PillButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
7
+ /** Start as the circle and spread into the pill on hover. */
8
+ expand?: boolean;
9
+ /** The icon (default: an arrow). */
10
+ icon?: ReactNode;
11
+ }
12
+
13
+ /** <PillButton onClick={ask}>Haz una pregunta</PillButton> */
14
+ export function PillButton({ expand, icon, className, children, type = 'button', ...props }: PillButtonProps) {
15
+ const ref = useRef<HTMLButtonElement>(null);
16
+ useIsomorphicLayoutEffect(() => {
17
+ const instance = createPillButton(ref.current, { expand });
18
+ return () => instance.destroy();
19
+ }, [expand]);
20
+ return (
21
+ <button {...props} type={type} ref={ref} className={['mk-pill-button', className].filter(Boolean).join(' ')}>
22
+ <span data-mk-pill-label="">{children}</span>
23
+ {icon ? (
24
+ <span data-mk-pill-icon="" aria-hidden="true">
25
+ {icon}
26
+ </span>
27
+ ) : (
28
+ <span data-mk-pill-icon="" aria-hidden="true" dangerouslySetInnerHTML={{ __html: PILL_ARROW }} />
29
+ )}
30
+ </button>
31
+ );
32
+ }
@@ -0,0 +1,44 @@
1
+ # popover
2
+
3
+ Panel flotante interactivo anclado a su botón, sobre la misma superficie que `menu` y `color-picker`: crece desde el botón (transformación de contenedor de `motion/morph.ts`) mientras su contenido entra en cascada como las opciones de un menú (desde 90 % y un blur de 4 px, 40 ms entre piezas), y al cerrar se pliega de vuelta en él. Se cierra con Escape, con un clic fuera o con cualquier `[data-mk-close]` de dentro, y el foco vuelve al botón.
4
+
5
+ Importa también `css/components/dialog.css` (o el CSS completo). La CLI lo copia: la entrada `requires` dialog.
6
+
7
+ ## HTML / Astro
8
+
9
+ ```html
10
+ <mk-popover class="mk-popover">
11
+ <button class="mk-button" data-mk-popover-trigger>Filtros</button>
12
+ <div data-mk-popover-content>
13
+ <label class="mk-field">Estado <select>…</select></label>
14
+ <button class="mk-button mk-button--primary" data-mk-close>Aplicar</button>
15
+ </div>
16
+ </mk-popover>
17
+ ```
18
+
19
+ `[data-mk-popover-content]` pasa a un `<dialog>` que crea el motor y vuelve a su sitio al destruirlo. También puedes escribir directamente `<dialog data-mk-popover-panel>`.
20
+
21
+ ## React
22
+
23
+ ```tsx
24
+ <Popover trigger={<button className="mk-button">Filtros</button>} onOpenChange={setOpen}>
25
+ <FiltersForm />
26
+ </Popover>
27
+ ```
28
+
29
+ Con `open` es controlado. `ref` da `open()` y `close()`.
30
+
31
+ ## Opciones
32
+
33
+ | Opción | Atributo | Por defecto | Qué hace |
34
+ |---|---|---|---|
35
+ | `label` | `label` | el texto del botón | Nombre accesible del panel. |
36
+ | `onOpenChange(open)` | — | — | Al abrirse o cerrarse. |
37
+
38
+ ## API y eventos
39
+
40
+ `open()`, `close()`, `toggle()`, `isOpen`, `panel` (el `<dialog>`), `destroy()`. Evento `mk:open-change` con `{ open }`.
41
+
42
+ ## Estilo
43
+
44
+ Esquinas de 20 px sobre `--mk-surface-1`, tan ancho como su contenido hasta 22rem, con 1rem de relleno. Se estiliza por clase (`.mk-popover-panel`), así la copia que se pliega al cerrar conserva su aspecto. En teléfonos el diálogo anclado se centra. Con movimiento reducido aparece sin crecer.
@@ -0,0 +1,31 @@
1
+ import { MkElement, defineElement, type OptionType } from '../../elements/base';
2
+ import { createPopover, type PopoverInstance } from './engine';
3
+
4
+ /**
5
+ * <mk-popover class="mk-popover">
6
+ * <button data-mk-popover-trigger>Filtros</button>
7
+ * <div data-mk-popover-content>…</div>
8
+ * </mk-popover>
9
+ * Emits mk:open-change ({open}).
10
+ */
11
+ export class MkPopoverElement extends MkElement<PopoverInstance> {
12
+ static options: Record<string, OptionType> = { label: 'string' };
13
+
14
+ protected create(options: Record<string, unknown>) {
15
+ return createPopover(this, options);
16
+ }
17
+
18
+ open() {
19
+ this.instance?.open();
20
+ }
21
+
22
+ close() {
23
+ this.instance?.close();
24
+ }
25
+
26
+ get isOpen() {
27
+ return this.instance?.isOpen ?? false;
28
+ }
29
+ }
30
+
31
+ export const definePopover = () => defineElement('mk-popover', MkPopoverElement);
@@ -0,0 +1,114 @@
1
+ import { createScope } from '../../core/scope';
2
+ import { inert, type Instance } from '../../core/types';
3
+ import { flowInMenu } from '../../motion/entrances';
4
+ import { createDialog } from '../dialog/engine';
5
+
6
+ /*
7
+ * Popover: an interactive panel anchored to its trigger, on the same anchored
8
+ * dialog surface as menu and color-picker. It grows out of the trigger
9
+ * (motion/morph.ts container transform) while its content flows in like a
10
+ * menu's options (from 90 % out of a 4 px blur, 40 ms apart), folds back into
11
+ * the trigger on close, closes with Escape, a click outside or any
12
+ * [data-mk-close] inside, and gives the focus back to the trigger. A
13
+ * dialog[data-mk-popover-panel] is used as it is; [data-mk-popover-content] is
14
+ * moved into a dialog the engine creates and put back on destroy.
15
+ */
16
+
17
+ export interface PopoverOptions {
18
+ /** Accessible name of the panel (default: the trigger's text). */
19
+ label?: string;
20
+ onOpenChange?: (open: boolean) => void;
21
+ }
22
+
23
+ export interface PopoverInstance extends Instance {
24
+ open(): void;
25
+ close(): void;
26
+ toggle(): void;
27
+ readonly isOpen: boolean;
28
+ /** The panel (a <dialog>). */
29
+ readonly panel: HTMLElement | null;
30
+ }
31
+
32
+ let sequence = 0;
33
+
34
+ export function createPopover(root: HTMLElement | null, options: PopoverOptions = {}): PopoverInstance {
35
+ const inertInstance = inert<PopoverInstance>({ open() {}, close() {}, toggle() {}, isOpen: false, panel: null });
36
+ if (!root) return inertInstance;
37
+ let dialog = root.querySelector<HTMLDialogElement>('dialog[data-mk-popover-panel]');
38
+ const content = dialog ? null : root.querySelector<HTMLElement>('[data-mk-popover-content]');
39
+ const trigger =
40
+ root.querySelector<HTMLElement>('[data-mk-popover-trigger]') ??
41
+ [...root.querySelectorAll<HTMLElement>('button, a[href], [role="button"]')].find((element) => !dialog?.contains(element) && !content?.contains(element)) ??
42
+ null;
43
+ if (!trigger || (!dialog && !content)) return inertInstance;
44
+ const scope = createScope();
45
+
46
+ if (!dialog) {
47
+ // The authored content moves into a dialog in its place, and back on destroy.
48
+ const created = document.createElement('dialog');
49
+ const anchor = content!.nextSibling;
50
+ const parent = content!.parentNode!;
51
+ parent.insertBefore(created, content);
52
+ created.append(content!);
53
+ dialog = created;
54
+ scope.add(() => {
55
+ if (content!.isConnected || created.isConnected) parent.insertBefore(content!, created.isConnected ? created : anchor);
56
+ created.remove();
57
+ });
58
+ }
59
+ const panel = dialog;
60
+ // Classes, not only attributes: the copy that folds back into the trigger on close keeps classes only.
61
+ scope.attr(panel, 'class', [panel.getAttribute('class'), 'mk-dialog', 'mk-popover-panel'].filter(Boolean).join(' '));
62
+ if (!panel.id) scope.attr(panel, 'id', `mk-popover-${++sequence}`);
63
+ if (!panel.hasAttribute('aria-label') && !panel.hasAttribute('aria-labelledby')) scope.attr(panel, 'aria-label', options.label ?? trigger.textContent?.trim() ?? 'Panel');
64
+ scope.attr(trigger, 'aria-haspopup', 'dialog');
65
+ scope.attr(trigger, 'aria-expanded', 'false');
66
+ scope.attr(trigger, 'aria-controls', panel.id);
67
+ scope.attr(root, 'data-mk-ready', '');
68
+
69
+ const announce = (open: boolean) => {
70
+ trigger.setAttribute('aria-expanded', String(open));
71
+ options.onOpenChange?.(open);
72
+ root.dispatchEvent(new CustomEvent('mk:open-change', { bubbles: true, detail: { open } }));
73
+ };
74
+ let flow: ReturnType<typeof flowInMenu> = null;
75
+ const surface = createDialog(panel, {
76
+ placement: 'anchor',
77
+ backdrop: false,
78
+ drag: false,
79
+ autoResize: false,
80
+ triggers: false,
81
+ animateContent: false,
82
+ // Like a menu's options: the content flows in while the surface grows out of the trigger.
83
+ onOpen: () => {
84
+ flow?.kill();
85
+ flow = flowInMenu([...panel.children].filter((child) => !child.classList.contains('mk-morph-face')));
86
+ announce(true);
87
+ },
88
+ onClose: () => announce(false),
89
+ });
90
+ scope.add(() => {
91
+ flow?.kill();
92
+ surface.destroy();
93
+ });
94
+
95
+ const open = () => {
96
+ if (!surface.isOpen) surface.open(trigger);
97
+ };
98
+ scope.on(trigger, 'click', (event) => {
99
+ event.preventDefault();
100
+ if (surface.isOpen) surface.close();
101
+ else open();
102
+ });
103
+
104
+ return {
105
+ open,
106
+ close: () => surface.close(),
107
+ toggle: () => (surface.isOpen ? surface.close() : open()),
108
+ get isOpen() {
109
+ return surface.isOpen;
110
+ },
111
+ panel,
112
+ destroy: () => scope.dispose(),
113
+ };
114
+ }
@@ -0,0 +1,24 @@
1
+ /* popover — an anchored .mk-dialog (needs dialog.css): 20 px corners on surface-1, as wide as its content up to
2
+ 22rem, 1rem padding. Styled by class: the copy that folds back into the trigger keeps classes only. */
3
+ .mk-popover,
4
+ mk-popover {
5
+ display: inline-block;
6
+ }
7
+
8
+ .mk-dialog.mk-popover-panel {
9
+ --mk-dialog-radius: 20px;
10
+ --mk-dialog-bg: var(--mk-surface-1);
11
+ --mk-dialog-shadow: 0 16px 48px -12px color-mix(in srgb, var(--mk-shadow-color, #000) 35%, transparent);
12
+ gap: 0.75rem;
13
+ width: max-content;
14
+ min-width: min(14rem, calc(100vw - 32px));
15
+ max-width: min(22rem, calc(100vw - 32px));
16
+ padding: 1rem;
17
+ }
18
+
19
+ /* Phones: the anchored dialog is centred by dialog.css; keep it a panel, not a sheet. */
20
+ @media (max-width: 679px) {
21
+ .mk-dialog.mk-popover-panel {
22
+ max-width: calc(100vw - 32px);
23
+ }
24
+ }
@@ -0,0 +1,50 @@
1
+ 'use client';
2
+ import { forwardRef, useImperativeHandle, useRef, type HTMLAttributes, type ReactNode } from 'react';
3
+ import { useIsomorphicLayoutEffect, useLatest } from '../../react/use-recipe';
4
+ import { createPopover, type PopoverInstance, type PopoverOptions } from './engine';
5
+
6
+ export interface PopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'content'>, PopoverOptions {
7
+ /** The control that opens it (a button). */
8
+ trigger: ReactNode;
9
+ /** Controlled open state (optional). */
10
+ open?: boolean;
11
+ /** Extra class for the panel. */
12
+ panelClassName?: string;
13
+ }
14
+
15
+ export interface PopoverHandle {
16
+ open(): void;
17
+ close(): void;
18
+ }
19
+
20
+ /** <Popover trigger={<button>Filtros</button>}>…</Popover>: the panel grows out of the trigger. */
21
+ export const Popover = forwardRef<PopoverHandle, PopoverProps>(function Popover({ trigger, open, label, onOpenChange, panelClassName, className, children, ...props }, handle) {
22
+ const ref = useRef<HTMLDivElement>(null);
23
+ const instance = useRef<PopoverInstance | null>(null);
24
+ const change = useLatest(onOpenChange);
25
+ useImperativeHandle(handle, () => ({ open: () => instance.current?.open(), close: () => instance.current?.close() }), []);
26
+ useIsomorphicLayoutEffect(() => {
27
+ const created = createPopover(ref.current, { label, onOpenChange: (value) => change.current?.(value) });
28
+ instance.current = created;
29
+ return () => {
30
+ created.destroy();
31
+ instance.current = null;
32
+ };
33
+ // eslint-disable-next-line react-hooks/exhaustive-deps
34
+ }, [label]);
35
+ useIsomorphicLayoutEffect(() => {
36
+ if (open === undefined || !instance.current || instance.current.isOpen === open) return;
37
+ if (open) instance.current.open();
38
+ else instance.current.close();
39
+ }, [open]);
40
+ return (
41
+ <div {...props} ref={ref} className={['mk-popover', className].filter(Boolean).join(' ')}>
42
+ <span data-mk-popover-trigger-slot="" style={{ display: 'contents' }}>
43
+ {trigger}
44
+ </span>
45
+ <dialog data-mk-popover-panel="" className={panelClassName}>
46
+ {children}
47
+ </dialog>
48
+ </div>
49
+ );
50
+ });
@@ -0,0 +1,17 @@
1
+ # progress
2
+
3
+ Barra o anillo de progreso con valor determinado o indeterminado. El anillo sigue el `MetricsRing` de Melon Mind: radio `(tamaño − trazo) / 2`, `stroke-dasharray` derivado del ratio y arranque a las 12.
4
+
5
+ ```html
6
+ <mk-progress class="mk-progress" value="40" label="Subiendo informe" show-value></mk-progress>
7
+ <mk-progress class="mk-progress" variant="ring" value="72" label="Meta mensual" show-value></mk-progress>
8
+ <mk-progress class="mk-progress" label="Procesando"></mk-progress> <!-- indeterminado -->
9
+ ```
10
+
11
+ `defineElements()` desde `/elements`, `createProgress(root, options)` o `<Progress value={42} label="Subida" showValue />` desde `/react`.
12
+
13
+ Opciones: `value` (número o `null` = indeterminado; por defecto `min`), `min=0`, `max=100`, `label` (aria-label), `variant='linear'|'ring'`, `showValue`, `formatValue(value, ratio)` (texto visible y `aria-valuetext`), `duration=.7` (segundos del deslizamiento). API: `setValue(number | null)`, `value`, `destroy()`.
14
+
15
+ El root recibe `role="progressbar"`, `aria-valuemin/max/now` (sin `aria-valuenow` cuando es indeterminado). Valores no finitos se ignoran y los demás se acotan a los límites. No hay región viva: el valor se lee al llegar a la barra, sin anunciar cada cambio.
16
+
17
+ El dibujo es un único hijo decorativo `[data-mk-progress-visual]`; el contenido que ya tenga el root se conserva y `destroy()` restaura atributos y estilos. Al subir o bajar, el relleno (o el arco) se desliza con GSAP, las cifras ruedan, la punta brilla al avanzar, el anillo respira y llegar al máximo lanza un estallido. Variables: `--mk-progress-height` (10px), `--mk-progress-size` (anillo, 4.5rem), `--mk-progress-track`, `--mk-progress-fill`. Movimiento reducido: el valor cambia sin transición y el indeterminado queda como relleno parcial estático.
@@ -0,0 +1,30 @@
1
+ import { MkElement, defineElement, type OptionType } from '../../elements/base';
2
+ import { createProgress, type ProgressInstance } from './engine';
3
+
4
+ /**
5
+ * <mk-progress class="mk-progress" value="40" label="Subida" show-value></mk-progress>
6
+ * Without `value` (or value="indeterminate") it is indeterminate. A new value moves the fill.
7
+ */
8
+ export class MkProgressElement extends MkElement<ProgressInstance> {
9
+ static options: Record<string, OptionType> = { value: 'number', min: 'number', max: 'number', label: 'string', variant: 'string', showValue: 'boolean' };
10
+
11
+ protected create(options: Record<string, unknown>) {
12
+ return createProgress(this, { ...options, value: typeof options.value === 'number' ? options.value : null });
13
+ }
14
+
15
+ attributeChangedCallback(name: string, previous: string | null, next: string | null) {
16
+ if (previous === next || !this.instance) return;
17
+ if (name === 'value') this.instance.setValue(next === null || !Number.isFinite(Number(next)) ? null : Number(next));
18
+ else super.attributeChangedCallback(name, previous, next);
19
+ }
20
+
21
+ setValue(value: number | null) {
22
+ this.instance?.setValue(value);
23
+ }
24
+
25
+ get value() {
26
+ return this.instance?.value ?? null;
27
+ }
28
+ }
29
+
30
+ export const defineProgress = () => defineElement('mk-progress', MkProgressElement);
@@ -0,0 +1,173 @@
1
+ import { gsap, EASE, registerMotion } from '../../core/gsap';
2
+ import { reduced } from '../../core/reduced';
3
+ import { createScope } from '../../core/scope';
4
+ import { inert, type Instance } from '../../core/types';
5
+ import { burst, rollDigits } from '../../motion/micro';
6
+
7
+ /*
8
+ * Progress: a bar or a ring (Melon Mind's MetricsRing: radius (size - stroke) / 2,
9
+ * dasharray from the ratio, starting at 12 o'clock). The root is the progressbar;
10
+ * the drawing is one decorative [data-mk-progress-visual] child. ARIA follows a
11
+ * new value at once; the drawing glides to it with GSAP (Melonmind's playful
12
+ * swing, .38,.49,0,1.5): going up, a light runs at the head and the figure rolls
13
+ * up; going down, the figure rolls down. Reaching the maximum fires a small burst.
14
+ * null is indeterminate. Nothing is live: assistive tech reads the value on arrival.
15
+ */
16
+
17
+ export type ProgressVariant = 'linear' | 'ring';
18
+
19
+ export interface ProgressOptions {
20
+ /** Current value; null is indeterminate. Default: min. */
21
+ value?: number | null;
22
+ min?: number;
23
+ max?: number;
24
+ label?: string;
25
+ variant?: ProgressVariant;
26
+ /** Write the percentage beside the bar (inside the ring). */
27
+ showValue?: boolean;
28
+ /** Text for the value (also aria-valuetext). Default: rounded percentage. */
29
+ formatValue?: (value: number, ratio: number) => string;
30
+ /** Glide duration in seconds (default .7). */
31
+ duration?: number;
32
+ }
33
+
34
+ export interface ProgressInstance extends Instance {
35
+ setValue(value: number | null): void;
36
+ readonly value: number | null;
37
+ }
38
+
39
+ const SVG = 'http://www.w3.org/2000/svg';
40
+ const RING_SIZE = 48;
41
+ const RING_STROKE = 5;
42
+ const RADIUS = (RING_SIZE - RING_STROKE) / 2;
43
+ const CIRCUMFERENCE = 2 * Math.PI * RADIUS;
44
+
45
+ const finite = (value: unknown): value is number => typeof value === 'number' && Number.isFinite(value);
46
+
47
+ export function createProgress(root: HTMLElement | null, options: ProgressOptions = {}): ProgressInstance {
48
+ if (!root) return inert({ setValue() {}, value: null });
49
+ registerMotion();
50
+ const scope = createScope();
51
+ const min = finite(options.min) ? options.min : 0;
52
+ const max = finite(options.max) && options.max > min ? options.max : Math.max(min + 1, 100);
53
+ const variant: ProgressVariant = options.variant === 'ring' ? 'ring' : 'linear';
54
+ const duration = finite(options.duration) ? Math.max(0, options.duration) : 0.7;
55
+ const clamp = (n: number) => Math.min(max, Math.max(min, n));
56
+ let value: number | null = options.value === null ? null : clamp(finite(options.value) ? options.value : min);
57
+
58
+ const visual = document.createElement('span');
59
+ visual.dataset.mkProgressVisual = '';
60
+ visual.setAttribute('aria-hidden', 'true');
61
+ let arc: SVGCircleElement | null = null;
62
+ let head: HTMLElement | null = null;
63
+ let ring: SVGSVGElement | null = null;
64
+ if (variant === 'ring') {
65
+ ring = document.createElementNS(SVG, 'svg');
66
+ ring.setAttribute('viewBox', `0 0 ${RING_SIZE} ${RING_SIZE}`);
67
+ ring.dataset.mkPart = 'ring';
68
+ const circle = (part: string) => {
69
+ const element = document.createElementNS(SVG, 'circle');
70
+ element.setAttribute('cx', String(RING_SIZE / 2));
71
+ element.setAttribute('cy', String(RING_SIZE / 2));
72
+ element.setAttribute('r', String(RADIUS));
73
+ element.setAttribute('fill', 'none');
74
+ element.setAttribute('stroke-width', String(RING_STROKE));
75
+ element.dataset.mkPart = part;
76
+ ring!.append(element);
77
+ return element;
78
+ };
79
+ circle('track');
80
+ arc = circle('arc');
81
+ arc.setAttribute('stroke-linecap', 'round');
82
+ visual.append(ring);
83
+ } else {
84
+ const track = document.createElement('span');
85
+ track.dataset.mkPart = 'track';
86
+ const bar = document.createElement('span');
87
+ bar.dataset.mkPart = 'bar';
88
+ head = document.createElement('span');
89
+ head.dataset.mkPart = 'head';
90
+ track.append(bar, head);
91
+ visual.append(track);
92
+ }
93
+ const text = options.showValue ? document.createElement('span') : null;
94
+ if (text) {
95
+ text.dataset.mkPart = 'value';
96
+ visual.append(text);
97
+ }
98
+ root.append(visual);
99
+
100
+ scope.attr(root, 'style', root.getAttribute('style'));
101
+ scope.attr(root, 'role', 'progressbar');
102
+ scope.attr(root, 'aria-valuemin', String(min));
103
+ scope.attr(root, 'aria-valuemax', String(max));
104
+ if (options.label) scope.attr(root, 'aria-label', options.label);
105
+ scope.attr(root, 'data-mk-variant', variant);
106
+ scope.attr(root, 'data-mk-ready', '');
107
+
108
+ const ratioOf = (n: number | null) => (n === null ? 0 : (n - min) / (max - min));
109
+ const labelOf = (n: number | null) => (n === null ? '' : options.formatValue ? options.formatValue(n, ratioOf(n)) : `${Math.round(ratioOf(n) * 100)} %`);
110
+ /** What is drawn now (it trails `value` while gliding). */
111
+ const shown = { ratio: ratioOf(value) };
112
+ const draw = () => {
113
+ const ratio = Math.min(1, Math.max(0, shown.ratio));
114
+ root.style.setProperty('--mk-progress', ratio.toFixed(4));
115
+ if (arc) {
116
+ const length = value === null ? CIRCUMFERENCE * 0.25 : CIRCUMFERENCE * ratio;
117
+ arc.setAttribute('stroke-dasharray', `${length.toFixed(2)} ${CIRCUMFERENCE.toFixed(2)}`);
118
+ }
119
+ };
120
+ let glide: gsap.core.Tween | null = null;
121
+ const motion: gsap.core.Animation[] = [];
122
+ scope.add(() => {
123
+ glide?.kill();
124
+ for (const animation of motion.splice(0)) animation.progress(1).kill();
125
+ visual.remove();
126
+ });
127
+
128
+ const render = (previous: number | null, animate: boolean) => {
129
+ const label = labelOf(value);
130
+ scope.attr(root, 'aria-valuenow', value === null ? null : String(value));
131
+ scope.attr(root, 'aria-valuetext', value !== null && options.formatValue ? label : null);
132
+ scope.attr(root, 'data-mk-indeterminate', value === null ? '' : null);
133
+ scope.attr(root, 'data-mk-complete', value !== null && value >= max ? '' : null);
134
+ const target = ratioOf(value);
135
+ const direction: 1 | -1 = previous === null || value === null || value >= previous ? 1 : -1;
136
+ glide?.kill();
137
+ if (!animate || reduced() || value === null || previous === null || duration === 0) {
138
+ shown.ratio = target;
139
+ draw();
140
+ if (text) text.textContent = label;
141
+ return;
142
+ }
143
+ glide = gsap.to(shown, { ratio: target, duration, ease: EASE.swatch, onUpdate: draw });
144
+ if (text) {
145
+ const roll = rollDigits(text, label, direction);
146
+ if (roll) motion.push(roll);
147
+ }
148
+ // Going up: a light runs at the head of the bar; the ring breathes.
149
+ if (direction > 0 && head) motion.push(gsap.fromTo(head, { opacity: 1, scale: 0.4 }, { opacity: 0, scale: 1.6, duration: 0.6, ease: 'power2.out' }));
150
+ if (ring) motion.push(gsap.fromTo(ring, { scale: direction > 0 ? 1.06 : 0.95 }, { scale: 1, duration: 0.5, ease: EASE.click, clearProps: 'scale,transform' }));
151
+ if (value >= max && previous < max) {
152
+ const done = burst(variant === 'ring' ? visual : (text ?? visual), { count: 6, distance: 22, ring: variant === 'ring' });
153
+ if (done) motion.push(done);
154
+ }
155
+ if (motion.length > 12) motion.splice(0, motion.length - 12);
156
+ };
157
+ render(null, false);
158
+
159
+ return {
160
+ setValue(next) {
161
+ if (scope.disposed) return;
162
+ const previous = value;
163
+ if (next === null) value = null;
164
+ else if (finite(next)) value = clamp(next);
165
+ else return;
166
+ render(previous, true);
167
+ },
168
+ get value() {
169
+ return value;
170
+ },
171
+ destroy: () => scope.dispose(),
172
+ };
173
+ }
@@ -0,0 +1,139 @@
1
+ /* progress — Melonmind line: a neutral track, the accent only for the value; a ring (MetricsRing) with the figure inside.
2
+ The fill is drawn from --mk-progress, which the engine glides with GSAP. */
3
+ .mk-progress,
4
+ mk-progress {
5
+ --mk-progress-height: 10px;
6
+ --mk-progress-size: 4.5rem;
7
+ --mk-progress-track: var(--mk-surface-4);
8
+ --mk-progress-fill: var(--mk-accent);
9
+ display: block;
10
+ color: var(--mk-text);
11
+ font-family: var(--mk-font);
12
+ }
13
+
14
+ :is(.mk-progress, mk-progress) [data-mk-progress-visual] {
15
+ display: flex;
16
+ align-items: center;
17
+ gap: 0.875rem;
18
+ }
19
+
20
+ /* Linear */
21
+ :is(.mk-progress, mk-progress) span[data-mk-part='track'] {
22
+ position: relative;
23
+ flex: 1;
24
+ height: var(--mk-progress-height);
25
+ border-radius: var(--mk-radius-full);
26
+ background: var(--mk-progress-track);
27
+ }
28
+
29
+ :is(.mk-progress, mk-progress) [data-mk-part='bar'] {
30
+ position: absolute;
31
+ inset: 0;
32
+ border-radius: inherit;
33
+ background: var(--mk-progress-fill);
34
+ clip-path: inset(0 calc((1 - var(--mk-progress, 0)) * 100%) 0 0 round var(--mk-radius-full));
35
+ }
36
+
37
+ /* The light at the head of the bar (flashes when the value goes up). */
38
+ :is(.mk-progress, mk-progress) [data-mk-part='head'] {
39
+ position: absolute;
40
+ top: 50%;
41
+ left: calc(var(--mk-progress, 0) * 100%);
42
+ width: calc(var(--mk-progress-height) * 2.4);
43
+ aspect-ratio: 1;
44
+ border-radius: 50%;
45
+ background: radial-gradient(circle, color-mix(in srgb, var(--mk-progress-fill) 70%, white) 0%, transparent 70%);
46
+ opacity: 0;
47
+ pointer-events: none;
48
+ translate: -50% -50%;
49
+ }
50
+
51
+ :is(.mk-progress, mk-progress)[data-mk-indeterminate] [data-mk-part='bar'] {
52
+ clip-path: none;
53
+ width: 38%;
54
+ animation: mk-progress-slide 1.4s cubic-bezier(0.65, 0, 0.35, 1) infinite;
55
+ }
56
+
57
+ :is(.mk-progress, mk-progress) [data-mk-part='value'] {
58
+ min-width: 4.5ch;
59
+ color: var(--mk-muted);
60
+ font-size: 0.875rem;
61
+ font-weight: 500;
62
+ font-variant-numeric: tabular-nums;
63
+ text-align: right;
64
+ }
65
+
66
+ :is(.mk-progress, mk-progress)[data-mk-complete] [data-mk-part='value'] {
67
+ color: var(--mk-text);
68
+ }
69
+
70
+ /* Ring */
71
+ :is(.mk-progress, mk-progress)[data-mk-variant='ring'] {
72
+ display: inline-block;
73
+ width: var(--mk-progress-size);
74
+ }
75
+
76
+ :is(.mk-progress, mk-progress)[data-mk-variant='ring'] [data-mk-progress-visual] {
77
+ position: relative;
78
+ display: grid;
79
+ place-items: center;
80
+ aspect-ratio: 1;
81
+ }
82
+
83
+ :is(.mk-progress, mk-progress) [data-mk-part='ring'] {
84
+ grid-area: 1 / 1;
85
+ width: 100%;
86
+ height: 100%;
87
+ overflow: visible;
88
+ rotate: -90deg;
89
+ }
90
+
91
+ :is(.mk-progress, mk-progress) circle[data-mk-part='track'] {
92
+ stroke: var(--mk-progress-track);
93
+ }
94
+
95
+ :is(.mk-progress, mk-progress) [data-mk-part='arc'] {
96
+ stroke: var(--mk-progress-fill);
97
+ }
98
+
99
+ :is(.mk-progress, mk-progress)[data-mk-variant='ring'][data-mk-indeterminate] [data-mk-part='ring'] {
100
+ animation: mk-progress-spin 1.1s linear infinite;
101
+ }
102
+
103
+ :is(.mk-progress, mk-progress)[data-mk-variant='ring'] [data-mk-part='value'] {
104
+ grid-area: 1 / 1;
105
+ min-width: 0;
106
+ color: var(--mk-text);
107
+ font-size: calc(var(--mk-progress-size) * 0.24);
108
+ letter-spacing: -0.02em;
109
+ text-align: center;
110
+ }
111
+
112
+ @keyframes mk-progress-slide {
113
+ from {
114
+ translate: -100% 0;
115
+ }
116
+ to {
117
+ translate: 265% 0;
118
+ }
119
+ }
120
+
121
+ @keyframes mk-progress-spin {
122
+ from {
123
+ rotate: -90deg;
124
+ }
125
+ to {
126
+ rotate: 270deg;
127
+ }
128
+ }
129
+
130
+ /* Reduced motion: values jump; indeterminate becomes a still, partial fill. */
131
+ @media (prefers-reduced-motion: reduce) {
132
+ :is(.mk-progress, mk-progress) :is([data-mk-part='bar'], [data-mk-part='ring']) {
133
+ animation: none !important;
134
+ }
135
+
136
+ :is(.mk-progress, mk-progress)[data-mk-indeterminate] [data-mk-part='bar'] {
137
+ opacity: 0.55;
138
+ }
139
+ }