@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,110 @@
1
+ import { createScope } from '../../core/scope';
2
+ import { registerMotion } from '../../core/gsap';
3
+ import { inert, type Instance } from '../../core/types';
4
+ import { formatTime, parseTime, timeMinutes, to12, to24 } from '../../core/segments';
5
+ import { createSegmentField, type SegmentValues } from '../../core/segment-field';
6
+
7
+ /*
8
+ * Time field: hour, minute (and second) segments in the locale's order, with
9
+ * a.m./p.m. where the locale writes 12 hours. The value is always 24 h text
10
+ * ("13:05"). Arrows step with wrap and the digits roll; typing fills and moves
11
+ * on; a pill glides to the focused segment (core/segment-field.ts). min/max
12
+ * mark the group invalid (one shake when it becomes invalid) but the value is
13
+ * still reported, like a native input.
14
+ */
15
+
16
+ export interface TimeFieldOptions {
17
+ /** 'HH:MM' or 'HH:MM:SS' (24 h). */
18
+ value?: string | null;
19
+ locale?: string;
20
+ /** 12 or 24; default: the locale's. */
21
+ hourCycle?: 12 | 24;
22
+ seconds?: boolean;
23
+ /** Arrow step of the minutes (and seconds). */
24
+ minuteStep?: number;
25
+ min?: string;
26
+ max?: string;
27
+ /** Accessible name of the group (default 'Hora'). */
28
+ label?: string;
29
+ /** Hidden input with the 24 h text. */
30
+ name?: string;
31
+ disabled?: boolean;
32
+ readOnly?: boolean;
33
+ onChange?: (value: string | null) => void;
34
+ }
35
+
36
+ export interface TimeFieldInstance extends Instance {
37
+ setValue(value: string | null, animate?: boolean): void;
38
+ focus(): void;
39
+ readonly value: string | null;
40
+ }
41
+
42
+ export function createTimeField(root: HTMLElement | null, options: TimeFieldOptions = {}): TimeFieldInstance {
43
+ if (!root) return inert({ setValue() {}, focus() {}, value: null });
44
+ registerMotion();
45
+ const scope = createScope();
46
+ const locale = options.locale ?? root.closest('[lang]')?.getAttribute('lang') ?? 'es';
47
+ const seconds = Boolean(options.seconds);
48
+ const step = options.minuteStep && options.minuteStep > 0 ? Math.round(options.minuteStep) : 1;
49
+ const min = parseTime(options.min);
50
+ const max = parseTime(options.max);
51
+ let value: string | null = null;
52
+ let invalid = false;
53
+
54
+ const hidden = options.name ? document.createElement('input') : null;
55
+ const field = createSegmentField(root, {
56
+ kind: 'time',
57
+ locale,
58
+ hour12: options.hourCycle ? options.hourCycle === 12 : undefined,
59
+ seconds,
60
+ steps: { minute: step, second: step },
61
+ disabled: options.disabled,
62
+ readOnly: options.readOnly,
63
+ onChange: (values) => {
64
+ update(values);
65
+ options.onChange?.(value);
66
+ root.dispatchEvent(new CustomEvent('mk:change', { bubbles: true, detail: { value } }));
67
+ },
68
+ });
69
+ scope.add(() => field.destroy());
70
+ field.element.setAttribute('aria-label', options.label ?? 'Hora');
71
+ if (hidden) {
72
+ hidden.type = 'hidden';
73
+ hidden.name = options.name!;
74
+ root.append(hidden);
75
+ scope.add(() => hidden.remove());
76
+ }
77
+ scope.attr(root, 'data-mk-ready', '');
78
+ const twelve = field.element.querySelector('[data-mk-segment="dayPeriod"]') !== null;
79
+
80
+ const update = (values: SegmentValues, initial = false) => {
81
+ const complete = values.hour != null && values.minute != null && (!seconds || values.second != null) && (!twelve || values.dayPeriod != null);
82
+ const time = complete ? { hour: twelve ? to24(values.hour!, values.dayPeriod!) : values.hour!, minute: values.minute!, second: values.second ?? 0 } : null;
83
+ value = time ? formatTime(time, seconds) : null;
84
+ if (hidden) hidden.value = value ?? '';
85
+ const out = !!time && ((!!min && timeMinutes(time) < timeMinutes(min)) || (!!max && timeMinutes(time) > timeMinutes(max)));
86
+ field.invalid(out, out && !invalid && !initial);
87
+ invalid = out;
88
+ };
89
+
90
+ const setValue = (next: string | null, animate = true) => {
91
+ if (scope.disposed) return;
92
+ const time = parseTime(next);
93
+ if (!time) field.setValues({ hour: null, minute: null, second: null, dayPeriod: null }, animate);
94
+ else if (twelve) {
95
+ const { hour, period } = to12(time.hour);
96
+ field.setValues({ hour, dayPeriod: period, minute: time.minute, second: time.second }, animate);
97
+ } else field.setValues({ hour: time.hour, minute: time.minute, second: time.second }, animate);
98
+ update(field.values(), true);
99
+ };
100
+ setValue(options.value ?? null, false);
101
+
102
+ return {
103
+ setValue,
104
+ focus: () => field.focus('first'),
105
+ get value() {
106
+ return value;
107
+ },
108
+ destroy: () => scope.dispose(),
109
+ };
110
+ }
@@ -0,0 +1,45 @@
1
+ 'use client';
2
+ import { useRef, type HTMLAttributes } from 'react';
3
+ import { useIsomorphicLayoutEffect, useLatest } from '../../react/use-recipe';
4
+ import { createTimeField, type TimeFieldInstance, type TimeFieldOptions } from './engine';
5
+
6
+ export interface TimeFieldProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'>, Omit<TimeFieldOptions, 'value'> {
7
+ /** Controlled time ('HH:MM', 24 h); without it the field keeps its own (defaultValue). */
8
+ value?: string | null;
9
+ defaultValue?: string | null;
10
+ }
11
+
12
+ /** <TimeField value={time} onChange={setTime} minuteStep={15} />. */
13
+ export function TimeField({ value, defaultValue, locale, hourCycle, seconds, minuteStep, min, max, label, name, disabled, readOnly, onChange, className, ...props }: TimeFieldProps) {
14
+ const ref = useRef<HTMLDivElement>(null);
15
+ const instance = useRef<TimeFieldInstance | null>(null);
16
+ const change = useLatest(onChange);
17
+ const start = useRef(value !== undefined ? value : (defaultValue ?? null));
18
+ useIsomorphicLayoutEffect(() => {
19
+ const created = createTimeField(ref.current, {
20
+ value: value !== undefined ? value : start.current,
21
+ locale,
22
+ hourCycle,
23
+ seconds,
24
+ minuteStep,
25
+ min,
26
+ max,
27
+ label,
28
+ name,
29
+ disabled,
30
+ readOnly,
31
+ onChange: (next) => change.current?.(next),
32
+ });
33
+ instance.current = created;
34
+ return () => {
35
+ start.current = created.value;
36
+ created.destroy();
37
+ instance.current = null;
38
+ };
39
+ // eslint-disable-next-line react-hooks/exhaustive-deps
40
+ }, [locale, hourCycle, seconds, minuteStep, min, max, label, name, disabled, readOnly]);
41
+ useIsomorphicLayoutEffect(() => {
42
+ if (value !== undefined && instance.current && instance.current.value !== value) instance.current.setValue(value);
43
+ }, [value]);
44
+ return <div {...props} ref={ref} className={['mk-time-field', className].filter(Boolean).join(' ')} />;
45
+ }
@@ -0,0 +1,87 @@
1
+ /* time-field — a 12 px field on surface-3; tabular digits; the focused segment sits on a 6 px accent-soft pill that
2
+ glides between segments; empty segments are muted dashes; invalid draws an error ring. */
3
+ .mk-time-field,
4
+ mk-time-field {
5
+ display: inline-block;
6
+ max-width: 100%;
7
+ }
8
+
9
+ :is(.mk-time-field, mk-time-field) [data-mk-segments] {
10
+ position: relative;
11
+ display: inline-flex;
12
+ align-items: center;
13
+ min-height: 2.75rem;
14
+ padding: 0 0.75rem;
15
+ border-radius: 12px;
16
+ background: var(--mk-surface-3);
17
+ color: var(--mk-text);
18
+ font-variant-numeric: tabular-nums;
19
+ white-space: nowrap;
20
+ transition: box-shadow 0.2s ease;
21
+ }
22
+
23
+ :is(.mk-time-field, mk-time-field) [data-mk-segments]:focus-within {
24
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--mk-accent) 35%, transparent);
25
+ }
26
+
27
+ :is(.mk-time-field, mk-time-field) [data-mk-segments][aria-invalid='true'] {
28
+ box-shadow: 0 0 0 2px var(--mk-error, #d93025);
29
+ }
30
+
31
+ :is(.mk-time-field, mk-time-field) [data-mk-segments][aria-disabled='true'] {
32
+ opacity: 0.5;
33
+ }
34
+
35
+ :is(.mk-time-field, mk-time-field) [data-mk-segment] {
36
+ position: relative;
37
+ z-index: 1;
38
+ padding: 0.2rem 0.15rem;
39
+ border-radius: 6px;
40
+ caret-color: transparent;
41
+ outline: none;
42
+ cursor: default;
43
+ }
44
+
45
+ :is(.mk-time-field, mk-time-field) [data-mk-segment][data-mk-empty] {
46
+ color: var(--mk-muted);
47
+ }
48
+
49
+ :is(.mk-time-field, mk-time-field) [data-mk-segment]:focus {
50
+ color: var(--mk-on-accent-soft, var(--mk-text));
51
+ }
52
+
53
+ :is(.mk-time-field, mk-time-field) [data-mk-segment]::selection {
54
+ background: transparent;
55
+ }
56
+
57
+ :is(.mk-time-field, mk-time-field) [data-mk-segment-literal] {
58
+ padding: 0 0.05rem;
59
+ color: var(--mk-muted);
60
+ }
61
+
62
+ :is(.mk-time-field, mk-time-field) [data-mk-segment-focus] {
63
+ position: absolute;
64
+ top: 50%;
65
+ left: 0;
66
+ height: 1.75rem;
67
+ margin-top: -0.875rem;
68
+ border-radius: 6px;
69
+ background: var(--mk-accent-soft);
70
+ opacity: 0;
71
+ pointer-events: none;
72
+ }
73
+
74
+ /* Without motion the pill is not drawn: the focused segment gets the colour directly. */
75
+ @media (prefers-reduced-motion: reduce) {
76
+ :is(.mk-time-field, mk-time-field) [data-mk-segment]:focus {
77
+ background: var(--mk-accent-soft);
78
+ }
79
+
80
+ :is(.mk-time-field, mk-time-field) [data-mk-segment-focus] {
81
+ display: none;
82
+ }
83
+
84
+ :is(.mk-time-field, mk-time-field) [data-mk-segments] {
85
+ transition: none;
86
+ }
87
+ }
@@ -0,0 +1,57 @@
1
+ # timeline
2
+
3
+ Línea de tiempo para historiales de actividades, cambios y eventos: cada evento es un punto sobre un riel, con su hora («hace 2 h», con la fecha completa en el título; se actualiza cada minuto), un título, una descripción y un dato pequeño. El punto lleva un icono o el color de su estado: hecho, en curso (su anillo respira), pendiente (con borde punteado) o con error. El tramo recorrido del riel se rellena con el acento hasta el evento en curso.
4
+
5
+ Al entrar en pantalla, el riel se dibuja desde el primer punto (.8 s, curva wipe) y los eventos aparecen en cascada saliendo de un blur, 60 ms entre uno y otro. `add()` mete un evento al principio o al final: los demás se deslizan para hacerle sitio (el riel los sigue), el nuevo entra desde un blur, su punto hace pop y un resaltado suave se apaga detrás de él. `update()` lo cambia en su sitio (un estado nuevo vuelve a hacer pop) y `remove()` lo pliega. Con `layout="alternate"`, cuando la línea de tiempo mide 520 px o más, los eventos se reparten a los dos lados del riel; `group` pone cada día como una etiqueta sobre el riel («Hoy», «Ayer», «Lunes, 16 de noviembre»).
6
+
7
+ ## HTML / Astro
8
+
9
+ ```html
10
+ <!-- Eventos en JSON… -->
11
+ <mk-timeline class="mk-timeline" group
12
+ events='[{"id":"1","title":"Pedido recibido","time":"2026-11-23T09:12","status":"done","icon":"✓"},
13
+ {"id":"2","title":"En camino","time":"2026-11-23T14:30","status":"current","description":"Salió de Monterrey"},
14
+ {"id":"3","title":"Entrega","status":"upcoming","meta":"Estimada: jueves"}]'></mk-timeline>
15
+
16
+ <!-- …o escritos: el texto del <li> es el título y el <p>, la descripción. -->
17
+ <mk-timeline class="mk-timeline">
18
+ <ol>
19
+ <li data-status="done" data-time="2026-11-20">Alta de la cuenta<p>Plan Pro, facturación mensual</p></li>
20
+ <li data-status="current" data-time="2026-11-21T10:00" data-icon="★">Primer proyecto</li>
21
+ </ol>
22
+ </mk-timeline>
23
+
24
+ <script>
25
+ const timeline = document.querySelector('mk-timeline');
26
+ timeline.add({ id: '4', title: 'Entregado', status: 'done', time: new Date() });
27
+ </script>
28
+ ```
29
+
30
+ ## React
31
+
32
+ ```tsx
33
+ <Timeline events={history} layout="alternate" group />
34
+ ```
35
+
36
+ Cambiar `events` actualiza en su sitio: un evento nuevo en un extremo entra con su animación, uno que cambia de estado vuelve a colorear su punto y uno que desaparece se pliega.
37
+
38
+ ## Opciones
39
+
40
+ | Opción | Atributo | Por defecto | Qué hace |
41
+ |---|---|---|---|
42
+ | `events` | `events` (JSON) | los `<li>` escritos | `{ id, title, description?, time?, status?, icon?, meta? }[]`; `status`: `done`, `current`, `upcoming` o `error`. |
43
+ | `layout` | `layout` | `'start'` | `'alternate'` reparte los eventos a los dos lados del riel cuando la línea mide 520 px o más. |
44
+ | `group` | `group` | `false` | Un encabezado por día. |
45
+ | `relative` | `relative` | `true` | Horas relativas («hace 5 min»); `false` muestra fecha y hora. |
46
+ | `locale` | `locale` | el `lang` más cercano | Idioma de las fechas. |
47
+ | `label` | `label` | `'Historial'` | Nombre accesible de la lista. |
48
+
49
+ `time` acepta un `Date`, una cadena ISO (`2026-11-23` o `2026-11-23T09:12`) o una marca de tiempo.
50
+
51
+ ## API
52
+
53
+ `add(event, 'start' | 'end')`, `update(id, cambios)`, `remove(id)`, `setEvents(events)`, `events`, `destroy()`.
54
+
55
+ ## Accesibilidad
56
+
57
+ Una lista ordenada con nombre propio; cada hora es un `<time datetime>` con la fecha completa en su título, y el estado de cada evento («En curso», «Pendiente», «Con error») se lee después del título. Los encabezados de día son de presentación. Con movimiento reducido no hay animación de entrada y los cambios ocurren sin transición.
@@ -0,0 +1,31 @@
1
+ import { MkElement, defineElement, type OptionType } from '../../elements/base';
2
+ import { createTimeline, type TimelineEvent, type TimelineInstance } from './engine';
3
+
4
+ /**
5
+ * <mk-timeline class="mk-timeline" events='[{"id":"1","title":"Pedido recibido","time":"2026-11-23T09:12","status":"done"}]'>
6
+ * </mk-timeline> — or authored <ol><li data-status data-time>Title<p>Description</p></li></ol>.
7
+ */
8
+ export class MkTimelineElement extends MkElement<TimelineInstance> {
9
+ static options: Record<string, OptionType> = { events: 'json', layout: 'string', group: 'boolean', relative: 'boolean', locale: 'string', label: 'string' };
10
+
11
+ protected create(options: Record<string, unknown>) {
12
+ return createTimeline(this, options);
13
+ }
14
+
15
+ attributeChangedCallback(name: string, previous: string | null, next: string | null) {
16
+ if (previous === next || !this.instance) return;
17
+ if (name === 'events') {
18
+ try {
19
+ this.instance.setEvents(JSON.parse(next ?? '[]') as TimelineEvent[]);
20
+ } catch {
21
+ // Malformed JSON: keep the current events.
22
+ }
23
+ } else super.attributeChangedCallback(name, previous, next);
24
+ }
25
+
26
+ add(event: TimelineEvent, at?: 'start' | 'end') {
27
+ this.instance?.add(event, at);
28
+ }
29
+ }
30
+
31
+ export const defineTimeline = () => defineElement('mk-timeline', MkTimelineElement);
@@ -0,0 +1,300 @@
1
+ import { gsap, EASE, Flip, registerMotion } from '../../core/gsap';
2
+ import { reduced } from '../../core/reduced';
3
+ import { TIMING } from '../../core/timing';
4
+ import { createScope } from '../../core/scope';
5
+ import { inert, type Instance } from '../../core/types';
6
+ import { dayKey, fromJson } from '../../core/dates';
7
+ import { dayLabel, everyMinute, fullTime, relativeTime, toTime, type TimeInput } from '../../core/relative-time';
8
+ import { blurIn, collapse } from '../../motion/micro';
9
+
10
+ /*
11
+ * Timeline: events in order along a rail — dots with an icon or a state, a
12
+ * time ("hace 2 h", the full date in its title; refreshed every minute), a
13
+ * title, a description and small meta. When it comes into view the rail draws
14
+ * itself from the first dot (.8 s, wipe) and the events cascade in out of a
15
+ * blur (60 ms apart); the done stretch of the rail is filled in the accent up
16
+ * to the current event, whose dot breathes. add() drops an event in at the
17
+ * start or the end: the others glide to make room (layout reflow, the rail
18
+ * following), it comes in out of a blur, its dot pops and a soft highlight
19
+ * fades behind it; update() changes one in place (a new state pops its dot);
20
+ * remove() folds one away. 'alternate' puts the events on both sides of the
21
+ * rail when there is room; `group` heads each day with a chip on the rail.
22
+ */
23
+
24
+ export type TimelineStatus = 'done' | 'current' | 'upcoming' | 'error';
25
+
26
+ export interface TimelineEvent {
27
+ id: string;
28
+ title: string;
29
+ description?: string;
30
+ time?: TimeInput;
31
+ status?: TimelineStatus;
32
+ /** A short glyph in the dot (an emoji or one or two letters). */
33
+ icon?: string;
34
+ /** Small text under it (an author, a place). */
35
+ meta?: string;
36
+ }
37
+
38
+ export interface TimelineOptions {
39
+ events?: TimelineEvent[];
40
+ /** 'start' (default): the rail on the left; 'alternate': both sides on wide screens. */
41
+ layout?: 'start' | 'alternate';
42
+ /** A heading for each day (default false). */
43
+ group?: boolean;
44
+ /** Times as "hace 2 h", refreshed every minute (default true); false shows the date and time. */
45
+ relative?: boolean;
46
+ locale?: string;
47
+ /** Accessible name of the list (default 'Historial'). */
48
+ label?: string;
49
+ }
50
+
51
+ export interface TimelineInstance extends Instance {
52
+ add(event: TimelineEvent, at?: 'start' | 'end'): void;
53
+ update(id: string, patch: Partial<Omit<TimelineEvent, 'id'>>): void;
54
+ remove(id: string): void;
55
+ setEvents(events: TimelineEvent[]): void;
56
+ readonly events: TimelineEvent[];
57
+ }
58
+
59
+ const STATUS_LABEL: Record<TimelineStatus, string> = { done: 'Hecho', current: 'En curso', upcoming: 'Pendiente', error: 'Con error' };
60
+
61
+ /** Events written as <li data-status data-time data-icon>Title<p>description</p></li>. */
62
+ const readAuthored = (root: HTMLElement): TimelineEvent[] =>
63
+ [...root.querySelectorAll<HTMLElement>(':scope > ol > li, :scope > ul > li')].map((item, i) => {
64
+ const description = item.querySelector('p')?.textContent?.trim();
65
+ const title = [...item.childNodes].filter((node) => node.nodeType === Node.TEXT_NODE || (node instanceof HTMLElement && node.tagName !== 'P')).map((node) => node.textContent).join('').trim();
66
+ return {
67
+ id: item.id || `e${i}`,
68
+ title,
69
+ description,
70
+ time: item.dataset.time,
71
+ status: item.dataset.status as TimelineStatus | undefined,
72
+ icon: item.dataset.icon,
73
+ meta: item.dataset.meta,
74
+ };
75
+ });
76
+
77
+ export function createTimeline(root: HTMLElement | null, options: TimelineOptions = {}): TimelineInstance {
78
+ if (!root) return inert({ add() {}, update() {}, remove() {}, setEvents() {}, events: [] });
79
+ registerMotion();
80
+ const scope = createScope();
81
+ const locale = options.locale ?? root.closest('[lang]')?.getAttribute('lang') ?? 'es';
82
+ const relative = options.relative !== false;
83
+ // JSON text too (data-mk-events through autoInit).
84
+ let events = (fromJson(options.events) ?? readAuthored(root)).map((event) => ({ ...event }));
85
+ const effects = new Set<gsap.core.Animation>();
86
+ const keep = (animation: gsap.core.Animation | null) => {
87
+ if (!animation) return;
88
+ effects.add(animation);
89
+ // Finished ones leave as new ones arrive: the animation's own onComplete stays untouched.
90
+ for (const effect of effects) if (effect.totalProgress() === 1) effects.delete(effect);
91
+ };
92
+
93
+ // Authored markup stays, out of sight; the engine draws its own list.
94
+ const holder = document.createElement('div');
95
+ holder.hidden = true;
96
+ holder.append(...root.childNodes);
97
+ const list = document.createElement('ol');
98
+ list.dataset.mkTimelineList = '';
99
+ list.setAttribute('aria-label', options.label ?? 'Historial');
100
+ const rail = document.createElement('span');
101
+ rail.dataset.mkTlRail = '';
102
+ rail.setAttribute('aria-hidden', 'true');
103
+ const progress = document.createElement('span');
104
+ progress.dataset.mkTlProgress = '';
105
+ rail.append(progress);
106
+ const wrap = document.createElement('div');
107
+ wrap.dataset.mkTlWrap = '';
108
+ wrap.append(rail, list);
109
+ root.append(wrap);
110
+ scope.add(() => {
111
+ for (const effect of effects) effect.kill();
112
+ effects.clear();
113
+ wrap.remove();
114
+ root.append(...holder.childNodes);
115
+ });
116
+ scope.attr(root, 'data-mk-layout', options.layout === 'alternate' ? 'alternate' : 'start');
117
+ scope.attr(root, 'data-mk-ready', '');
118
+
119
+ const timeText = (date: Date) => (relative ? relativeTime(date, new Date(), locale) : fullTime(date, locale));
120
+
121
+ const item = (event: TimelineEvent) => {
122
+ const li = document.createElement('li');
123
+ li.dataset.mkTlItem = '';
124
+ li.dataset.id = event.id;
125
+ li.dataset.status = event.status ?? 'done';
126
+ const dot = document.createElement('span');
127
+ dot.dataset.mkTlDot = '';
128
+ dot.setAttribute('aria-hidden', 'true');
129
+ dot.textContent = event.icon ?? '';
130
+ const body = document.createElement('div');
131
+ body.dataset.mkTlBody = '';
132
+ const date = toTime(event.time);
133
+ if (date) {
134
+ const time = document.createElement('time');
135
+ time.dataset.mkTlTime = '';
136
+ time.dateTime = date.toISOString();
137
+ time.title = fullTime(date, locale);
138
+ time.textContent = timeText(date);
139
+ body.append(time);
140
+ }
141
+ const title = document.createElement('strong');
142
+ title.dataset.mkTlTitle = '';
143
+ title.textContent = event.title;
144
+ body.append(title);
145
+ if (event.status && event.status !== 'done') {
146
+ const state = document.createElement('span');
147
+ state.className = 'mk-sr-only';
148
+ state.textContent = ` (${STATUS_LABEL[event.status]})`;
149
+ title.append(state);
150
+ }
151
+ if (event.description) {
152
+ const description = document.createElement('p');
153
+ description.dataset.mkTlDescription = '';
154
+ description.textContent = event.description;
155
+ body.append(description);
156
+ }
157
+ if (event.meta) {
158
+ const meta = document.createElement('span');
159
+ meta.dataset.mkTlMeta = '';
160
+ meta.textContent = event.meta;
161
+ body.append(meta);
162
+ }
163
+ li.append(dot, body);
164
+ return li;
165
+ };
166
+
167
+ const heading = (date: Date) => {
168
+ const li = document.createElement('li');
169
+ li.dataset.mkTlDay = '';
170
+ li.dataset.day = dayKey(date);
171
+ li.setAttribute('role', 'presentation');
172
+ li.dataset.flipId = `day-${li.dataset.day}`;
173
+ li.textContent = dayLabel(date, new Date(), locale);
174
+ return li;
175
+ };
176
+
177
+ /** The rail runs from the first dot to the last; its filled part reaches the current (or last done) event. */
178
+ const measureRail = () => {
179
+ const dots = [...list.querySelectorAll<HTMLElement>('[data-mk-tl-dot]')];
180
+ if (!dots.length) {
181
+ rail.hidden = true;
182
+ return;
183
+ }
184
+ rail.hidden = false;
185
+ // Centres measured against the wrapper, whatever positions the items.
186
+ const base = wrap.getBoundingClientRect().top;
187
+ const centre = (dot: HTMLElement) => {
188
+ const box = dot.getBoundingClientRect();
189
+ return box.top - base + box.height / 2;
190
+ };
191
+ const top = centre(dots[0]!);
192
+ const bottom = centre(dots[dots.length - 1]!);
193
+ rail.style.top = `${top}px`;
194
+ rail.style.height = `${Math.max(0, bottom - top)}px`;
195
+ const reached = [...list.querySelectorAll<HTMLElement>('[data-mk-tl-item]')].filter((li) => li.dataset.status === 'done' || li.dataset.status === 'current');
196
+ const last = reached[reached.length - 1]?.querySelector<HTMLElement>('[data-mk-tl-dot]');
197
+ progress.style.height = `${last ? Math.max(0, centre(last) - top) : 0}px`;
198
+ };
199
+ const itemOf = (id: string) => [...list.querySelectorAll<HTMLElement>('[data-mk-tl-item]')].find((li) => li.dataset.id === id) ?? null;
200
+
201
+ const render = () => {
202
+ const nodes: HTMLElement[] = [];
203
+ let day = '';
204
+ events.forEach((event, i) => {
205
+ const date = toTime(event.time);
206
+ if (options.group && date && dayKey(date) !== day) {
207
+ day = dayKey(date);
208
+ nodes.push(heading(date));
209
+ }
210
+ const element = item(event);
211
+ // 'alternate': the events take turns on each side of the rail.
212
+ element.dataset.side = i % 2 ? 'end' : 'start';
213
+ element.dataset.flipId = event.id;
214
+ nodes.push(element);
215
+ });
216
+ list.replaceChildren(...nodes);
217
+ measureRail();
218
+ };
219
+
220
+ const refreshTimes = () => {
221
+ for (const time of list.querySelectorAll<HTMLTimeElement>('[data-mk-tl-time]')) time.textContent = timeText(new Date(time.dateTime));
222
+ if (options.group) for (const day of list.querySelectorAll<HTMLElement>('[data-mk-tl-day]')) day.textContent = dayLabel(toTime(day.dataset.day!)!, new Date(), locale);
223
+ };
224
+ if (relative) scope.add(everyMinute(refreshTimes));
225
+ if (typeof ResizeObserver === 'function') scope.observe(new ResizeObserver(() => measureRail())).observe(list);
226
+
227
+ /** The entrance: the rail draws, the events cascade in. */
228
+ const enter = () => {
229
+ if (reduced()) return;
230
+ keep(gsap.fromTo(rail, { scaleY: 0 }, { scaleY: 1, transformOrigin: '50% 0%', duration: 0.8, ease: EASE.wipe, clearProps: 'transform' }));
231
+ keep(blurIn([...list.children], { from: 'rise', stagger: 0.06 }));
232
+ };
233
+
234
+ render();
235
+ if (typeof IntersectionObserver === 'function' && !reduced()) {
236
+ gsap.set([rail, ...list.children], { opacity: 0 });
237
+ const observer = scope.observe(
238
+ new IntersectionObserver((entries) => {
239
+ if (!entries.some((entry) => entry.isIntersecting)) return;
240
+ observer.disconnect();
241
+ gsap.set([rail, ...list.children], { clearProps: 'opacity' });
242
+ enter();
243
+ }, { threshold: 0.15 }),
244
+ );
245
+ observer.observe(root);
246
+ }
247
+
248
+ return {
249
+ add(event, at = 'end') {
250
+ if (scope.disposed) return;
251
+ // What is there glides to make room (the rail follows); the new event and a new day come in.
252
+ const state = reduced() ? null : Flip.getState([...list.children]);
253
+ events = at === 'start' ? [{ ...event }, ...events] : [...events, { ...event }];
254
+ render();
255
+ const added = itemOf(event.id);
256
+ if (!added || !state) return;
257
+ added.setAttribute('data-mk-tl-fresh', '');
258
+ scope.timeout(() => added.removeAttribute('data-mk-tl-fresh'), 1800);
259
+ keep(
260
+ Flip.from(state, {
261
+ targets: [...list.children],
262
+ duration: TIMING.layoutTravel,
263
+ ease: EASE.layoutReflow,
264
+ onUpdate: measureRail,
265
+ onComplete: measureRail,
266
+ onEnter: (entering) =>
267
+ gsap.fromTo(entering, { opacity: 0, y: at === 'start' ? -16 : 16, filter: 'blur(10px)' }, { opacity: 1, y: 0, filter: 'blur(0px)', duration: 0.45, ease: 'power2.out', clearProps: 'opacity,transform,filter' }),
268
+ }),
269
+ );
270
+ const dot = added.querySelector<HTMLElement>('[data-mk-tl-dot]')!;
271
+ keep(gsap.fromTo(dot, { scale: 0 }, { scale: 1, duration: 0.4, delay: 0.12, ease: EASE.pop, clearProps: 'transform' }));
272
+ },
273
+ update(id, patch) {
274
+ const event = events.find((entry) => entry.id === id);
275
+ if (!event || scope.disposed) return;
276
+ const statusChanged = patch.status && patch.status !== event.status;
277
+ Object.assign(event, patch);
278
+ render();
279
+ const dot = itemOf(id)?.querySelector<HTMLElement>('[data-mk-tl-dot]');
280
+ if (statusChanged && dot && !reduced()) keep(gsap.fromTo(dot, { scale: 0.6 }, { scale: 1, duration: 0.4, ease: EASE.pop, clearProps: 'transform' }));
281
+ },
282
+ remove(id) {
283
+ const element = itemOf(id);
284
+ events = events.filter((event) => event.id !== id);
285
+ if (!element) return render();
286
+ if (reduced()) return render();
287
+ keep(collapse(element, { onComplete: render }));
288
+ },
289
+ setEvents(next) {
290
+ if (scope.disposed) return;
291
+ events = next.map((event) => ({ ...event }));
292
+ render();
293
+ if (!reduced()) keep(blurIn([...list.children], { from: 'rise', stagger: 0.04 }));
294
+ },
295
+ get events() {
296
+ return events.map((event) => ({ ...event }));
297
+ },
298
+ destroy: () => scope.dispose(),
299
+ };
300
+ }