@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,35 @@
1
+ 'use client';
2
+ import { useRef, type HTMLAttributes } from 'react';
3
+ import { useIsomorphicLayoutEffect, useLatest } from '../../react/use-recipe';
4
+ import { createProgress, type ProgressInstance, type ProgressOptions } from './engine';
5
+
6
+ export interface ProgressProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'>, ProgressOptions {}
7
+
8
+ /** <Progress value={42} label="Subida" showValue />; value={null} is indeterminate. The engine owns the drawing and ARIA. */
9
+ export function Progress({ value, min, max, label, variant, showValue, formatValue, className, ...props }: ProgressProps) {
10
+ const ref = useRef<HTMLDivElement>(null);
11
+ const instance = useRef<ProgressInstance | null>(null);
12
+ const current = useLatest(value);
13
+ const format = useLatest(formatValue);
14
+ const formatted = formatValue !== undefined;
15
+ useIsomorphicLayoutEffect(() => {
16
+ const created = createProgress(ref.current, {
17
+ value: current.current,
18
+ min,
19
+ max,
20
+ label,
21
+ variant,
22
+ showValue,
23
+ formatValue: formatted ? (n, ratio) => format.current?.(n, ratio) ?? '' : undefined,
24
+ });
25
+ instance.current = created;
26
+ return () => {
27
+ created.destroy();
28
+ instance.current = null;
29
+ };
30
+ }, [min, max, label, variant, showValue, formatted]);
31
+ useIsomorphicLayoutEffect(() => {
32
+ instance.current?.setValue(value === undefined ? (min ?? 0) : value);
33
+ }, [value]);
34
+ return <div {...props} ref={ref} className={['mk-progress', className].filter(Boolean).join(' ')} />;
35
+ }
@@ -0,0 +1,32 @@
1
+ # questionnaire
2
+
3
+ Preguntas por pasos sobre un formulario nativo: texto, respuesta única y múltiple, anterior/siguiente, progreso, validación de obligatorios y finalización. Compone el motor de [steps](../steps/README.md) (entrada/salida en flujo, contador y foco en el título); la persistencia es de la app.
4
+
5
+ ```html
6
+ <mk-questionnaire>
7
+ <form class="mk-questionnaire">
8
+ <section data-mk-question>
9
+ <h3>¿Cómo te llamas?</h3>
10
+ <input name="name" required aria-label="Nombre" />
11
+ <button type="button" data-mk-question-next>Siguiente</button>
12
+ </section>
13
+ <section data-mk-question>
14
+ <h3>¿Qué te interesa?</h3>
15
+ <label><input type="checkbox" name="topics" value="diseño" required /> Diseño</label>
16
+ <label><input type="checkbox" name="topics" value="código" required /> Código</label>
17
+ <button type="button" data-mk-question-prev>Anterior</button>
18
+ <button type="submit">Finalizar</button>
19
+ </section>
20
+ <p data-mk-question-error role="alert"></p>
21
+ <div data-mk-question-complete hidden>¡Gracias! <button type="reset">Empezar de nuevo</button></div>
22
+ </form>
23
+ </mk-questionnaire>
24
+ ```
25
+
26
+ Vacío, `<mk-questionnaire questions='[{"id":"name","label":"Nombre","type":"text","required":true}]'>` crea el mismo marcado. React: `<Questionnaire questions={questions} onComplete={save} complete={(answers) => <Summary answers={answers} />} />` con `Question {id, label, type: 'text'|'textarea'|'single'|'multiple', options?, required?, description?, placeholder?}` y `defaultAnswers`.
27
+
28
+ Opciones: `index`, `labels {required, choice}`, `onChange(index, answers)`, `onComplete(answers)`. API: `next(): Promise<boolean>`, `prev()`, `reset()`, `answers`, `index`, `count`, `complete`, `destroy()`. `readAnswers(form)` devuelve `QuestionnaireAnswers` (`string` o `string[]` por nombre de campo: casillas y selects múltiples dan arrays).
29
+
30
+ Siguiente valida el paso actual: los campos obligatorios vacíos o inválidos y los grupos de casillas/radios obligatorios (basta uno marcado por grupo). Marca `aria-invalid`, escribe el mensaje en `[data-mk-question-error]`, enfoca el primer campo inválido y emite `mk:invalid`. Un campo corregido deja de estar inválido al momento. Los botones `[data-mk-question-next|prev]` son propios: nunca saltan la validación. Enviar en el último paso completa una sola vez (`mk:complete` con `{answers}`), muestra `[data-mk-question-complete]` y evita la navegación. El reset nativo limpia respuestas, errores y finalización y vuelve al primer paso. Cada cambio de paso emite `mk:question` `{index, previous, answers}`.
31
+
32
+ Las respuestas viven en los controles nativos, así que se conservan al volver atrás y entre renders de React. `destroy()` restaura atributos, textos y visibilidad. Variables: `--mk-question-radius` (24px), `--mk-question-option-radius` (16px); `--mk-question-progress` lo escribe el motor. Movimiento reducido: los pasos cambian sin flujo y la barra sin transición.
@@ -0,0 +1,118 @@
1
+ import { MkElement, defineElement, type OptionType } from '../../elements/base';
2
+ import type { Instance } from '../../core/types';
3
+ import { createQuestionnaire, type QuestionnaireInstance } from './engine';
4
+
5
+ interface QuestionData {
6
+ id: string;
7
+ label: string;
8
+ type: 'text' | 'textarea' | 'single' | 'multiple';
9
+ options?: Array<string | { value: string; label: string }>;
10
+ required?: boolean;
11
+ description?: string;
12
+ }
13
+
14
+ const el = <K extends keyof HTMLElementTagNameMap>(tag: K, attrs: Record<string, string> = {}, text?: string) => {
15
+ const element = document.createElement(tag);
16
+ for (const [name, value] of Object.entries(attrs)) element.setAttribute(name, value);
17
+ if (text !== undefined) element.textContent = text;
18
+ return element;
19
+ };
20
+
21
+ /** The same form the React <Questionnaire> renders, built with DOM APIs (all text as text). */
22
+ function buildForm(questions: QuestionData[]) {
23
+ const form = el('form', { class: 'mk-questionnaire', novalidate: '' });
24
+ const progress = el('div', { 'data-mk-question-progress': '', 'aria-hidden': 'true' });
25
+ progress.append(el('span', { 'data-mk-question-bar': '' }));
26
+ form.append(progress);
27
+ questions.forEach((question, i) => {
28
+ const titleId = `${question.id}-title`;
29
+ const section = el('section', { 'data-mk-question': '', 'aria-labelledby': titleId });
30
+ if (i) section.hidden = true;
31
+ section.append(el('p', { 'data-mk-question-step': '' }, `Pregunta ${i + 1} de ${questions.length}`));
32
+ const title = el('h3', { id: titleId, 'data-mk-step-title': '', 'data-mk-flow-item': '' }, question.label);
33
+ if (question.required) title.append(el('span', { 'data-mk-question-required': '', 'aria-hidden': 'true' }, ' *'));
34
+ section.append(title);
35
+ if (question.description) section.append(el('p', { 'data-mk-question-description': '', 'data-mk-flow-item': '' }, question.description));
36
+ const field = el('div', { 'data-mk-question-field': '', 'data-mk-flow-item': '' });
37
+ if (question.type === 'text' || question.type === 'textarea') {
38
+ const input = question.type === 'text' ? el('input', { type: 'text' }) : el('textarea', { rows: '4' });
39
+ input.name = question.id;
40
+ input.required = Boolean(question.required);
41
+ input.setAttribute('aria-labelledby', titleId);
42
+ field.append(input);
43
+ } else {
44
+ const group = el('div', { role: question.type === 'single' ? 'radiogroup' : 'group', 'aria-labelledby': titleId, 'data-mk-question-options': '' });
45
+ for (const raw of question.options ?? []) {
46
+ const option = typeof raw === 'string' ? { value: raw, label: raw } : raw;
47
+ const label = el('label', { 'data-mk-question-option': '' });
48
+ const input = el('input', { type: question.type === 'single' ? 'radio' : 'checkbox' });
49
+ input.name = question.id;
50
+ input.value = option.value;
51
+ input.required = Boolean(question.required);
52
+ label.append(input, el('span', {}, option.label));
53
+ group.append(label);
54
+ }
55
+ field.append(group);
56
+ }
57
+ section.append(field);
58
+ const actions = el('div', { 'data-mk-question-actions': '', 'data-mk-flow-item': '' });
59
+ if (i) actions.append(el('button', { type: 'button', class: 'mk-button mk-button--text', 'data-mk-question-prev': '' }, 'Anterior'));
60
+ actions.append(
61
+ i < questions.length - 1
62
+ ? el('button', { type: 'button', class: 'mk-button', 'data-mk-question-next': '' }, 'Siguiente')
63
+ : el('button', { type: 'submit', class: 'mk-button' }, 'Finalizar'),
64
+ );
65
+ section.append(actions);
66
+ form.append(section);
67
+ });
68
+ form.append(el('p', { 'data-mk-question-error': '', role: 'alert' }));
69
+ const done = el('div', { 'data-mk-question-complete': '' });
70
+ done.hidden = true;
71
+ done.append(el('p', {}, '¡Gracias! Respuestas enviadas.'), el('button', { type: 'reset', class: 'mk-button mk-button--tonal' }, 'Empezar de nuevo'));
72
+ form.append(done);
73
+ return form;
74
+ }
75
+
76
+ /**
77
+ * <mk-questionnaire><form>…<section data-mk-question>…</section>…</form></mk-questionnaire>
78
+ * or, empty, <mk-questionnaire questions='[{"id":"name","label":"Nombre","type":"text","required":true}]'>.
79
+ * Emits mk:question ({index, previous, answers}), mk:invalid and mk:complete ({answers}).
80
+ */
81
+ export class MkQuestionnaireElement extends MkElement<Instance> {
82
+ static options: Record<string, OptionType> = { questions: 'json', index: 'number' };
83
+
84
+ questionnaire: QuestionnaireInstance | null = null;
85
+
86
+ protected create(options: Record<string, unknown>): Instance {
87
+ const questions = Array.isArray(options.questions) ? (options.questions as QuestionData[]) : null;
88
+ const built = questions && !this.querySelector('[data-mk-question]') ? buildForm(questions) : null;
89
+ if (built) this.append(built);
90
+ const engine = createQuestionnaire(this, { index: options.index as number | undefined });
91
+ this.questionnaire = engine;
92
+ return {
93
+ destroy: () => {
94
+ engine.destroy();
95
+ built?.remove();
96
+ this.questionnaire = null;
97
+ },
98
+ };
99
+ }
100
+
101
+ next() {
102
+ return this.questionnaire?.next() ?? Promise.resolve(false);
103
+ }
104
+
105
+ prev() {
106
+ return this.questionnaire?.prev() ?? Promise.resolve();
107
+ }
108
+
109
+ reset() {
110
+ this.questionnaire?.reset();
111
+ }
112
+
113
+ get answers() {
114
+ return this.questionnaire?.answers ?? {};
115
+ }
116
+ }
117
+
118
+ export const defineQuestionnaire = () => defineElement('mk-questionnaire', MkQuestionnaireElement);
@@ -0,0 +1,255 @@
1
+ import { createScope } from '../../core/scope';
2
+ import { inert, type Instance } from '../../core/types';
3
+ import { createSteps } from '../steps/engine';
4
+ import { shake } from '../../motion/micro';
5
+
6
+ /*
7
+ * Questionnaire: a native form split into [data-mk-question] steps, moved by
8
+ * the steps engine (flow out/in, counter, focus on the title). Next validates
9
+ * the current step first — required text, choices and checkbox groups (one
10
+ * checked is enough) — marks invalid fields, writes the message and focuses
11
+ * the first one. Submitting on the last step completes once; native reset
12
+ * clears errors and completion and returns to the first step.
13
+ * Parts: [data-mk-question], [data-mk-question-next|prev], [data-mk-question-error],
14
+ * [data-mk-question-complete], [data-mk-counter] (step number).
15
+ */
16
+
17
+ export type QuestionnaireAnswers = Record<string, string | string[]>;
18
+
19
+ export interface QuestionnaireLabels {
20
+ required?: string;
21
+ choice?: string;
22
+ }
23
+
24
+ export interface QuestionnaireOptions {
25
+ index?: number;
26
+ labels?: QuestionnaireLabels;
27
+ onChange?: (index: number, answers: QuestionnaireAnswers) => void;
28
+ onComplete?: (answers: QuestionnaireAnswers) => void;
29
+ }
30
+
31
+ export interface QuestionnaireInstance extends Instance {
32
+ /** Validate the current step and go on (or complete on the last one). */
33
+ next(): Promise<boolean>;
34
+ prev(): Promise<void>;
35
+ /** Native form reset: clears answers, errors and completion. */
36
+ reset(): void;
37
+ readonly answers: QuestionnaireAnswers;
38
+ readonly index: number;
39
+ readonly count: number;
40
+ readonly complete: boolean;
41
+ }
42
+
43
+ type Field = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
44
+ const FIELDS = 'input[name], select[name], textarea[name]';
45
+ const SKIP = new Set(['button', 'submit', 'reset', 'image', 'file']);
46
+ let sequence = 0;
47
+
48
+ /** Answers of a form keyed by field name: checkboxes and multi-selects give arrays. */
49
+ export function readAnswers(form: HTMLElement): QuestionnaireAnswers {
50
+ const answers: QuestionnaireAnswers = {};
51
+ for (const field of form.querySelectorAll<Field>(FIELDS)) {
52
+ if (field.disabled || SKIP.has(field.type)) continue;
53
+ const { name } = field;
54
+ if (field instanceof HTMLInputElement && field.type === 'checkbox') {
55
+ const list = (answers[name] as string[] | undefined) ?? [];
56
+ if (field.checked) list.push(field.value);
57
+ answers[name] = list;
58
+ } else if (field instanceof HTMLInputElement && field.type === 'radio') {
59
+ if (field.checked) answers[name] = field.value;
60
+ else answers[name] ??= '';
61
+ } else if (field instanceof HTMLSelectElement && field.multiple) {
62
+ answers[name] = [...field.selectedOptions].map((option) => option.value);
63
+ } else answers[name] = field.value;
64
+ }
65
+ return answers;
66
+ }
67
+
68
+ export function createQuestionnaire(root: HTMLElement | null, options: QuestionnaireOptions = {}): QuestionnaireInstance {
69
+ const form = root instanceof HTMLFormElement ? root : root?.querySelector('form') ?? null;
70
+ const sections = form ? [...form.querySelectorAll<HTMLElement>('[data-mk-question]')] : [];
71
+ if (!root || !form || !sections.length) {
72
+ return inert({ next: async () => false, prev: async () => {}, reset() {}, answers: {}, index: -1, count: 0, complete: false });
73
+ }
74
+ const scope = createScope();
75
+ const labels = { required: 'Completa este campo.', choice: 'Elige al menos una opción.', ...options.labels };
76
+ for (const section of sections) if (!section.hasAttribute('data-mk-step')) scope.attr(section, 'data-mk-step', '');
77
+ const start = Math.min(sections.length - 1, Math.max(0, Math.round(options.index ?? 0)));
78
+ let index = start;
79
+ let complete = false;
80
+ // Our own navigation buttons only (not [data-mk-step-*]): steps never skips validation.
81
+ const steps = createSteps(form, { index: start, animateFirst: false });
82
+ scope.add(() => steps.destroy());
83
+ scope.attr(form, 'novalidate', '');
84
+ scope.attr(form, 'data-mk-questionnaire', '');
85
+
86
+ const fieldsOf = (section: HTMLElement) => [...section.querySelectorAll<Field>(FIELDS)].filter((field) => !field.disabled && !SKIP.has(field.type));
87
+ const errorOf = (section: HTMLElement) => section.querySelector<HTMLElement>('[data-mk-question-error]') ?? form.querySelector<HTMLElement>('[data-mk-question-error]');
88
+ const errorTexts = new Map<HTMLElement, string | null>();
89
+ const writeError = (element: HTMLElement | null, text: string) => {
90
+ if (!element) return;
91
+ if (!errorTexts.has(element)) errorTexts.set(element, element.textContent);
92
+ element.textContent = text;
93
+ };
94
+ scope.add(() => errorTexts.forEach((text, element) => (element.textContent = text)));
95
+ for (const element of form.querySelectorAll<HTMLElement>('[data-mk-question-error]')) {
96
+ if (!element.id) scope.attr(element, 'id', `mk-question-error-${++sequence}`);
97
+ if (!element.matches('output') && !element.hasAttribute('role')) scope.attr(element, 'role', 'alert');
98
+ }
99
+
100
+ const markValid = (field: Field) => {
101
+ scope.attr(field, 'aria-invalid', null);
102
+ scope.attr(field, 'aria-errormessage', null);
103
+ };
104
+ const clearErrors = () => {
105
+ for (const field of form.querySelectorAll<Field>(FIELDS)) markValid(field);
106
+ for (const element of form.querySelectorAll<HTMLElement>('[data-mk-question-error]')) writeError(element, '');
107
+ };
108
+
109
+ /** Invalid fields of a step and the first message. */
110
+ const check = (section: HTMLElement) => {
111
+ const invalid: Field[] = [];
112
+ let message = '';
113
+ const groups = new Map<string, HTMLInputElement[]>();
114
+ for (const field of fieldsOf(section)) {
115
+ if (field instanceof HTMLInputElement && (field.type === 'checkbox' || field.type === 'radio')) {
116
+ const group = groups.get(field.name) ?? [];
117
+ group.push(field);
118
+ groups.set(field.name, group);
119
+ continue;
120
+ }
121
+ const empty = field.required && !field.value.trim();
122
+ if (empty || !field.checkValidity()) {
123
+ invalid.push(field);
124
+ message ||= empty ? labels.required : field.validationMessage || labels.required;
125
+ }
126
+ }
127
+ for (const group of groups.values()) {
128
+ const required = group.some((field) => field.required) || Boolean(group[0]!.closest('[data-mk-required]'));
129
+ if (required && !group.some((field) => field.checked)) {
130
+ invalid.push(...group);
131
+ message ||= labels.choice;
132
+ }
133
+ }
134
+ return { invalid, message };
135
+ };
136
+
137
+ const validate = (section: HTMLElement) => {
138
+ clearErrors();
139
+ const { invalid, message } = check(section);
140
+ if (!invalid.length) return true;
141
+ const error = errorOf(section);
142
+ writeError(error, message);
143
+ for (const field of invalid) {
144
+ scope.attr(field, 'aria-invalid', 'true');
145
+ if (error?.id) scope.attr(field, 'aria-errormessage', error.id);
146
+ }
147
+ invalid[0]!.focus();
148
+ shake(invalid[0]!.closest('[data-mk-question-options], [data-mk-question-field]') ?? invalid[0]!);
149
+ root.dispatchEvent(new CustomEvent('mk:invalid', { bubbles: true, detail: { index, fields: invalid } }));
150
+ return false;
151
+ };
152
+
153
+ const render = () => {
154
+ scope.attr(form, 'data-mk-complete', complete ? '' : null);
155
+ form.style.setProperty('--mk-question-progress', String(complete ? 1 : (index + 1) / sections.length));
156
+ for (const panel of form.querySelectorAll<HTMLElement>('[data-mk-question-complete]')) scope.attr(panel, 'hidden', complete ? null : '');
157
+ };
158
+ scope.attr(form, 'style', form.getAttribute('style'));
159
+
160
+ const finish = () => {
161
+ if (complete) return;
162
+ complete = true;
163
+ render();
164
+ const answers = readAnswers(form);
165
+ const panel = form.querySelector<HTMLElement>('[data-mk-question-complete]');
166
+ if (panel) {
167
+ if (!panel.hasAttribute('tabindex')) scope.attr(panel, 'tabindex', '-1');
168
+ panel.focus({ preventScroll: true });
169
+ }
170
+ options.onComplete?.(answers);
171
+ root.dispatchEvent(new CustomEvent('mk:complete', { bubbles: true, detail: { answers } }));
172
+ };
173
+
174
+ const go = async (to: number) => {
175
+ const previous = index;
176
+ index = to;
177
+ render();
178
+ await steps.goTo(to);
179
+ if (scope.disposed) return;
180
+ const answers = readAnswers(form);
181
+ options.onChange?.(index, answers);
182
+ root.dispatchEvent(new CustomEvent('mk:question', { bubbles: true, detail: { index, previous, answers } }));
183
+ };
184
+
185
+ // Everything before the first await runs at once: a submit completes synchronously.
186
+ const next = async () => {
187
+ if (scope.disposed) return false;
188
+ if (complete) return true;
189
+ if (!validate(sections[index]!)) return false;
190
+ if (index === sections.length - 1) {
191
+ finish();
192
+ return true;
193
+ }
194
+ await go(index + 1);
195
+ return !scope.disposed;
196
+ };
197
+ const prev = async () => {
198
+ if (scope.disposed || complete || index === 0) return;
199
+ clearErrors();
200
+ await go(index - 1);
201
+ };
202
+
203
+ scope.on(form, 'click', (event) => {
204
+ const trigger = (event.target as Element | null)?.closest<HTMLElement>('[data-mk-question-next], [data-mk-question-prev]');
205
+ if (!trigger || !form.contains(trigger)) return;
206
+ event.preventDefault();
207
+ if (trigger.hasAttribute('data-mk-question-next')) void next();
208
+ else void prev();
209
+ });
210
+ scope.on(form, 'submit', (event) => {
211
+ event.preventDefault();
212
+ void next();
213
+ });
214
+ // A corrected field stops being invalid as soon as it is.
215
+ const recheck = (event: Event) => {
216
+ const field = (event.target as Element | null)?.closest<Field>(FIELDS);
217
+ if (!field || field.getAttribute('aria-invalid') !== 'true') return;
218
+ const section = field.closest<HTMLElement>('[data-mk-question]');
219
+ if (!section) return;
220
+ const { invalid } = check(section);
221
+ for (const candidate of fieldsOf(section)) if (!invalid.includes(candidate)) markValid(candidate);
222
+ if (!invalid.length) writeError(errorOf(section), '');
223
+ };
224
+ scope.on(form, 'input', recheck);
225
+ scope.on(form, 'change', recheck);
226
+ scope.on(form, 'reset', (event) => {
227
+ if (event.defaultPrevented) return;
228
+ clearErrors();
229
+ complete = false;
230
+ if (index !== 0) void go(0);
231
+ else render();
232
+ });
233
+ render();
234
+
235
+ return {
236
+ next,
237
+ prev,
238
+ reset() {
239
+ if (!scope.disposed) form.reset();
240
+ },
241
+ get answers() {
242
+ return readAnswers(form);
243
+ },
244
+ get index() {
245
+ return index;
246
+ },
247
+ get count() {
248
+ return sections.length;
249
+ },
250
+ get complete() {
251
+ return complete;
252
+ },
253
+ destroy: () => scope.dispose(),
254
+ };
255
+ }
@@ -0,0 +1,216 @@
1
+ /* questionnaire — one question at a time on a soft card: a thin progress line, large title, pill choices. */
2
+ .mk-questionnaire,
3
+ mk-questionnaire > form {
4
+ --mk-question-radius: var(--mk-radius-lg, 24px);
5
+ --mk-question-option-radius: var(--mk-radius-md, 16px);
6
+ display: grid;
7
+ gap: 1.25rem;
8
+ padding: clamp(1.25rem, 4vw, 2rem);
9
+ border-radius: var(--mk-question-radius);
10
+ background: var(--mk-surface-1);
11
+ box-shadow: inset 0 0 0 1px var(--mk-outline-soft);
12
+ color: var(--mk-text);
13
+ font-family: var(--mk-font);
14
+ }
15
+
16
+ mk-questionnaire {
17
+ display: block;
18
+ }
19
+
20
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-progress] {
21
+ height: 4px;
22
+ overflow: hidden;
23
+ border-radius: var(--mk-radius-full);
24
+ background: color-mix(in srgb, var(--mk-text) 9%, transparent);
25
+ }
26
+
27
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-bar] {
28
+ display: block;
29
+ height: 100%;
30
+ border-radius: inherit;
31
+ background: var(--mk-accent);
32
+ transform: scaleX(var(--mk-question-progress, 0));
33
+ transform-origin: left center;
34
+ transition: transform 0.7s cubic-bezier(0.38, 0.49, 0, 1);
35
+ }
36
+
37
+ /* A full-width column (steps' own flex centring does not apply here). */
38
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question] {
39
+ display: grid;
40
+ grid-template-columns: minmax(0, 1fr);
41
+ gap: 1rem;
42
+ align-content: start;
43
+ justify-content: normal;
44
+ justify-items: stretch;
45
+ }
46
+
47
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question][hidden],
48
+ :is(.mk-questionnaire, mk-questionnaire)[data-mk-complete] [data-mk-question],
49
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-complete][hidden] {
50
+ display: none !important;
51
+ }
52
+
53
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-step] {
54
+ margin: 0;
55
+ color: var(--mk-muted);
56
+ font-size: 0.8125rem;
57
+ letter-spacing: 0.02em;
58
+ }
59
+
60
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question] h3 {
61
+ margin: 0;
62
+ font-size: clamp(1.35rem, 3vw, 1.75rem);
63
+ font-weight: 500;
64
+ line-height: 1.15;
65
+ letter-spacing: -0.02em;
66
+ }
67
+
68
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question] h3:focus {
69
+ outline: none;
70
+ }
71
+
72
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-required] {
73
+ color: var(--mk-accent);
74
+ }
75
+
76
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-description] {
77
+ margin: -0.5rem 0 0;
78
+ color: var(--mk-muted);
79
+ }
80
+
81
+ :is(.mk-questionnaire, mk-questionnaire) :is(input[type='text'], input[type='email'], input[type='number'], textarea, select) {
82
+ width: 100%;
83
+ min-height: 3.25rem;
84
+ padding: 0.75rem 1.1rem;
85
+ border: 1px solid var(--mk-outline-soft);
86
+ border-radius: var(--mk-question-option-radius);
87
+ background: var(--mk-surface-3);
88
+ color: var(--mk-text);
89
+ font: inherit;
90
+ transition:
91
+ border-color 0.2s ease,
92
+ background-color 0.2s ease;
93
+ }
94
+
95
+ :is(.mk-questionnaire, mk-questionnaire) textarea {
96
+ resize: vertical;
97
+ }
98
+
99
+ :is(.mk-questionnaire, mk-questionnaire) :is(input, textarea, select):focus-visible {
100
+ border-color: var(--mk-accent);
101
+ outline: 2px solid color-mix(in srgb, var(--mk-accent) 35%, transparent);
102
+ outline-offset: 1px;
103
+ }
104
+
105
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-options] {
106
+ display: grid;
107
+ gap: 0.5rem;
108
+ }
109
+
110
+ /* Melonmind label.style-1: padding and radius spring; a chosen option becomes a pill. */
111
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-option] {
112
+ display: flex;
113
+ align-items: center;
114
+ gap: 0.75rem;
115
+ min-height: 3.25rem;
116
+ padding: 0.5rem 1.1rem;
117
+ border-radius: 16px;
118
+ background: var(--mk-surface-3);
119
+ cursor: pointer;
120
+ user-select: none;
121
+ transition:
122
+ padding 300ms cubic-bezier(0.38, 0.49, 0, 2),
123
+ background-color 300ms cubic-bezier(0.38, 0.49, 0, 1.5),
124
+ color 300ms cubic-bezier(0.38, 0.49, 0, 1.5),
125
+ border-radius 200ms cubic-bezier(0.38, 0.49, 0, 1.5);
126
+ }
127
+
128
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-option]:hover {
129
+ padding-inline: 1.3rem;
130
+ background: var(--mk-surface-4);
131
+ }
132
+
133
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-option]:active {
134
+ animation: mk-question-press 500ms cubic-bezier(0.37, 1.42, 0.37, 1);
135
+ }
136
+
137
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-option]:has(input:checked) {
138
+ padding-inline: 1.5rem;
139
+ border-radius: 64px;
140
+ background: var(--mk-accent-soft);
141
+ color: var(--mk-on-accent-soft);
142
+ }
143
+
144
+ @keyframes mk-question-press {
145
+ 50% {
146
+ transform: scale(0.98, 0.94);
147
+ }
148
+ }
149
+
150
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-option]:has(input:focus-visible) {
151
+ outline: 2px solid var(--mk-accent);
152
+ outline-offset: 2px;
153
+ }
154
+
155
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-option] input {
156
+ width: 1.15rem;
157
+ height: 1.15rem;
158
+ margin: 0;
159
+ accent-color: var(--mk-accent);
160
+ }
161
+
162
+ :is(.mk-questionnaire, mk-questionnaire) [aria-invalid='true']:not([type='checkbox'], [type='radio']) {
163
+ border-color: var(--mk-error);
164
+ }
165
+
166
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-option]:has([aria-invalid='true']) {
167
+ border-color: color-mix(in srgb, var(--mk-error) 60%, transparent);
168
+ }
169
+
170
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-actions] {
171
+ display: flex;
172
+ flex-wrap: wrap;
173
+ justify-content: flex-end;
174
+ gap: 0.5rem;
175
+ margin-top: 0.25rem;
176
+ }
177
+
178
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-error] {
179
+ margin: 0;
180
+ color: var(--mk-error);
181
+ font-size: 0.875rem;
182
+ }
183
+
184
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-error]:empty {
185
+ display: none;
186
+ }
187
+
188
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-complete] {
189
+ display: grid;
190
+ gap: 1rem;
191
+ justify-items: start;
192
+ animation: mk-question-done 0.45s var(--mk-ease-sheet, ease-out) both;
193
+ }
194
+
195
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-complete]:focus {
196
+ outline: none;
197
+ }
198
+
199
+ @keyframes mk-question-done {
200
+ from {
201
+ opacity: 0;
202
+ transform: translateY(8px);
203
+ }
204
+ }
205
+
206
+ @media (prefers-reduced-motion: reduce) {
207
+ :is(.mk-questionnaire, mk-questionnaire) :is([data-mk-question-bar], [data-mk-question-option], [data-mk-question-complete]) {
208
+ transition: none;
209
+ animation: none;
210
+ transform: none;
211
+ }
212
+
213
+ :is(.mk-questionnaire, mk-questionnaire) [data-mk-question-bar] {
214
+ transform: scaleX(var(--mk-question-progress, 0));
215
+ }
216
+ }