@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,410 @@
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 { blurIn, shake } from '../../motion/micro';
6
+ import { BRAND_LABELS, cardGroups, cardLength, cvcLength, detectBrand, formatNumber, luhn, parseExpiry, type CardBrand } from './card';
7
+
8
+ /*
9
+ * Credit card: native fields (cc-number, cc-name, cc-exp, cc-csc autocomplete)
10
+ * beside a dark card that fills in as you type. Each new character rolls into
11
+ * its slot (y 100 % → 0 out of a blur); a frame glides to the part of the card
12
+ * being edited; the brand appears by prefix (as text, no logos); the CVC field
13
+ * turns the card around in 3D (0.8 s, Melonmind's swing) and leaving it turns it
14
+ * back. A fine pointer tilts the card a little. Fields validate on blur (Luhn,
15
+ * a future expiry, CVC length) and shake when wrong. Nothing is charged: the
16
+ * app reads the form. Events carry no card data: mk:change {brand, complete, valid}, mk:complete.
17
+ */
18
+
19
+ export type CreditCardField = 'number' | 'name' | 'expiry' | 'cvc';
20
+
21
+ export interface CreditCardLabels {
22
+ number?: string;
23
+ name?: string;
24
+ expiry?: string;
25
+ cvc?: string;
26
+ namePlaceholder?: string;
27
+ invalidNumber?: string;
28
+ invalidExpiry?: string;
29
+ invalidCvc?: string;
30
+ }
31
+
32
+ export interface CreditCardOptions {
33
+ labels?: CreditCardLabels;
34
+ /** Form names of the fields (default cc-number, cc-name, cc-exp, cc-csc). */
35
+ names?: Partial<Record<CreditCardField, string>>;
36
+ /** Tilt the card with a fine pointer (default true). */
37
+ tilt?: boolean;
38
+ onChange?: (state: { brand: CardBrand; complete: boolean; valid: boolean }) => void;
39
+ onComplete?: () => void;
40
+ }
41
+
42
+ export interface CreditCardValues {
43
+ number: string;
44
+ name: string;
45
+ expiry: string;
46
+ cvc: string;
47
+ }
48
+
49
+ export interface CreditCardInstance extends Instance {
50
+ readonly values: CreditCardValues;
51
+ readonly brand: CardBrand;
52
+ readonly valid: boolean;
53
+ focus(field: CreditCardField): void;
54
+ /** Turn the card (true: the back). */
55
+ flip(back?: boolean): void;
56
+ }
57
+
58
+ const LABELS: Required<CreditCardLabels> = {
59
+ number: 'Número de tarjeta',
60
+ name: 'Titular',
61
+ expiry: 'Caducidad',
62
+ cvc: 'CVC',
63
+ namePlaceholder: 'NOMBRE APELLIDO',
64
+ invalidNumber: 'Revisa el número de la tarjeta.',
65
+ invalidExpiry: 'La fecha de caducidad no es válida.',
66
+ invalidCvc: 'El CVC está incompleto.',
67
+ };
68
+
69
+ const FIELDS: CreditCardField[] = ['number', 'name', 'expiry', 'cvc'];
70
+ const NAMES: Record<CreditCardField, string> = { number: 'cc-number', name: 'cc-name', expiry: 'cc-exp', cvc: 'cc-csc' };
71
+ let sequence = 0;
72
+
73
+ const el = <K extends keyof HTMLElementTagNameMap>(tag: K, attrs: Record<string, string> = {}, text?: string) => {
74
+ const element = document.createElement(tag);
75
+ for (const [name, value] of Object.entries(attrs)) element.setAttribute(name, value);
76
+ if (text !== undefined) element.textContent = text;
77
+ return element;
78
+ };
79
+
80
+ export function createCreditCard(root: HTMLElement | null, options: CreditCardOptions = {}): CreditCardInstance {
81
+ if (!root) return inert({ values: { number: '', name: '', expiry: '', cvc: '' }, brand: 'unknown', valid: false, focus() {}, flip() {} });
82
+ registerMotion();
83
+ const scope = createScope();
84
+ const labels = { ...LABELS, ...options.labels };
85
+ const uid = `mk-card-${++sequence}`;
86
+ const made: HTMLElement[] = [];
87
+ const own = <T extends HTMLElement>(element: T) => {
88
+ made.push(element);
89
+ return element;
90
+ };
91
+ scope.add(() => made.forEach((element) => element.remove()));
92
+
93
+ // The card (decorative: the fields are the accessible control).
94
+ const visual = own(el('div', { 'data-mk-card-visual': '', 'aria-hidden': 'true' }));
95
+ const inner = el('div', { 'data-mk-card-inner': '' });
96
+ const front = el('div', { 'data-mk-card-face': 'front' });
97
+ const back = el('div', { 'data-mk-card-face': 'back' });
98
+ const chip = el('span', { 'data-mk-card-chip': '' });
99
+ const brand = el('span', { 'data-mk-card-brand': '' });
100
+ const number = el('span', { 'data-mk-card-number': '' });
101
+ const name = el('span', { 'data-mk-card-name': '' });
102
+ const expiry = el('span', { 'data-mk-card-expiry': '' });
103
+ const holderLabel = el('span', { 'data-mk-card-caption': '' }, labels.name);
104
+ const expiryLabel = el('span', { 'data-mk-card-caption': '' }, labels.expiry);
105
+ const holder = el('span', { 'data-mk-card-region': 'name' });
106
+ holder.append(holderLabel, name);
107
+ const valid = el('span', { 'data-mk-card-region': 'expiry' });
108
+ valid.append(expiryLabel, expiry);
109
+ const frame = el('span', { 'data-mk-card-frame': '' });
110
+ const numberRegion = el('span', { 'data-mk-card-region': 'number' });
111
+ numberRegion.append(number);
112
+ front.append(chip, brand, numberRegion, holder, valid, frame);
113
+ const stripe = el('span', { 'data-mk-card-stripe': '' });
114
+ const signature = el('span', { 'data-mk-card-signature': '' });
115
+ const cvc = el('span', { 'data-mk-card-cvc': '' });
116
+ signature.append(cvc);
117
+ const backBrand = el('span', { 'data-mk-card-brand': '' });
118
+ back.append(stripe, signature, backBrand);
119
+ inner.append(front, back);
120
+ visual.append(inner);
121
+
122
+ // The fields: authored ones are used as they are; missing ones are made.
123
+ const fields = {} as Record<CreditCardField, HTMLInputElement>;
124
+ const errors = {} as Record<CreditCardField, HTMLElement | null>;
125
+ let grid = root.querySelector<HTMLElement>('[data-mk-card-fields]');
126
+ if (!grid) grid = own(el('div', { 'data-mk-card-fields': '' }));
127
+ for (const field of FIELDS) {
128
+ let input = root.querySelector<HTMLInputElement>(`input[data-mk-card-field="${field}"]`);
129
+ if (!input) {
130
+ const label = el('label', { 'data-mk-card-label': field });
131
+ label.append(el('span', {}, labels[field]));
132
+ input = el('input', { 'data-mk-card-field': field });
133
+ label.append(input);
134
+ const error = el('span', { 'data-mk-card-error': '', id: `${uid}-${field}-error` });
135
+ label.append(error);
136
+ grid.append(label);
137
+ }
138
+ fields[field] = input;
139
+ errors[field] = input.closest('label')?.querySelector<HTMLElement>('[data-mk-card-error]') ?? null;
140
+ }
141
+ root.prepend(visual);
142
+ if (!grid.isConnected) root.append(grid);
143
+
144
+ const attrs: Record<CreditCardField, Record<string, string>> = {
145
+ number: { inputmode: 'numeric', autocomplete: 'cc-number', placeholder: '0000 0000 0000 0000' },
146
+ name: { autocomplete: 'cc-name', placeholder: labels.namePlaceholder, autocapitalize: 'characters', spellcheck: 'false' },
147
+ expiry: { inputmode: 'numeric', autocomplete: 'cc-exp', placeholder: 'MM/AA', maxlength: '5' },
148
+ cvc: { inputmode: 'numeric', autocomplete: 'cc-csc', placeholder: '•••', maxlength: '4' },
149
+ };
150
+ for (const field of FIELDS) {
151
+ const input = fields[field];
152
+ scope.attr(input, 'type', 'text');
153
+ for (const [key, value] of Object.entries(attrs[field])) if (!input.hasAttribute(key)) scope.attr(input, key, value);
154
+ if (!input.name) scope.attr(input, 'name', options.names?.[field] ?? NAMES[field]);
155
+ if (errors[field]?.id) scope.attr(input, 'aria-describedby', errors[field]!.id);
156
+ }
157
+ scope.attr(root, 'data-mk-ready', '');
158
+
159
+ const effects = new Set<gsap.core.Animation>();
160
+ const keep = (animation: gsap.core.Animation | null | undefined) => {
161
+ if (!animation) return;
162
+ effects.add(animation);
163
+ // Finished ones leave as new ones arrive: the animation's own onComplete stays untouched.
164
+ for (const effect of effects) if (effect.totalProgress() === 1) effects.delete(effect);
165
+ };
166
+ scope.add(() => {
167
+ for (const effect of effects) effect.kill();
168
+ effects.clear();
169
+ gsap.killTweensOf([inner, visual, frame]);
170
+ });
171
+
172
+ /** Write text into `target` one span per character; changed characters roll in. */
173
+ const chars = (target: HTMLElement, text: string, placeholder: string) => {
174
+ const shown = text || placeholder;
175
+ const empty = !text;
176
+ target.toggleAttribute('data-mk-empty', empty);
177
+ const current = [...target.children] as HTMLElement[];
178
+ for (let i = 0; i < Math.max(current.length, shown.length); i++) {
179
+ const char = shown[i];
180
+ const span = current[i];
181
+ if (char === undefined) {
182
+ span?.remove();
183
+ continue;
184
+ }
185
+ if (span && span.textContent === char && span.hasAttribute('data-mk-placeholder') === (empty || char === '•')) continue;
186
+ const next = el('span', {}, char);
187
+ next.toggleAttribute('data-mk-placeholder', empty || char === '•');
188
+ if (char === ' ') next.dataset.mkSpace = '';
189
+ if (span) span.replaceWith(next);
190
+ else target.append(next);
191
+ if (!empty && char !== '•' && char !== ' ' && !reduced()) keep(gsap.fromTo(next, { yPercent: 70, opacity: 0, filter: 'blur(4px)' }, { yPercent: 0, opacity: 1, filter: 'blur(0px)', duration: 0.35, ease: EASE.signature, clearProps: 'all' }));
192
+ }
193
+ };
194
+
195
+ const state = { number: '', name: '', expiry: '', cvc: '', brand: 'unknown' as CardBrand };
196
+ let flipped = false;
197
+ let lastComplete = false;
198
+ let lastSignature = '';
199
+
200
+ const numberMask = (brand: CardBrand, digits: string) => {
201
+ const groups = cardGroups(brand);
202
+ const parts: string[] = [];
203
+ let at = 0;
204
+ for (const size of groups) {
205
+ parts.push(Array.from({ length: size }, (_, i) => digits[at + i] ?? '•').join(''));
206
+ at += size;
207
+ }
208
+ return parts.join(' ');
209
+ };
210
+
211
+ const checks = () => {
212
+ const expiryState = parseExpiry(state.expiry);
213
+ return {
214
+ number: state.number.length === cardLength(state.brand) && luhn(state.number),
215
+ name: state.name.trim().length > 1,
216
+ expiry: expiryState.valid,
217
+ cvc: state.cvc.length === cvcLength(state.brand),
218
+ };
219
+ };
220
+
221
+ const render = () => {
222
+ chars(number, numberMask(state.brand, state.number), '');
223
+ number.toggleAttribute('data-mk-empty', !state.number);
224
+ chars(name, state.name.toUpperCase(), labels.namePlaceholder);
225
+ chars(expiry, state.expiry, 'MM/AA');
226
+ chars(cvc, state.cvc, '•'.repeat(cvcLength(state.brand)));
227
+ const label = BRAND_LABELS[state.brand];
228
+ if (brand.textContent !== label) {
229
+ brand.textContent = label;
230
+ backBrand.textContent = label;
231
+ keep(blurIn(label ? [brand] : null, { from: 'pop' }));
232
+ }
233
+ scope.attr(root, 'data-mk-brand', state.brand);
234
+ fields.cvc.maxLength = cvcLength(state.brand);
235
+ };
236
+
237
+ const emit = () => {
238
+ const ok = checks();
239
+ const complete = FIELDS.every((field) => (field === 'number' ? state.number.length === cardLength(state.brand) : field === 'expiry' ? state.expiry.length === 5 : field === 'cvc' ? state.cvc.length === cvcLength(state.brand) : state.name.trim().length > 0));
240
+ const allValid = Object.values(ok).every(Boolean);
241
+ const signature = `${state.brand}|${complete}|${allValid}`;
242
+ if (signature !== lastSignature) {
243
+ lastSignature = signature;
244
+ const detail = { brand: state.brand, complete, valid: allValid };
245
+ options.onChange?.(detail);
246
+ root.dispatchEvent(new CustomEvent('mk:change', { bubbles: true, detail }));
247
+ }
248
+ if (allValid && !lastComplete) {
249
+ options.onComplete?.();
250
+ root.dispatchEvent(new CustomEvent('mk:complete', { bubbles: true }));
251
+ }
252
+ lastComplete = allValid;
253
+ };
254
+
255
+ const setInvalid = (field: CreditCardField, message: string | null) => {
256
+ scope.attr(fields[field], 'aria-invalid', message ? 'true' : null);
257
+ if (errors[field]) errors[field]!.textContent = message ?? '';
258
+ };
259
+
260
+ const flip = (toBack = !flipped) => {
261
+ if (scope.disposed || toBack === flipped) return;
262
+ flipped = toBack;
263
+ scope.attr(root, 'data-mk-flipped', flipped ? '' : null);
264
+ gsap.killTweensOf(inner, 'rotationY');
265
+ if (reduced()) gsap.set(inner, { rotationY: flipped ? 180 : 0 });
266
+ else keep(gsap.to(inner, { rotationY: flipped ? 180 : 0, duration: 0.8, ease: EASE.swatch }));
267
+ };
268
+
269
+ /** The frame glides to the region of the card being edited. */
270
+ const regions: Record<CreditCardField, HTMLElement | null> = { number: numberRegion, name: holder, expiry: valid, cvc: null };
271
+ const moveFrame = (field: CreditCardField | null) => {
272
+ const target = field ? regions[field] : null;
273
+ if (!target) {
274
+ keep(gsap.to(frame, { opacity: 0, duration: 0.2, overwrite: 'auto' }));
275
+ return;
276
+ }
277
+ const box = { x: target.offsetLeft - 8, y: target.offsetTop - 6, width: target.offsetWidth + 16, height: target.offsetHeight + 12 };
278
+ const visible = Number(gsap.getProperty(frame, 'opacity')) > 0.5;
279
+ if (!visible || reduced()) gsap.set(frame, { ...box, opacity: reduced() ? 1 : 0 });
280
+ if (!reduced()) keep(gsap.to(frame, { ...box, opacity: 1, duration: 0.5, ease: EASE.swatch, overwrite: 'auto' }));
281
+ };
282
+
283
+ // Typing: keep the field formatted and the caret after the same digits.
284
+ const caretDigits = (input: HTMLInputElement) => (input.value.slice(0, input.selectionStart ?? input.value.length).match(/\d/g) ?? []).length;
285
+ const placeCaret = (input: HTMLInputElement, digits: number) => {
286
+ let seen = 0;
287
+ let at = 0;
288
+ while (at < input.value.length && seen < digits) {
289
+ if (/\d/.test(input.value[at]!)) seen += 1;
290
+ at += 1;
291
+ }
292
+ if (document.activeElement === input) input.setSelectionRange(at, at);
293
+ };
294
+
295
+ const read = (field: CreditCardField, fromInput: boolean) => {
296
+ const input = fields[field];
297
+ if (field === 'number') {
298
+ const caret = caretDigits(input);
299
+ const digits = input.value.replace(/\D/g, '');
300
+ state.brand = detectBrand(digits);
301
+ state.number = digits.slice(0, cardLength(state.brand));
302
+ input.value = formatNumber(state.number, state.brand);
303
+ if (fromInput) placeCaret(input, caret);
304
+ } else if (field === 'expiry') {
305
+ const parsed = parseExpiry(input.value);
306
+ state.expiry = parsed.text;
307
+ // Deleting the slash deletes the month digit before it.
308
+ input.value = parsed.text;
309
+ } else if (field === 'cvc') {
310
+ state.cvc = input.value.replace(/\D/g, '').slice(0, cvcLength(state.brand));
311
+ input.value = state.cvc;
312
+ } else state.name = input.value.replace(/\s+/g, ' ').trimStart().slice(0, 26);
313
+ };
314
+
315
+ const validate = (field: CreditCardField) => {
316
+ const ok = checks();
317
+ const filled = field === 'number' ? state.number : field === 'expiry' ? state.expiry : field === 'cvc' ? state.cvc : state.name;
318
+ const message = !filled || ok[field] ? null : field === 'number' ? labels.invalidNumber : field === 'expiry' ? labels.invalidExpiry : field === 'cvc' ? labels.invalidCvc : null;
319
+ setInvalid(field, message);
320
+ if (message) {
321
+ keep(shake(fields[field].closest('label') ?? fields[field]));
322
+ keep(shake(visual, 6));
323
+ }
324
+ };
325
+
326
+ let leaving: ReturnType<typeof setTimeout> | undefined;
327
+ scope.add(() => clearTimeout(leaving));
328
+ for (const field of FIELDS) {
329
+ const input = fields[field];
330
+ read(field, false);
331
+ scope.on(input, 'input', () => {
332
+ read(field, true);
333
+ if (fields[field].getAttribute('aria-invalid') === 'true' && checks()[field]) setInvalid(field, null);
334
+ render();
335
+ emit();
336
+ });
337
+ scope.on(input, 'focus', () => {
338
+ root.dataset.mkActive = field;
339
+ if (field === 'cvc') flip(true);
340
+ else flip(false);
341
+ moveFrame(field);
342
+ });
343
+ scope.on(input, 'blur', () => {
344
+ validate(field);
345
+ // Leaving the form: the card faces front again.
346
+ clearTimeout(leaving);
347
+ leaving = setTimeout(() => {
348
+ if (scope.disposed) return;
349
+ const active = document.activeElement;
350
+ if (!FIELDS.some((name) => fields[name] === active)) {
351
+ delete root.dataset.mkActive;
352
+ flip(false);
353
+ moveFrame(null);
354
+ }
355
+ }, 0);
356
+ });
357
+ }
358
+ scope.add(() => delete root.dataset.mkActive);
359
+ // Expiry: a backspace right after the slash also removes the month's second digit.
360
+ scope.on(fields.expiry, 'keydown', (event) => {
361
+ const key = event as KeyboardEvent;
362
+ const input = fields.expiry;
363
+ if (key.key === 'Backspace' && input.selectionStart === input.value.length && input.value.endsWith('/')) {
364
+ key.preventDefault();
365
+ input.value = input.value.slice(0, 1);
366
+ read('expiry', true);
367
+ render();
368
+ emit();
369
+ }
370
+ });
371
+
372
+ // A fine pointer tilts the card.
373
+ if (options.tilt !== false && typeof matchMedia === 'function' && matchMedia('(pointer: fine)').matches) {
374
+ scope.on(visual, 'pointermove', (event) => {
375
+ if (reduced()) return;
376
+ const box = visual.getBoundingClientRect();
377
+ const x = ((event as PointerEvent).clientX - box.left) / box.width - 0.5;
378
+ const y = ((event as PointerEvent).clientY - box.top) / box.height - 0.5;
379
+ gsap.to(visual, { rotationY: x * 12, rotationX: -y * 10, duration: 0.5, ease: 'power3.out', overwrite: 'auto' });
380
+ });
381
+ scope.on(visual, 'pointerleave', () => {
382
+ gsap.to(visual, { rotationY: 0, rotationX: 0, duration: 0.7, ease: EASE.swatch, overwrite: 'auto' });
383
+ });
384
+ }
385
+ // A click on the card focuses its part.
386
+ scope.on(visual, 'click', (event) => {
387
+ const region = (event.target as Element | null)?.closest<HTMLElement>('[data-mk-card-region]')?.dataset.mkCardRegion as CreditCardField | undefined;
388
+ fields[flipped ? 'cvc' : region ?? 'number'].focus();
389
+ });
390
+ render();
391
+ lastSignature = '';
392
+ lastComplete = Object.values(checks()).every(Boolean);
393
+
394
+ return {
395
+ get values() {
396
+ return { number: state.number, name: state.name, expiry: state.expiry, cvc: state.cvc };
397
+ },
398
+ get brand() {
399
+ return state.brand;
400
+ },
401
+ get valid() {
402
+ return Object.values(checks()).every(Boolean);
403
+ },
404
+ focus(field) {
405
+ fields[field]?.focus();
406
+ },
407
+ flip: (toBack) => flip(toBack ?? !flipped),
408
+ destroy: () => scope.dispose(),
409
+ };
410
+ }
@@ -0,0 +1,36 @@
1
+ 'use client';
2
+ import { useRef, type HTMLAttributes, type MutableRefObject } from 'react';
3
+ import { useIsomorphicLayoutEffect, useLatest } from '../../react/use-recipe';
4
+ import { createCreditCard, type CreditCardInstance, type CreditCardOptions } from './engine';
5
+
6
+ export interface CreditCardProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'children'>, CreditCardOptions {
7
+ instanceRef?: MutableRefObject<CreditCardInstance | null>;
8
+ }
9
+
10
+ /**
11
+ * <CreditCard onComplete={() => setReady(true)} /> inside a <form>: the engine makes the card and the
12
+ * native cc-* fields; the app reads the form when it submits. Callbacks carry no card data.
13
+ */
14
+ export function CreditCard({ labels, names, tilt, onChange, onComplete, instanceRef, className, ...props }: CreditCardProps) {
15
+ const ref = useRef<HTMLDivElement>(null);
16
+ const change = useLatest(onChange);
17
+ const complete = useLatest(onComplete);
18
+ const key = JSON.stringify([labels ?? {}, names ?? {}]);
19
+ useIsomorphicLayoutEffect(() => {
20
+ const created = createCreditCard(ref.current, {
21
+ labels,
22
+ names,
23
+ tilt,
24
+ onChange: (state) => change.current?.(state),
25
+ onComplete: () => complete.current?.(),
26
+ });
27
+ if (instanceRef) instanceRef.current = created;
28
+ return () => {
29
+ created.destroy();
30
+ if (instanceRef) instanceRef.current = null;
31
+ };
32
+ // labels and names are compared by content.
33
+ // eslint-disable-next-line react-hooks/exhaustive-deps
34
+ }, [key, tilt]);
35
+ return <div {...props} ref={ref} className={['mk-credit-card', className].filter(Boolean).join(' ')} />;
36
+ }
@@ -0,0 +1,83 @@
1
+ # data-table
2
+
3
+ Tabla avanzada con ordenamiento, búsqueda, filtros, selección, paginación, acciones por fila y columnas configurables. Al ordenar, las filas se deslizan a su nuevo lugar (el resorte de layout del kit, .62 s) y la flecha del encabezado gira. La búsqueda resalta lo que coincide (sin importar tildes ni mayúsculas) y las filas que quedan se reacomodan juntas. Los filtros usan `filter-builder` dentro de un panel que crece desde su botón: la tabla responde mientras editas y una frase dice qué está filtrado («Estado es Enviado y Monto mayor que 500»).
4
+
5
+ Las casillas se dibujan solas y hacen pop; la del encabezado queda a medias cuando solo hay algunas filas elegidas. Una fila elegida se tiñe apenas y lleva un borde de acento a la izquierda, sin tapar sus datos. Al elegir filas, la barra con el conteo (que rueda) y las acciones masivas aparece con un blur en el lugar de la barra de herramientas, así nunca cubre filas, y ofrece elegir todos los resultados cuando la página entera está marcada. Al cambiar de página, las filas entran por el lado hacia el que vas; si la tabla cabe en su panel, el desborde se oculta mientras viajan para que no parpadee una barra de desplazamiento (si ya es más ancha, aparecen con un fundido). Las filas eliminadas salen deslizándose y las demás cierran el hueco. Mientras carga hay *skeletons* que brillan, y sin nada que mostrar aparece un estado vacío que explica por qué y ofrece limpiar los filtros.
6
+
7
+ ## HTML / Astro
8
+
9
+ ```html
10
+ <mk-data-table class="mk-data-table" selectable page-size="10" sort="monto:desc" caption="Pedidos"
11
+ columns='[{"key":"cliente","label":"Cliente"},
12
+ {"key":"monto","label":"Monto","type":"number"},
13
+ {"key":"fecha","label":"Fecha","type":"date"},
14
+ {"key":"estado","label":"Estado","type":"select","options":[{"value":"nuevo","label":"Nuevo"},{"value":"enviado","label":"Enviado"}]}]'
15
+ rows='[{"id":1,"cliente":"Ana Gómez","monto":1240,"fecha":"2026-10-28","estado":"nuevo"}]'
16
+ actions='[{"id":"ver","label":"Ver pedido"},{"id":"cancelar","label":"Cancelar","danger":true}]'
17
+ bulk-actions='[{"id":"exportar","label":"Exportar"}]'></mk-data-table>
18
+
19
+ <script>
20
+ const table = document.querySelector('mk-data-table');
21
+ table.addEventListener('mk:action', (event) => console.log(event.detail.action, event.detail.row));
22
+ </script>
23
+ ```
24
+
25
+ Con JavaScript, `createDataTable(root, opciones)` acepta además `format` y `render` en cada columna.
26
+
27
+ ## React
28
+
29
+ ```tsx
30
+ const table = useRef<DataTableHandle<Pedido>>(null);
31
+
32
+ <DataTable
33
+ ref={table}
34
+ columns={columnas}
35
+ rows={pedidos}
36
+ selectable
37
+ actions={[{ id: 'cancelar', label: 'Cancelar', danger: true }]}
38
+ onAction={(accion, pedido) => accion === 'cancelar' && table.current?.removeRows([pedido.id])}
39
+ bulkActions={[{ id: 'exportar', label: 'Exportar' }]}
40
+ onBulkAction={(accion, filas) => exportar(filas)}
41
+ />;
42
+ ```
43
+
44
+ Unas `rows` nuevas entran en su sitio y se conservan el orden, los filtros y la selección. Las celdas son texto (`format`) o se dibujan con `render(valor, fila, celda)`.
45
+
46
+ ## Columnas
47
+
48
+ `{ key, label, type?, options?, sortable?, filterable?, searchable?, hidden?, hideable?, align?, width?, format?, render?, value? }`. `type`: `text`, `number`, `date`, `boolean` o `select` (decide cómo se ordena, se filtra y se escribe: números y fechas en el idioma de la página, «Sí»/«No», la etiqueta de la opción). Los números se alinean a la derecha.
49
+
50
+ ## Opciones
51
+
52
+ | Opción | Atributo | Por defecto | Qué hace |
53
+ |---|---|---|---|
54
+ | `columns` | `columns` (JSON) | `[]` | Las columnas. |
55
+ | `rows` | `rows` (JSON) | `[]` | Las filas. |
56
+ | `rowKey` | `row-key` | `'id'` | Clave (o función) del id de cada fila. |
57
+ | `caption` | `caption` | `'Tabla'` | Nombre accesible. |
58
+ | `pageSize` | `page-size` | `10` | Filas por página (`0`: todas). |
59
+ | `pageSizes` | `page-sizes` (JSON) | `[10, 25, 50]` | Opciones del menú «Filas» (un botón que abre un menú como Filtros y Columnas, con la opción actual marcada). |
60
+ | `selectable` | `selectable` | `false` | Casillas para elegir filas. |
61
+ | `search` | `search` | `true` | Campo de búsqueda (un texto es su marcador). |
62
+ | `filters` | `filters` | `true` | Botón «Filtros» con `filter-builder`. |
63
+ | `filter` | — | vacío | Filtro inicial. |
64
+ | `columnsMenu` | `columns-menu` | `true` | Botón «Columnas» para mostrar y ocultar. |
65
+ | `actions` | `actions` (JSON) | — | Menú de cada fila: `{ id, label, danger? }[]`. |
66
+ | `bulkActions` | `bulk-actions` (JSON) | — | Botones de la barra de selección. |
67
+ | `sort` | `sort` (`clave` o `clave:desc`) | sin orden | Orden inicial. |
68
+ | `loading` | `loading` | `false` | *Skeletons* mientras carga. |
69
+ | `emptyTitle` / `emptyDescription` | `empty-title` / `empty-description` | — | Textos sin filas. |
70
+ | `onSortChange`, `onSelectionChange(ids, filas)`, `onAction(accion, fila)`, `onBulkAction(accion, filas)`, `onPageChange(pagina)`, `onFilterChange(filtro, busqueda)` | — | — | Cada cambio. |
71
+ | `onRender(tbody)` | — | — | Después de dibujar las filas (lo usa `editable-table`). |
72
+
73
+ ## API y eventos
74
+
75
+ `setRows`, `updateRow(id, cambios)`, `removeRows(ids)`, `setLoading`, `sortBy(clave | null, direccion)`, `setPage`, `setPageSize`, `setQuery`, `setFilter`, `setColumnVisible(clave, visible)`, `select(ids)`, `rowOf(id)`, `cellOf(id, clave)`, `refresh()`, `idOf(fila)`, y `rows`, `results`, `page`, `pageCount`, `selection`, `sort`, `query`, `filter`, `columns`, `body`, `destroy()`. Eventos `mk:sort`, `mk:select`, `mk:action`, `mk:bulk-action`, `mk:page` y `mk:filter`.
76
+
77
+ ## Variables CSS
78
+
79
+ `--mk-dt-max-height` (alto máximo antes de desplazarse dentro, con el encabezado fijo).
80
+
81
+ ## Accesibilidad
82
+
83
+ Una tabla real con `caption`, encabezados `th scope="col"` con `aria-sort` y botones para ordenar; casillas con etiqueta («Seleccionar Ana Gómez»); el botón de acciones dice de qué fila es y abre un menú de WAI-ARIA; «Filas» es un botón con `aria-haspopup="menu"` y sus opciones son `menuitemradio` con `aria-checked`; la barra de selección es un `toolbar` con nombre. Si la tabla es más ancha que su contenedor, se desplaza de lado dentro de una región enfocable. Un estado discreto anuncia el orden, los resultados, la página y la selección. Con movimiento reducido los cambios son inmediatos.