@yewdiel21/motion-kit 0.9.1 → 0.14.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 (458) hide show
  1. package/README.md +72 -0
  2. package/dist/auto/index.d.ts +72 -3
  3. package/dist/auto/index.js +139 -3
  4. package/dist/auto/index.js.map +1 -1
  5. package/dist/{chunk-BFC27F2G.js → chunk-6P4P7NU6.js} +2 -218
  6. package/dist/chunk-6P4P7NU6.js.map +1 -0
  7. package/dist/chunk-CU6SXW3E.js +20334 -0
  8. package/dist/chunk-CU6SXW3E.js.map +1 -0
  9. package/dist/{chunk-XDWBVFHQ.js → chunk-EY4BJKC4.js} +1203 -29
  10. package/dist/chunk-EY4BJKC4.js.map +1 -0
  11. package/dist/chunk-QP4QJOEN.js +72 -0
  12. package/dist/chunk-QP4QJOEN.js.map +1 -0
  13. package/dist/css/components/activity-feed.css +240 -0
  14. package/dist/css/components/attachment.css +266 -0
  15. package/dist/css/components/breadcrumb.css +110 -0
  16. package/dist/css/components/calendar.css +159 -0
  17. package/dist/css/components/chart-tooltip.css +168 -0
  18. package/dist/css/components/chart.css +296 -0
  19. package/dist/css/components/code-block.css +264 -0
  20. package/dist/css/components/color-area.css +82 -0
  21. package/dist/css/components/color-field.css +67 -0
  22. package/dist/css/components/color-picker.css +131 -0
  23. package/dist/css/components/color-slider.css +113 -0
  24. package/dist/css/components/command-search.css +252 -0
  25. package/dist/css/components/context-menu.css +23 -0
  26. package/dist/css/components/credit-card.css +288 -0
  27. package/dist/css/components/data-table.css +591 -0
  28. package/dist/css/components/date-range-picker.css +168 -0
  29. package/dist/css/components/date-time-picker.css +178 -0
  30. package/dist/css/components/drawer.css +58 -0
  31. package/dist/css/components/editable-table.css +201 -0
  32. package/dist/css/components/empty-state.css +61 -0
  33. package/dist/css/components/file-explorer.css +633 -0
  34. package/dist/css/components/filter-builder.css +232 -0
  35. package/dist/css/components/hold-confirm.css +87 -0
  36. package/dist/css/components/hover-card.css +20 -0
  37. package/dist/css/components/image-preview.css +195 -0
  38. package/dist/css/components/input-otp.css +10 -0
  39. package/dist/css/components/json-viewer.css +272 -0
  40. package/dist/css/components/like-button.css +78 -0
  41. package/dist/css/components/link-preview.css +275 -0
  42. package/dist/css/components/loading-button.css +77 -0
  43. package/dist/css/components/multi-select.css +267 -0
  44. package/dist/css/components/notification-bell.css +127 -0
  45. package/dist/css/components/pagination.css +11 -0
  46. package/dist/css/components/password-strength.css +183 -0
  47. package/dist/css/components/popover.css +25 -0
  48. package/dist/css/components/progress.css +140 -0
  49. package/dist/css/components/quantity.css +16 -0
  50. package/dist/css/components/questionnaire.css +217 -0
  51. package/dist/css/components/range-calendar.css +186 -0
  52. package/dist/css/components/range-slider.css +192 -0
  53. package/dist/css/components/resizable-panel.css +243 -0
  54. package/dist/css/components/rich-text-editor.css +284 -0
  55. package/dist/css/components/scratch-card.css +75 -0
  56. package/dist/css/components/skeleton.css +108 -0
  57. package/dist/css/components/slot-picker.css +126 -0
  58. package/dist/css/components/split-view.css +19 -0
  59. package/dist/css/components/star-rating.css +80 -0
  60. package/dist/css/components/stat-card.css +164 -0
  61. package/dist/css/components/studio-dock.css +35 -0
  62. package/dist/css/components/swipe-actions.css +105 -0
  63. package/dist/css/components/tag-input.css +244 -0
  64. package/dist/css/components/time-field.css +88 -0
  65. package/dist/css/components/timeline.css +219 -0
  66. package/dist/css/components/tooltip.css +79 -0
  67. package/dist/css/components/trailer.css +37 -0
  68. package/dist/css/components/tree-view.css +210 -0
  69. package/dist/css/components/virtual-list.css +195 -0
  70. package/dist/css/controls.css +65 -0
  71. package/dist/css/tokens.css +185 -181
  72. package/dist/elements/index.d.ts +742 -5
  73. package/dist/elements/index.js +1527 -8
  74. package/dist/elements/index.js.map +1 -1
  75. package/dist/{engine-GDGwQnJE.d.ts → engine-Cn6IhE3z.d.ts} +1 -1
  76. package/dist/engine-QECQnGz1.d.ts +33 -0
  77. package/dist/index.css +10113 -181
  78. package/dist/index.d.ts +89 -5
  79. package/dist/index.js +285 -9
  80. package/dist/index.js.map +1 -1
  81. package/dist/react/index.d.ts +678 -23
  82. package/dist/react/index.js +2389 -7
  83. package/dist/react/index.js.map +1 -1
  84. package/dist/{reduced-B98f8LPs.d.ts → reduced-BBUusld6.d.ts} +206 -2
  85. package/dist/reveal-DEvp6U6T.d.ts +2381 -0
  86. package/dist/{store-pHiUvxP8.d.ts → store-DjkTBX7f.d.ts} +2 -2
  87. package/package.json +1 -1
  88. package/registry.json +583 -104
  89. package/skills/motion-kit/SKILL.md +209 -189
  90. package/src/auto/auto-init.ts +136 -0
  91. package/src/components/activity-feed/README.md +56 -0
  92. package/src/components/activity-feed/activity-feed.css +239 -0
  93. package/src/components/activity-feed/element.ts +36 -0
  94. package/src/components/activity-feed/engine.ts +351 -0
  95. package/src/components/activity-feed/react.tsx +32 -0
  96. package/src/components/attachment/README.md +27 -0
  97. package/src/components/attachment/attachment.css +265 -0
  98. package/src/components/attachment/element.ts +50 -0
  99. package/src/components/attachment/engine.ts +469 -0
  100. package/src/components/attachment/react.tsx +65 -0
  101. package/src/components/breadcrumb/README.md +38 -0
  102. package/src/components/breadcrumb/breadcrumb.css +109 -0
  103. package/src/components/breadcrumb/element.ts +27 -0
  104. package/src/components/breadcrumb/engine.ts +249 -0
  105. package/src/components/breadcrumb/react.tsx +30 -0
  106. package/src/components/calendar/README.md +82 -0
  107. package/src/components/calendar/calendar.css +158 -0
  108. package/src/components/calendar/element.ts +27 -0
  109. package/src/components/calendar/engine.ts +412 -0
  110. package/src/components/calendar/react.tsx +69 -0
  111. package/src/components/chart/README.md +24 -0
  112. package/src/components/chart/chart.css +295 -0
  113. package/src/components/chart/element.ts +41 -0
  114. package/src/components/chart/engine.ts +811 -0
  115. package/src/components/chart/react.tsx +50 -0
  116. package/src/components/chart-tooltip/README.md +53 -0
  117. package/src/components/chart-tooltip/chart-tooltip.css +167 -0
  118. package/src/components/chart-tooltip/element.ts +37 -0
  119. package/src/components/chart-tooltip/engine.ts +442 -0
  120. package/src/components/chart-tooltip/react.tsx +47 -0
  121. package/src/components/code-block/README.md +19 -0
  122. package/src/components/code-block/code-block.css +263 -0
  123. package/src/components/code-block/element.ts +34 -0
  124. package/src/components/code-block/engine.ts +254 -0
  125. package/src/components/code-block/highlight.ts +244 -0
  126. package/src/components/code-block/react.tsx +94 -0
  127. package/src/components/color-area/README.md +50 -0
  128. package/src/components/color-area/color-area.css +81 -0
  129. package/src/components/color-area/element.ts +26 -0
  130. package/src/components/color-area/engine.ts +246 -0
  131. package/src/components/color-area/react.tsx +42 -0
  132. package/src/components/color-field/README.md +43 -0
  133. package/src/components/color-field/color-field.css +66 -0
  134. package/src/components/color-field/element.ts +26 -0
  135. package/src/components/color-field/engine.ts +174 -0
  136. package/src/components/color-field/react.tsx +42 -0
  137. package/src/components/color-picker/README.md +45 -0
  138. package/src/components/color-picker/color-picker.css +130 -0
  139. package/src/components/color-picker/element.ts +45 -0
  140. package/src/components/color-picker/engine.ts +314 -0
  141. package/src/components/color-picker/react.tsx +47 -0
  142. package/src/components/color-slider/README.md +55 -0
  143. package/src/components/color-slider/color-slider.css +112 -0
  144. package/src/components/color-slider/element.ts +26 -0
  145. package/src/components/color-slider/engine.ts +234 -0
  146. package/src/components/color-slider/react.tsx +45 -0
  147. package/src/components/command-search/README.md +15 -0
  148. package/src/components/command-search/command-search.css +251 -0
  149. package/src/components/command-search/element.ts +36 -0
  150. package/src/components/command-search/engine.ts +356 -0
  151. package/src/components/command-search/match.ts +53 -0
  152. package/src/components/command-search/react.tsx +66 -0
  153. package/src/components/context-menu/README.md +31 -0
  154. package/src/components/context-menu/context-menu.css +22 -0
  155. package/src/components/context-menu/element.ts +40 -0
  156. package/src/components/context-menu/engine.ts +153 -0
  157. package/src/components/context-menu/react.tsx +57 -0
  158. package/src/components/credit-card/README.md +20 -0
  159. package/src/components/credit-card/card.ts +77 -0
  160. package/src/components/credit-card/credit-card.css +287 -0
  161. package/src/components/credit-card/element.ts +33 -0
  162. package/src/components/credit-card/engine.ts +410 -0
  163. package/src/components/credit-card/react.tsx +36 -0
  164. package/src/components/data-table/README.md +83 -0
  165. package/src/components/data-table/data-table.css +590 -0
  166. package/src/components/data-table/element.ts +54 -0
  167. package/src/components/data-table/engine.ts +1059 -0
  168. package/src/components/data-table/react.tsx +94 -0
  169. package/src/components/date-range-picker/README.md +51 -0
  170. package/src/components/date-range-picker/date-range-picker.css +167 -0
  171. package/src/components/date-range-picker/element.ts +52 -0
  172. package/src/components/date-range-picker/engine.ts +352 -0
  173. package/src/components/date-range-picker/react.tsx +57 -0
  174. package/src/components/date-time-picker/README.md +48 -0
  175. package/src/components/date-time-picker/date-time-picker.css +177 -0
  176. package/src/components/date-time-picker/element.ts +47 -0
  177. package/src/components/date-time-picker/engine.ts +350 -0
  178. package/src/components/date-time-picker/react.tsx +54 -0
  179. package/src/components/dialog/README.md +103 -102
  180. package/src/components/dialog/element.ts +123 -118
  181. package/src/components/dialog/engine.ts +449 -432
  182. package/src/components/drawer/README.md +28 -0
  183. package/src/components/drawer/drawer.css +57 -0
  184. package/src/components/drawer/element.ts +21 -0
  185. package/src/components/drawer/engine.ts +56 -0
  186. package/src/components/drawer/react.tsx +85 -0
  187. package/src/components/editable-table/README.md +67 -0
  188. package/src/components/editable-table/editable-table.css +200 -0
  189. package/src/components/editable-table/element.ts +45 -0
  190. package/src/components/editable-table/engine.ts +775 -0
  191. package/src/components/editable-table/react.tsx +79 -0
  192. package/src/components/empty-state/README.md +41 -0
  193. package/src/components/empty-state/element.ts +23 -0
  194. package/src/components/empty-state/empty-state.css +60 -0
  195. package/src/components/empty-state/engine.ts +232 -0
  196. package/src/components/empty-state/react.tsx +34 -0
  197. package/src/components/file-explorer/README.md +67 -0
  198. package/src/components/file-explorer/element.ts +39 -0
  199. package/src/components/file-explorer/engine.ts +1307 -0
  200. package/src/components/file-explorer/file-explorer.css +632 -0
  201. package/src/components/file-explorer/react.tsx +77 -0
  202. package/src/components/filter-builder/README.md +47 -0
  203. package/src/components/filter-builder/element.ts +34 -0
  204. package/src/components/filter-builder/engine.ts +365 -0
  205. package/src/components/filter-builder/filter-builder.css +231 -0
  206. package/src/components/filter-builder/react.tsx +36 -0
  207. package/src/components/hold-confirm/README.md +13 -0
  208. package/src/components/hold-confirm/element.ts +24 -0
  209. package/src/components/hold-confirm/engine.ts +216 -0
  210. package/src/components/hold-confirm/hold-confirm.css +86 -0
  211. package/src/components/hold-confirm/react.tsx +28 -0
  212. package/src/components/hover-card/README.md +20 -0
  213. package/src/components/hover-card/element.ts +8 -0
  214. package/src/components/hover-card/engine.ts +131 -0
  215. package/src/components/hover-card/hover-card.css +19 -0
  216. package/src/components/hover-card/react.tsx +19 -0
  217. package/src/components/image-preview/README.md +16 -0
  218. package/src/components/image-preview/element.ts +26 -0
  219. package/src/components/image-preview/engine.ts +325 -0
  220. package/src/components/image-preview/image-preview.css +194 -0
  221. package/src/components/image-preview/react.tsx +43 -0
  222. package/src/components/input-otp/README.md +18 -0
  223. package/src/components/input-otp/element.ts +14 -0
  224. package/src/components/input-otp/engine.ts +106 -0
  225. package/src/components/input-otp/input-otp.css +9 -0
  226. package/src/components/input-otp/react.tsx +21 -0
  227. package/src/components/json-viewer/README.md +56 -0
  228. package/src/components/json-viewer/element.ts +37 -0
  229. package/src/components/json-viewer/engine.ts +440 -0
  230. package/src/components/json-viewer/json-viewer.css +271 -0
  231. package/src/components/json-viewer/react.tsx +56 -0
  232. package/src/components/like-button/README.md +13 -0
  233. package/src/components/like-button/element.ts +47 -0
  234. package/src/components/like-button/engine.ts +145 -0
  235. package/src/components/like-button/like-button.css +77 -0
  236. package/src/components/like-button/react.tsx +39 -0
  237. package/src/components/link-preview/README.md +19 -0
  238. package/src/components/link-preview/element.ts +29 -0
  239. package/src/components/link-preview/engine.ts +192 -0
  240. package/src/components/link-preview/link-preview.css +274 -0
  241. package/src/components/link-preview/react.tsx +101 -0
  242. package/src/components/loading-button/README.md +45 -0
  243. package/src/components/loading-button/element.ts +34 -0
  244. package/src/components/loading-button/engine.ts +201 -0
  245. package/src/components/loading-button/loading-button.css +76 -0
  246. package/src/components/loading-button/react.tsx +43 -0
  247. package/src/components/multi-select/README.md +48 -0
  248. package/src/components/multi-select/element.ts +28 -0
  249. package/src/components/multi-select/engine.ts +294 -0
  250. package/src/components/multi-select/multi-select.css +266 -0
  251. package/src/components/multi-select/react.tsx +39 -0
  252. package/src/components/notification-bell/README.md +14 -0
  253. package/src/components/notification-bell/element.ts +48 -0
  254. package/src/components/notification-bell/engine.ts +202 -0
  255. package/src/components/notification-bell/notification-bell.css +126 -0
  256. package/src/components/notification-bell/react.tsx +57 -0
  257. package/src/components/pagination/README.md +17 -0
  258. package/src/components/pagination/element.ts +14 -0
  259. package/src/components/pagination/engine.ts +102 -0
  260. package/src/components/pagination/pagination.css +10 -0
  261. package/src/components/pagination/react.tsx +22 -0
  262. package/src/components/password-strength/README.md +17 -0
  263. package/src/components/password-strength/element.ts +22 -0
  264. package/src/components/password-strength/engine.ts +212 -0
  265. package/src/components/password-strength/password-strength.css +182 -0
  266. package/src/components/password-strength/react.tsx +36 -0
  267. package/src/components/password-strength/score.ts +62 -0
  268. package/src/components/popover/README.md +44 -0
  269. package/src/components/popover/element.ts +31 -0
  270. package/src/components/popover/engine.ts +114 -0
  271. package/src/components/popover/popover.css +24 -0
  272. package/src/components/popover/react.tsx +50 -0
  273. package/src/components/progress/README.md +17 -0
  274. package/src/components/progress/element.ts +30 -0
  275. package/src/components/progress/engine.ts +173 -0
  276. package/src/components/progress/progress.css +139 -0
  277. package/src/components/progress/react.tsx +35 -0
  278. package/src/components/quantity/README.md +20 -0
  279. package/src/components/quantity/element.ts +14 -0
  280. package/src/components/quantity/engine.ts +85 -0
  281. package/src/components/quantity/quantity.css +15 -0
  282. package/src/components/quantity/react.tsx +21 -0
  283. package/src/components/questionnaire/README.md +32 -0
  284. package/src/components/questionnaire/element.ts +118 -0
  285. package/src/components/questionnaire/engine.ts +255 -0
  286. package/src/components/questionnaire/questionnaire.css +216 -0
  287. package/src/components/questionnaire/react.tsx +140 -0
  288. package/src/components/range-calendar/README.md +58 -0
  289. package/src/components/range-calendar/element.ts +42 -0
  290. package/src/components/range-calendar/engine.ts +390 -0
  291. package/src/components/range-calendar/range-calendar.css +185 -0
  292. package/src/components/range-calendar/react.tsx +56 -0
  293. package/src/components/range-slider/README.md +23 -0
  294. package/src/components/range-slider/element.ts +53 -0
  295. package/src/components/range-slider/engine.ts +316 -0
  296. package/src/components/range-slider/range-slider.css +191 -0
  297. package/src/components/range-slider/react.tsx +66 -0
  298. package/src/components/resizable-panel/README.md +61 -0
  299. package/src/components/resizable-panel/element.ts +36 -0
  300. package/src/components/resizable-panel/engine.ts +551 -0
  301. package/src/components/resizable-panel/react.tsx +74 -0
  302. package/src/components/resizable-panel/resizable-panel.css +242 -0
  303. package/src/components/rich-text-editor/README.md +57 -0
  304. package/src/components/rich-text-editor/element.ts +34 -0
  305. package/src/components/rich-text-editor/engine.ts +673 -0
  306. package/src/components/rich-text-editor/react.tsx +60 -0
  307. package/src/components/rich-text-editor/rich-text-editor.css +283 -0
  308. package/src/components/scratch-card/README.md +15 -0
  309. package/src/components/scratch-card/element.ts +30 -0
  310. package/src/components/scratch-card/engine.ts +257 -0
  311. package/src/components/scratch-card/react.tsx +40 -0
  312. package/src/components/scratch-card/scratch-card.css +74 -0
  313. package/src/components/skeleton/README.md +15 -0
  314. package/src/components/skeleton/element.ts +32 -0
  315. package/src/components/skeleton/engine.ts +104 -0
  316. package/src/components/skeleton/react.tsx +41 -0
  317. package/src/components/skeleton/skeleton.css +107 -0
  318. package/src/components/slot-picker/README.md +68 -0
  319. package/src/components/slot-picker/element.ts +27 -0
  320. package/src/components/slot-picker/engine.ts +412 -0
  321. package/src/components/slot-picker/react.tsx +76 -0
  322. package/src/components/slot-picker/slot-picker.css +125 -0
  323. package/src/components/split-view/README.md +50 -0
  324. package/src/components/split-view/element.ts +34 -0
  325. package/src/components/split-view/engine.ts +114 -0
  326. package/src/components/split-view/react.tsx +63 -0
  327. package/src/components/split-view/split-view.css +18 -0
  328. package/src/components/star-rating/README.md +14 -0
  329. package/src/components/star-rating/element.ts +26 -0
  330. package/src/components/star-rating/engine.ts +217 -0
  331. package/src/components/star-rating/react.tsx +33 -0
  332. package/src/components/star-rating/star-rating.css +79 -0
  333. package/src/components/stat-card/README.md +42 -0
  334. package/src/components/stat-card/element.ts +40 -0
  335. package/src/components/stat-card/engine.ts +283 -0
  336. package/src/components/stat-card/react.tsx +36 -0
  337. package/src/components/stat-card/stat-card.css +163 -0
  338. package/src/components/studio-dock/README.md +44 -0
  339. package/src/components/studio-dock/element.ts +11 -0
  340. package/src/components/studio-dock/engine.ts +212 -0
  341. package/src/components/studio-dock/react.tsx +23 -0
  342. package/src/components/studio-dock/studio-dock.css +34 -0
  343. package/src/components/swipe-actions/README.md +19 -0
  344. package/src/components/swipe-actions/element.ts +26 -0
  345. package/src/components/swipe-actions/engine.ts +260 -0
  346. package/src/components/swipe-actions/react.tsx +80 -0
  347. package/src/components/swipe-actions/swipe-actions.css +104 -0
  348. package/src/components/tag-input/README.md +42 -0
  349. package/src/components/tag-input/element.ts +39 -0
  350. package/src/components/tag-input/engine.ts +313 -0
  351. package/src/components/tag-input/react.tsx +54 -0
  352. package/src/components/tag-input/tag-input.css +243 -0
  353. package/src/components/time-field/README.md +54 -0
  354. package/src/components/time-field/element.ts +38 -0
  355. package/src/components/time-field/engine.ts +110 -0
  356. package/src/components/time-field/react.tsx +45 -0
  357. package/src/components/time-field/time-field.css +87 -0
  358. package/src/components/timeline/README.md +57 -0
  359. package/src/components/timeline/element.ts +31 -0
  360. package/src/components/timeline/engine.ts +300 -0
  361. package/src/components/timeline/react.tsx +59 -0
  362. package/src/components/timeline/timeline.css +218 -0
  363. package/src/components/tooltip/README.md +46 -0
  364. package/src/components/tooltip/element.ts +22 -0
  365. package/src/components/tooltip/engine.ts +288 -0
  366. package/src/components/tooltip/react.tsx +30 -0
  367. package/src/components/tooltip/tooltip.css +78 -0
  368. package/src/components/trailer/README.md +28 -0
  369. package/src/components/trailer/element.ts +13 -0
  370. package/src/components/trailer/engine.ts +189 -0
  371. package/src/components/trailer/react.tsx +16 -0
  372. package/src/components/trailer/trailer.css +36 -0
  373. package/src/components/tree-view/README.md +61 -0
  374. package/src/components/tree-view/element.ts +32 -0
  375. package/src/components/tree-view/engine.ts +569 -0
  376. package/src/components/tree-view/react.tsx +78 -0
  377. package/src/components/tree-view/tree-view.css +209 -0
  378. package/src/components/virtual-list/README.md +81 -0
  379. package/src/components/virtual-list/element.ts +42 -0
  380. package/src/components/virtual-list/engine.ts +678 -0
  381. package/src/components/virtual-list/react.tsx +101 -0
  382. package/src/components/virtual-list/virtual-list.css +194 -0
  383. package/src/core/chips.ts +196 -0
  384. package/src/core/color.ts +304 -0
  385. package/src/core/date-range.ts +67 -0
  386. package/src/core/dates.ts +108 -0
  387. package/src/core/files.ts +107 -0
  388. package/src/core/filter.ts +229 -0
  389. package/src/core/gsap.ts +80 -65
  390. package/src/core/listbox.ts +332 -0
  391. package/src/core/mark.ts +29 -0
  392. package/src/core/position.ts +89 -0
  393. package/src/core/relative-time.ts +77 -0
  394. package/src/core/segment-field.ts +373 -0
  395. package/src/core/segments.ts +153 -0
  396. package/src/core/tree.ts +116 -0
  397. package/src/core/virtual.ts +79 -0
  398. package/src/css/controls/README.md +14 -0
  399. package/src/css/controls/status.css +63 -0
  400. package/src/css/tokens.css +186 -182
  401. package/src/elements/index.ts +171 -0
  402. package/src/index.ts +97 -0
  403. package/src/motion/micro.ts +248 -0
  404. package/src/motion/sheet.ts +88 -65
  405. package/src/motion/surface.ts +9 -0
  406. package/src/react/index.ts +78 -0
  407. package/src/react/use-action-button.ts +6 -0
  408. package/src/react/use-editorial-reveal.ts +7 -0
  409. package/src/react/use-film-hero.ts +6 -0
  410. package/src/react/use-font-cycle.ts +7 -0
  411. package/src/react/use-image-zoom.ts +5 -0
  412. package/src/react/use-joined-cta.ts +5 -0
  413. package/src/react/use-local-clock.ts +5 -0
  414. package/src/react/use-scroll-dock.ts +5 -0
  415. package/src/react/use-sticker.ts +5 -0
  416. package/src/react/use-studio-dock.ts +8 -0
  417. package/src/react/use-thumbnail-nav.ts +7 -0
  418. package/src/react/use-trailer.ts +6 -0
  419. package/src/react/use-weight-hover.ts +5 -0
  420. package/src/recipes/action-button/README.md +31 -0
  421. package/src/recipes/action-button/action-button.css +113 -0
  422. package/src/recipes/action-button/create-action-button.ts +56 -0
  423. package/src/recipes/editorial-reveal/README.md +35 -0
  424. package/src/recipes/editorial-reveal/create-editorial-reveal.ts +91 -0
  425. package/src/recipes/editorial-reveal/editorial-reveal.css +17 -0
  426. package/src/recipes/film-hero/README.md +23 -0
  427. package/src/recipes/film-hero/create-film-hero.ts +65 -0
  428. package/src/recipes/film-hero/film-hero.css +29 -0
  429. package/src/recipes/font-cycle/README.md +11 -0
  430. package/src/recipes/font-cycle/create-font-cycle.ts +126 -0
  431. package/src/recipes/font-cycle/font-cycle.css +36 -0
  432. package/src/recipes/image-zoom/README.md +16 -0
  433. package/src/recipes/image-zoom/create-image-zoom.ts +27 -0
  434. package/src/recipes/image-zoom/image-zoom.css +7 -0
  435. package/src/recipes/joined-cta/README.md +13 -0
  436. package/src/recipes/joined-cta/create-joined-cta.ts +22 -0
  437. package/src/recipes/joined-cta/joined-cta.css +17 -0
  438. package/src/recipes/local-clock/README.md +31 -0
  439. package/src/recipes/local-clock/create-local-clock.ts +61 -0
  440. package/src/recipes/scroll-dock/README.md +46 -0
  441. package/src/recipes/scroll-dock/create-scroll-dock.ts +72 -0
  442. package/src/recipes/scroll-dock/scroll-dock.css +70 -0
  443. package/src/recipes/sticker/README.md +59 -0
  444. package/src/recipes/sticker/create-sticker.ts +490 -0
  445. package/src/recipes/sticker/sticker.css +112 -0
  446. package/src/recipes/thumbnail-nav/README.md +16 -0
  447. package/src/recipes/thumbnail-nav/create-thumbnail-nav.ts +165 -0
  448. package/src/recipes/thumbnail-nav/thumbnail-nav.css +108 -0
  449. package/src/recipes/weight-hover/README.md +37 -0
  450. package/src/recipes/weight-hover/create-weight-hover.ts +136 -0
  451. package/src/recipes/weight-hover/weight-hover.css +7 -0
  452. package/dist/chunk-BFC27F2G.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-JQMJQSXD.js +0 -2374
  456. package/dist/chunk-JQMJQSXD.js.map +0 -1
  457. package/dist/chunk-XDWBVFHQ.js.map +0 -1
  458. package/dist/reveal-C0hCDcB_.d.ts +0 -415
@@ -0,0 +1,74 @@
1
+ /* scratch-card — a Melonmind card (20 px radius) whose content hides under a metallic cover; a small glass
2
+ "Revelar" pill sits on top for the keyboard. */
3
+ .mk-scratch-card,
4
+ mk-scratch-card {
5
+ position: relative;
6
+ display: block;
7
+ overflow: hidden;
8
+ border-radius: 20px;
9
+ background: var(--mk-surface-1);
10
+ box-shadow: inset 0 0 0 1px var(--mk-outline-soft);
11
+ isolation: isolate;
12
+ }
13
+
14
+ :is(.mk-scratch-card, mk-scratch-card) [data-mk-scratch-content] {
15
+ position: relative;
16
+ min-height: 9rem;
17
+ }
18
+
19
+ :is(.mk-scratch-card, mk-scratch-card) [data-mk-scratch-cover] {
20
+ position: absolute;
21
+ inset: 0;
22
+ z-index: 1;
23
+ cursor: crosshair;
24
+ touch-action: none;
25
+ }
26
+
27
+ :is(.mk-scratch-card, mk-scratch-card) [data-mk-scratch-cover] canvas {
28
+ display: block;
29
+ width: 100%;
30
+ height: 100%;
31
+ }
32
+
33
+ :is(.mk-scratch-card, mk-scratch-card) [data-mk-scratch-cover][data-mk-scratch-fallback] {
34
+ display: grid;
35
+ place-items: center;
36
+ background: linear-gradient(135deg, #c9ccd2, #eef0f3 45%, #d7dadf 55%, #a9adb5);
37
+ color: rgb(40 42 48 / 0.75);
38
+ font-weight: 600;
39
+ cursor: default;
40
+ }
41
+
42
+ :is(.mk-scratch-card, mk-scratch-card) [data-mk-scratch-cover][hidden] {
43
+ display: none;
44
+ }
45
+
46
+ :is(.mk-scratch-card, mk-scratch-card) [data-mk-scratch-reveal] {
47
+ position: absolute;
48
+ right: 0.75rem;
49
+ bottom: 0.75rem;
50
+ z-index: 2;
51
+ min-height: 2.25rem;
52
+ padding: 0 0.9rem;
53
+ border: 0;
54
+ border-radius: 64px;
55
+ background: rgb(20 21 24 / 0.72);
56
+ box-shadow:
57
+ inset 1px 1px 1px rgb(255 255 255 / 0.14),
58
+ inset -1px -1px 1px rgb(255 255 255 / 0.05);
59
+ backdrop-filter: blur(12px);
60
+ color: #fff;
61
+ font: inherit;
62
+ font-size: 0.8125rem;
63
+ font-weight: 500;
64
+ cursor: pointer;
65
+ }
66
+
67
+ :is(.mk-scratch-card, mk-scratch-card) [data-mk-scratch-reveal]:focus-visible {
68
+ outline: 2px solid var(--mk-accent);
69
+ outline-offset: 2px;
70
+ }
71
+
72
+ :is(.mk-scratch-card, mk-scratch-card) [data-mk-scratch-reveal][hidden] {
73
+ display: none;
74
+ }
@@ -0,0 +1,15 @@
1
+ # skeleton
2
+
3
+ Marcador de carga para texto, avatar, imagen o tarjeta. El placeholder es decorativo (`aria-hidden`) y el root marca `aria-busy` con un estado oculto que nombra lo que carga. El contenido real queda oculto sólo mientras carga.
4
+
5
+ ```html
6
+ <mk-skeleton class="mk-skeleton" shape="card" animation="shimmer" label="Cargando perfil">
7
+ <article data-mk-skeleton-content>…contenido real…</article>
8
+ </mk-skeleton>
9
+ ```
10
+
11
+ Con `[data-mk-skeleton-placeholder]` propio se usa ese marcado; sin él, el motor crea los huesos de `shape`. `defineElements()` (atributo `loaded` para terminar), `createSkeleton(root, options)` o `<Skeleton loading={pending} shape="avatar" label="Cargando autor"><Author /></Skeleton>`.
12
+
13
+ Opciones: `loading=true`, `animation='pulse'|'shimmer'|'none'`, `shape='text'|'avatar'|'image'|'card'`, `lines=3` (texto), `label='Cargando'`. API: `setLoading(boolean)`, `loading`, `destroy()`; evento `mk:loading` con `{loading}`. `skeletonBones(shape, lines)` devuelve los huesos para dibujar el mismo placeholder desde otro framework.
14
+
15
+ El contenido que el autor ya tenía `hidden` sigue oculto al terminar. En React, placeholder y contenido son subárboles distintos de React; el motor sólo cambia `hidden` y el estado. `destroy()` quita lo generado y restaura atributos. Variables: `--mk-skeleton-bone`, `--mk-skeleton-sheen`, `--mk-skeleton-radius`, `--mk-skeleton-duration` (1.6s). Movimiento reducido: superficie estática, sin pulso ni brillo.
@@ -0,0 +1,32 @@
1
+ import { MkElement, defineElement, type OptionType } from '../../elements/base';
2
+ import { createSkeleton, type SkeletonInstance } from './engine';
3
+
4
+ /**
5
+ * <mk-skeleton class="mk-skeleton" shape="card" label="Cargando perfil">
6
+ * <article data-mk-skeleton-content>…</article>
7
+ * </mk-skeleton>
8
+ * Loading until `loaded` is set (or `setLoading(false)`); a placeholder is made from `shape`.
9
+ */
10
+ export class MkSkeletonElement extends MkElement<SkeletonInstance> {
11
+ static options: Record<string, OptionType> = { loaded: 'boolean', animation: 'string', shape: 'string', lines: 'number', label: 'string' };
12
+
13
+ protected create(options: Record<string, unknown>) {
14
+ return createSkeleton(this, { ...options, loading: !options.loaded });
15
+ }
16
+
17
+ attributeChangedCallback(name: string, previous: string | null, next: string | null) {
18
+ if (previous === next || !this.instance) return;
19
+ if (name === 'loaded') this.instance.setLoading(next === null || next === 'false');
20
+ else super.attributeChangedCallback(name, previous, next);
21
+ }
22
+
23
+ setLoading(loading: boolean) {
24
+ this.instance?.setLoading(loading);
25
+ }
26
+
27
+ get loading() {
28
+ return this.instance?.loading ?? false;
29
+ }
30
+ }
31
+
32
+ export const defineSkeleton = () => defineElement('mk-skeleton', MkSkeletonElement);
@@ -0,0 +1,104 @@
1
+ import type { gsap } from '../../core/gsap';
2
+ import { createScope } from '../../core/scope';
3
+ import { inert, type Instance } from '../../core/types';
4
+ import { blurIn } from '../../motion/micro';
5
+
6
+ /*
7
+ * Skeleton: a decorative placeholder ([data-mk-skeleton-placeholder], made from
8
+ * `shape` when absent) stands in for the real content ([data-mk-skeleton-content])
9
+ * while loading. The root is aria-busy and a hidden status names what loads; the
10
+ * placeholder is aria-hidden. Content the author hid stays hidden. Pulse and
11
+ * shimmer are CSS; reduced motion keeps a still surface.
12
+ */
13
+
14
+ export type SkeletonShape = 'text' | 'avatar' | 'image' | 'card';
15
+ export type SkeletonAnimation = 'pulse' | 'shimmer' | 'none';
16
+
17
+ export interface SkeletonOptions {
18
+ loading?: boolean;
19
+ animation?: SkeletonAnimation;
20
+ /** Placeholder made when the markup has none. */
21
+ shape?: SkeletonShape;
22
+ /** Text lines of a generated text placeholder (default 3). */
23
+ lines?: number;
24
+ /** Announced while loading (default 'Cargando'). */
25
+ label?: string;
26
+ }
27
+
28
+ export interface SkeletonInstance extends Instance {
29
+ setLoading(loading: boolean): void;
30
+ readonly loading: boolean;
31
+ }
32
+
33
+ /** Bones of each shape: block (image), circle (avatar), line (text). */
34
+ export function skeletonBones(shape: SkeletonShape, lines = 3): Array<'block' | 'circle' | 'line' | 'short'> {
35
+ const count = Math.max(1, Math.round(lines) || 1);
36
+ const text = Array.from({ length: count }, (_, i) => (i === count - 1 && count > 1 ? 'short' : 'line') as 'line' | 'short');
37
+ if (shape === 'avatar') return ['circle', 'line', 'short'];
38
+ if (shape === 'image') return ['block'];
39
+ if (shape === 'card') return ['block', 'line', 'short'];
40
+ return text;
41
+ }
42
+
43
+ export function createSkeleton(root: HTMLElement | null, options: SkeletonOptions = {}): SkeletonInstance {
44
+ if (!root) return inert({ setLoading() {}, loading: false });
45
+ const scope = createScope();
46
+ const shape = options.shape ?? 'text';
47
+ const animation = options.animation ?? 'pulse';
48
+ let loading = options.loading ?? true;
49
+
50
+ let placeholder = root.querySelector<HTMLElement>('[data-mk-skeleton-placeholder]');
51
+ if (!placeholder) {
52
+ const made = document.createElement('div');
53
+ made.dataset.mkSkeletonPlaceholder = '';
54
+ made.dataset.mkShape = shape;
55
+ for (const bone of skeletonBones(shape, options.lines)) {
56
+ const element = document.createElement('span');
57
+ element.dataset.mkBone = bone;
58
+ made.append(element);
59
+ }
60
+ root.prepend(made);
61
+ scope.add(() => made.remove());
62
+ placeholder = made;
63
+ }
64
+ const contents = [...root.querySelectorAll<HTMLElement>('[data-mk-skeleton-content]')];
65
+ const authoredHidden = new Map(contents.map((content) => [content, content.hidden]));
66
+ const status = document.createElement('span');
67
+ status.className = 'mk-sr-only';
68
+ status.dataset.mkSkeletonStatus = '';
69
+ root.append(status);
70
+ scope.add(() => status.remove());
71
+
72
+ scope.attr(placeholder, 'aria-hidden', 'true');
73
+ scope.attr(root, 'data-mk-shape', shape);
74
+ scope.attr(root, 'data-mk-animation', animation);
75
+ scope.attr(root, 'data-mk-ready', '');
76
+
77
+ // The reveal animates the content's inline style: the authored one comes back on destroy.
78
+ for (const content of contents) scope.attr(content, 'style', content.getAttribute('style'));
79
+ let reveal: gsap.core.Animation | null = null;
80
+ scope.add(() => reveal?.progress(1).kill());
81
+ const render = () => {
82
+ scope.attr(root, 'aria-busy', String(loading));
83
+ scope.attr(placeholder!, 'hidden', loading ? null : '');
84
+ for (const content of contents) scope.attr(content, 'hidden', loading || authoredHidden.get(content) ? '' : null);
85
+ status.textContent = loading ? options.label ?? 'Cargando' : '';
86
+ };
87
+ render();
88
+
89
+ return {
90
+ setLoading(next) {
91
+ if (scope.disposed || next === loading) return;
92
+ loading = next;
93
+ render();
94
+ // Melonmind's list entrance (blur 16, y −20, 50 ms apart) for what was waiting.
95
+ reveal?.progress(1).kill();
96
+ if (!loading) reveal = blurIn(contents.filter((content) => !content.hidden), { stagger: 0.05 });
97
+ root.dispatchEvent(new CustomEvent('mk:loading', { bubbles: true, detail: { loading } }));
98
+ },
99
+ get loading() {
100
+ return loading;
101
+ },
102
+ destroy: () => scope.dispose(),
103
+ };
104
+ }
@@ -0,0 +1,41 @@
1
+ 'use client';
2
+ import { useRef, type HTMLAttributes, type ReactNode } from 'react';
3
+ import { useIsomorphicLayoutEffect } from '../../react/use-recipe';
4
+ import { createSkeleton, skeletonBones, type SkeletonInstance, type SkeletonOptions } from './engine';
5
+
6
+ export interface SkeletonProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'>, SkeletonOptions {
7
+ /** The real content, shown when loading ends. */
8
+ children?: ReactNode;
9
+ /** Custom placeholder instead of the shape's bones. */
10
+ placeholder?: ReactNode;
11
+ }
12
+
13
+ /**
14
+ * <Skeleton loading={pending} shape="card" label="Cargando perfil"><ProfileCard /></Skeleton>.
15
+ * React owns placeholder and content; the engine only toggles hidden and the busy state.
16
+ */
17
+ export function Skeleton({ loading = true, animation, shape = 'text', lines, label, placeholder, children, className, ...props }: SkeletonProps) {
18
+ const ref = useRef<HTMLDivElement>(null);
19
+ const instance = useRef<SkeletonInstance | null>(null);
20
+ const current = useRef(loading);
21
+ current.current = loading;
22
+ useIsomorphicLayoutEffect(() => {
23
+ const created = createSkeleton(ref.current, { loading: current.current, animation, shape, lines, label });
24
+ instance.current = created;
25
+ return () => {
26
+ created.destroy();
27
+ instance.current = null;
28
+ };
29
+ }, [animation, shape, lines, label]);
30
+ useIsomorphicLayoutEffect(() => {
31
+ instance.current?.setLoading(loading);
32
+ }, [loading]);
33
+ return (
34
+ <div {...props} ref={ref} className={['mk-skeleton', className].filter(Boolean).join(' ')} data-mk-ssr-loading={loading ? '' : undefined}>
35
+ <div data-mk-skeleton-placeholder="" data-mk-shape={shape}>
36
+ {placeholder ?? skeletonBones(shape, lines).map((bone, i) => <span key={i} data-mk-bone={bone} />)}
37
+ </div>
38
+ <div data-mk-skeleton-content="">{children}</div>
39
+ </div>
40
+ );
41
+ }
@@ -0,0 +1,107 @@
1
+ /* skeleton — soft bones on the surface tone; pulse (opacity) or shimmer (a passing sheen). */
2
+ .mk-skeleton,
3
+ mk-skeleton {
4
+ --mk-skeleton-bone: var(--mk-surface-3);
5
+ --mk-skeleton-sheen: color-mix(in srgb, var(--mk-surface-1) 80%, transparent);
6
+ --mk-skeleton-radius: var(--mk-radius-md, 16px);
7
+ /* Melonmind animation-loading-2: a sheen crossing in 1 s. */
8
+ --mk-skeleton-duration: 1s;
9
+ display: block;
10
+ }
11
+
12
+ :is(.mk-skeleton, mk-skeleton) [data-mk-skeleton-placeholder] {
13
+ display: grid;
14
+ gap: 0.625rem;
15
+ }
16
+
17
+ :is(.mk-skeleton, mk-skeleton) [data-mk-skeleton-placeholder][hidden],
18
+ :is(.mk-skeleton, mk-skeleton) [data-mk-skeleton-content][hidden] {
19
+ display: none !important;
20
+ }
21
+
22
+ /* Before the engine runs (server render), the React state decides what shows. */
23
+ :is(.mk-skeleton, mk-skeleton):not([data-mk-ready])[data-mk-ssr-loading] > [data-mk-skeleton-content],
24
+ :is(.mk-skeleton, mk-skeleton):not([data-mk-ready]):not([data-mk-ssr-loading]) > [data-mk-skeleton-placeholder] {
25
+ display: none;
26
+ }
27
+
28
+ :is(.mk-skeleton, mk-skeleton) [data-mk-bone] {
29
+ position: relative;
30
+ display: block;
31
+ overflow: hidden;
32
+ height: 0.875rem;
33
+ border-radius: var(--mk-radius-full);
34
+ background: var(--mk-skeleton-bone);
35
+ }
36
+
37
+ :is(.mk-skeleton, mk-skeleton) [data-mk-bone='short'] {
38
+ width: 62%;
39
+ }
40
+
41
+ :is(.mk-skeleton, mk-skeleton) [data-mk-bone='circle'] {
42
+ width: 3.5rem;
43
+ height: 3.5rem;
44
+ border-radius: 50%;
45
+ }
46
+
47
+ :is(.mk-skeleton, mk-skeleton) [data-mk-bone='block'] {
48
+ height: auto;
49
+ aspect-ratio: 16 / 9;
50
+ border-radius: var(--mk-skeleton-radius);
51
+ }
52
+
53
+ /* Avatar: circle beside two lines. */
54
+ :is(.mk-skeleton, mk-skeleton) [data-mk-shape='avatar'] {
55
+ grid-template-columns: auto minmax(0, 1fr);
56
+ align-items: center;
57
+ column-gap: 1rem;
58
+ }
59
+
60
+ :is(.mk-skeleton, mk-skeleton) [data-mk-shape='avatar'] [data-mk-bone='circle'] {
61
+ grid-row: span 2;
62
+ }
63
+
64
+ :is(.mk-skeleton, mk-skeleton) [data-mk-shape='card'] {
65
+ padding: 0.5rem 0.5rem 1rem;
66
+ border-radius: var(--mk-radius-lg, 24px);
67
+ background: var(--mk-surface-1);
68
+ box-shadow: inset 0 0 0 1px var(--mk-outline-soft);
69
+ }
70
+
71
+ :is(.mk-skeleton, mk-skeleton)[data-mk-animation='pulse'][aria-busy='true'] [data-mk-bone] {
72
+ animation: mk-skeleton-pulse var(--mk-skeleton-duration) ease-in-out infinite;
73
+ }
74
+
75
+ :is(.mk-skeleton, mk-skeleton)[data-mk-animation='shimmer'][aria-busy='true'] [data-mk-bone]::after {
76
+ content: '';
77
+ position: absolute;
78
+ inset: 0;
79
+ background: linear-gradient(90deg, transparent, var(--mk-skeleton-sheen), transparent);
80
+ transform: translateX(-100%);
81
+ animation: mk-skeleton-shimmer var(--mk-skeleton-duration) linear infinite;
82
+ }
83
+
84
+
85
+ @keyframes mk-skeleton-pulse {
86
+ 50% { opacity: 0.45; }
87
+ }
88
+
89
+ @keyframes mk-skeleton-shimmer {
90
+ to { transform: translateX(100%); }
91
+ }
92
+
93
+ @keyframes mk-skeleton-reveal {
94
+ from { opacity: 0; transform: translateY(4px); }
95
+ }
96
+
97
+ @media (prefers-reduced-motion: reduce) {
98
+ :is(.mk-skeleton, mk-skeleton) [data-mk-bone],
99
+ :is(.mk-skeleton, mk-skeleton) [data-mk-bone]::after,
100
+ :is(.mk-skeleton, mk-skeleton) [data-mk-skeleton-content] {
101
+ animation: none !important;
102
+ }
103
+
104
+ :is(.mk-skeleton, mk-skeleton) [data-mk-bone]::after {
105
+ display: none;
106
+ }
107
+ }
@@ -0,0 +1,68 @@
1
+ # slot-picker
2
+
3
+ El selector de citas de Melon Mind («Agendar cita»): a la izquierda un mes compacto y a la derecha los horarios del día elegido. Sirve para reservas, citas o mesas.
4
+
5
+ - **Cambiar de día:** los horarios salen 30 px hacia un lado y entran 30 px desde el otro (0.25 s `ease-out`), en la dirección del cambio. El original usa una View Transition `time-slot`.
6
+ - **Primera lista:** entra creciendo (escala .7, blur 32 → 0, 0.3 s `cubic-bezier(.38,.49,0,1.1)`), 20 ms entre horarios.
7
+ - **Encabezado del día:** se abre de 0 a 56 px en 0.5 s `cubic-bezier(.38,.49,0,1.4)`.
8
+ - **Horario elegido:** se ilumina en 0.7 s (escala .8 → 1, blur 16 → 0).
9
+ - **Cambiar de mes:** los días se deslizan igual que los horarios.
10
+
11
+ Origen: REA de la app de Melon Mind (`appt-creator.css`, `schedulePicker.css`, `CreateApptManager.js`).
12
+
13
+ ## HTML / Astro
14
+
15
+ ```html
16
+ <mk-slot-picker class="mk-slot-picker" locale="es" min="2026-10-23" closed-days="[0]"
17
+ slots='["09:00","10:00","11:30","16:00","17:30"]'>
18
+ <div class="mk-slot-picker__calendar">
19
+ <div class="mk-slot-picker__month">
20
+ <h3 class="mk-slot-picker__title" data-mk-slot-title></h3>
21
+ <button type="button" class="mk-slot-picker__nav" data-mk-slot-prev aria-label="Mes anterior">←</button>
22
+ <button type="button" class="mk-slot-picker__nav" data-mk-slot-next aria-label="Mes siguiente">→</button>
23
+ </div>
24
+ <div data-mk-slot-days></div>
25
+ </div>
26
+ <div class="mk-slot-picker__panel">
27
+ <p class="mk-slot-picker__heading" data-mk-slot-heading></p>
28
+ <div data-mk-slot-times></div>
29
+ <input type="hidden" name="cita" data-mk-slot-value>
30
+ </div>
31
+ </mk-slot-picker>
32
+ ```
33
+
34
+ El input oculto `[data-mk-slot-value]` lleva `YYYY-MM-DDTHH:mm` y emite `input`/`change`, así que funciona dentro de un `<form>`. Si cambias el atributo `slots`, la lista se actualiza sin perder el día. Sin custom element: `createSlotPicker(root, opciones)`.
35
+
36
+ ## React
37
+
38
+ ```tsx
39
+ <SlotPicker
40
+ name="cita"
41
+ min={new Date()}
42
+ closedDays={[0]}
43
+ slots={(day) => fetch(`/api/horarios?dia=${dayKey(day)}`).then((r) => r.json())}
44
+ onChange={({ value }) => setCita(value)}
45
+ actions={<button className="mk-button">Agendar</button>}
46
+ />
47
+ ```
48
+
49
+ ## Opciones
50
+
51
+ | Opción | Atributo | Por defecto | Qué hace |
52
+ |---|---|---|---|
53
+ | `slots` | `slots` (JSON) | `[]` | Lista igual todos los días, mapa `{"2026-10-23": [...]}` o función `(día) => lista \| Promise<lista>`. Horas `HH:mm` |
54
+ | `date` | `date` | hoy | Mes inicial (y día elegido si no hay `value`) |
55
+ | `value` | `value` | — | `"2026-10-23T10:30"` o `{ date, time }` |
56
+ | `min`, `max` | `min`, `max` | — | Días fuera de rango deshabilitados; flechas de mes limitadas |
57
+ | `closedDays` | `closed-days` (JSON) | `[]` | Días de la semana cerrados (0 = domingo) |
58
+ | `isDisabled(date)` | — | — | Regla propia |
59
+ | `firstDay` | `first-day` | `0` | Primer día de la semana |
60
+ | `locale` | `locale` | `'es'` | Nombres de mes y día |
61
+ | `labels` | — | español | `placeholder`, `empty`, `loading`, `heading(date)` |
62
+ | `onChange({date, time, key, value})`, `onDateChange(date)` | — | — | Callbacks |
63
+
64
+ API: `selectDate(d)`, `selectTime(t | null)`, `setSlots(fuente)`, `date`, `time`, `value`, `destroy()`. `mk:change` lleva `{date, time, key, value}`. Si los horarios llegan por promesa, mientras cargan se muestra `loading` con `aria-busy`, y una respuesta vieja nunca pisa a la más reciente.
65
+
66
+ ## Accesibilidad
67
+
68
+ Los días forman una rejilla ARIA con foco móvil: flechas, Inicio/Fin y RePág/AvPág para cambiar de mes. Los horarios son un `radiogroup`: las flechas mueven la selección, y el grupo está etiquetado por el encabezado del día. Los días deshabilitados son botones `disabled`. Con movimiento reducido no hay deslizamiento, entradas ni resaltado animado.
@@ -0,0 +1,27 @@
1
+ import { MkElement, defineElement, type OptionType } from '../../elements/base';
2
+ import { createSlotPicker, type SlotPickerInstance, type SlotSource } from './engine';
3
+
4
+ /** Light DOM: supply the [data-mk-slot-days] and [data-mk-slot-times] markup shown in the README. */
5
+ export class MkSlotPickerElement extends MkElement<SlotPickerInstance> {
6
+ static options: Record<string, OptionType> = {
7
+ date: 'string', value: 'string', slots: 'json', min: 'string', max: 'string', closedDays: 'json', firstDay: 'number', locale: 'string',
8
+ };
9
+
10
+ protected create(options: Record<string, unknown>) {
11
+ return createSlotPicker(this, options);
12
+ }
13
+
14
+ attributeChangedCallback(name: string, previous: string | null, next: string | null) {
15
+ if (previous === next || !this.isConnected || !this.instance) return;
16
+ if (name === 'slots') {
17
+ this.instance.setSlots((this.options.slots as SlotSource | undefined) ?? []);
18
+ return;
19
+ }
20
+ // Keep the visitor's pick unless the value itself changed.
21
+ const value = this.instance.value ?? (this.instance.date ? this.instance.date : undefined);
22
+ this.instance.destroy();
23
+ this.instance = this.create({ ...(name !== 'value' && value ? (typeof value === 'string' ? { value } : { date: value }) : {}), ...this.options });
24
+ }
25
+ }
26
+
27
+ export const defineSlotPicker = () => defineElement('mk-slot-picker', MkSlotPickerElement);