@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,36 @@
1
+ import { MkElement, defineElement, type OptionType } from '../../elements/base';
2
+ import { createResizablePanel, type ResizablePanelInstance } from './engine';
3
+
4
+ /**
5
+ * <mk-resizable-panel class="mk-resizable-panel" sizes="25,75" collapsible="0" storage-key="layout">
6
+ * <aside data-min="15">…</aside><main>…</main>
7
+ * </mk-resizable-panel>. Emits mk:resize ({sizes}) and mk:collapse ({index, collapsed}).
8
+ */
9
+ export class MkResizablePanelElement extends MkElement<ResizablePanelInstance> {
10
+ static options: Record<string, OptionType> = {
11
+ orientation: 'string',
12
+ sizes: 'list',
13
+ min: 'number',
14
+ max: 'number',
15
+ collapsible: 'list',
16
+ collapsed: 'list',
17
+ step: 'number',
18
+ storageKey: 'string',
19
+ handleButtons: 'boolean',
20
+ labels: 'list',
21
+ };
22
+
23
+ protected create(options: Record<string, unknown>) {
24
+ const numbers = (value: unknown) => (Array.isArray(value) ? value.map(Number).filter(Number.isFinite) : undefined);
25
+ return createResizablePanel(this, { ...options, sizes: numbers(options.sizes), collapsible: numbers(options.collapsible), collapsed: numbers(options.collapsed) });
26
+ }
27
+
28
+ attributeChangedCallback(name: string, previous: string | null, next: string | null) {
29
+ if (previous === next || !this.instance) return;
30
+ if (name === 'orientation') this.instance.setOrientation(next === 'vertical' ? 'vertical' : 'horizontal');
31
+ else if (name === 'sizes') this.instance.setSizes((next ?? '').split(',').map(Number).filter(Number.isFinite));
32
+ else super.attributeChangedCallback(name, previous, next);
33
+ }
34
+ }
35
+
36
+ export const defineResizablePanel = () => defineElement('mk-resizable-panel', MkResizablePanelElement);
@@ -0,0 +1,551 @@
1
+ import { gsap, EASE, registerMotion } from '../../core/gsap';
2
+ import { reduced } from '../../core/reduced';
3
+ import { createScope } from '../../core/scope';
4
+ import { inert, type Instance } from '../../core/types';
5
+ import { fromJson } from '../../core/dates';
6
+ import { requestFrame } from '../../core/frame';
7
+
8
+ /*
9
+ * Resizable panels: panels side by side (or stacked) with a separator between
10
+ * each pair that drags (mouse, pen, touch) and moves with the keyboard (the
11
+ * WAI-ARIA window splitter). A separator is a hairline with a grip that grows
12
+ * in the accent on hover and while dragging, and a bubble shows the two sizes
13
+ * ("32 % · 68 %") while it moves. Past a panel's limit the drag gives a quarter
14
+ * of the way (rubber band) and springs back on release (.45 s, swing). A
15
+ * collapsible panel dragged well under its minimum snaps shut (.3 s, swing)
16
+ * and opens again when dragged back out, with Enter on its separator, or with
17
+ * the separator's buttons (handleButtons). A double click on a separator puts
18
+ * the first sizes back (.45 s, signature). Sizes can be remembered.
19
+ */
20
+
21
+ export type PanelOrientation = 'horizontal' | 'vertical';
22
+
23
+ export interface ResizablePanelOptions {
24
+ /** 'horizontal' (default): side by side; 'vertical': stacked. */
25
+ orientation?: PanelOrientation;
26
+ /** Sizes in percent, one per panel (default: data-size on the panels, else equal). */
27
+ sizes?: number[];
28
+ /** Smallest size of a panel in percent (default 10; data-min on a panel wins). */
29
+ min?: number;
30
+ /** Largest size of a panel in percent (default 100; data-max on a panel wins). */
31
+ max?: number;
32
+ /** Panels (indexes) that snap shut when dragged well under their minimum; data-collapsible on a panel too. */
33
+ collapsible?: number[];
34
+ /** Panels that start shut. */
35
+ collapsed?: number[];
36
+ /** Arrow keys move this many percent (default 5; Shift: four times). */
37
+ step?: number;
38
+ /** Remember sizes in localStorage under this key. */
39
+ storageKey?: string;
40
+ /** Buttons on each separator to shut and open the panels beside it. */
41
+ handleButtons?: boolean;
42
+ /** Names of the panels, for the separators' labels (default: data-label, else "panel 1"…). */
43
+ labels?: string[];
44
+ /** While it moves (once a frame). */
45
+ onResize?: (sizes: number[]) => void;
46
+ /** When a drag, a key or an animation ends. */
47
+ onResizeEnd?: (sizes: number[]) => void;
48
+ onCollapse?: (index: number, collapsed: boolean) => void;
49
+ }
50
+
51
+ export interface ResizablePanelInstance extends Instance {
52
+ setSizes(sizes: number[], animate?: boolean): void;
53
+ collapse(index: number): void;
54
+ expand(index: number): void;
55
+ toggle(index: number): void;
56
+ /** The first sizes again. */
57
+ reset(): void;
58
+ setOrientation(orientation: PanelOrientation): void;
59
+ readonly sizes: number[];
60
+ readonly collapsed: number[];
61
+ readonly orientation: PanelOrientation;
62
+ }
63
+
64
+ const CHEVRON = (path: string) => `<svg aria-hidden="true" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="${path}"/></svg>`;
65
+ const ARROWS = { left: CHEVRON('M15 6l-6 6 6 6'), right: CHEVRON('M9 6l6 6-6 6'), up: CHEVRON('M6 15l6-6 6 6'), down: CHEVRON('M6 9l6 6 6-6') };
66
+ let sequence = 0;
67
+
68
+ const round = (n: number) => Math.round(n * 10) / 10;
69
+
70
+ /** Sizes that add up to 100: missing ones share what is left, then all scale to 100 (all missing: equal). */
71
+ export function normaliseSizes(sizes: Array<number | undefined>, count: number): number[] {
72
+ const given = Array.from({ length: count }, (_, i) => {
73
+ const size = sizes[i];
74
+ return typeof size === 'number' && Number.isFinite(size) && size >= 0 ? size : null;
75
+ });
76
+ const known = given.reduce<number>((sum, size) => sum + (size ?? 0), 0);
77
+ const missing = given.filter((size) => size === null).length;
78
+ const share = missing ? Math.max(0, 100 - known) / missing : 0;
79
+ const list = given.map((size) => size ?? share);
80
+ const total = list.reduce((sum, size) => sum + size, 0);
81
+ if (!total) return Array.from({ length: count }, () => 100 / count);
82
+ return list.map((size) => (size / total) * 100);
83
+ }
84
+
85
+ export function createResizablePanel(root: HTMLElement | null, options: ResizablePanelOptions = {}): ResizablePanelInstance {
86
+ if (!root) {
87
+ return inert({ setSizes() {}, collapse() {}, expand() {}, toggle() {}, reset() {}, setOrientation() {}, sizes: [], collapsed: [], orientation: 'horizontal' as PanelOrientation });
88
+ }
89
+ registerMotion();
90
+ const scope = createScope();
91
+ const uid = `mk-rp-${++sequence}`;
92
+ const panels = [...root.children].filter((child): child is HTMLElement => child instanceof HTMLElement && !child.hasAttribute('data-mk-resize-handle'));
93
+ const count = panels.length;
94
+ let orientation: PanelOrientation = options.orientation === 'vertical' ? 'vertical' : 'horizontal';
95
+ const step = options.step && options.step > 0 ? options.step : 5;
96
+ const number = (value: string | undefined) => (value !== undefined && value !== '' && Number.isFinite(Number(value)) ? Number(value) : undefined);
97
+ const mins = panels.map((panel) => Math.max(0, number(panel.dataset.min) ?? options.min ?? 10));
98
+ const maxs = panels.map((panel) => Math.min(100, number(panel.dataset.max) ?? options.max ?? 100));
99
+ const collapsibleList = fromJson(options.collapsible) ?? [];
100
+ const canCollapse = panels.map((panel, i) => panel.hasAttribute('data-collapsible') || collapsibleList.includes(i));
101
+ const names = panels.map((panel, i) => options.labels?.[i] ?? panel.dataset.label ?? panel.getAttribute('aria-label') ?? `panel ${i + 1}`);
102
+ const initial = normaliseSizes(fromJson(options.sizes) ?? panels.map((panel) => number(panel.dataset.size)), count);
103
+ let sizes = [...initial];
104
+ const collapsed = new Set<number>((fromJson(options.collapsed) ?? []).filter((i) => canCollapse[i]));
105
+ /** What a panel had before it shut, to open back to. */
106
+ const before = new Map<number, number>();
107
+ const effects = new Set<gsap.core.Animation>();
108
+ const keep = (animation: gsap.core.Animation | null) => {
109
+ if (!animation) return;
110
+ effects.add(animation);
111
+ // Finished ones leave as new ones arrive: the animation's own onComplete stays untouched.
112
+ for (const effect of effects) if (effect.totalProgress() === 1) effects.delete(effect);
113
+ };
114
+
115
+ // Remembered sizes win over the given ones.
116
+ const storage = (() => {
117
+ try {
118
+ return options.storageKey ? window.localStorage : null;
119
+ } catch {
120
+ return null;
121
+ }
122
+ })();
123
+ if (storage && options.storageKey) {
124
+ try {
125
+ const saved = JSON.parse(storage.getItem(options.storageKey) ?? 'null') as { sizes?: number[]; collapsed?: number[] } | null;
126
+ if (saved?.sizes?.length === count) {
127
+ sizes = normaliseSizes(saved.sizes, count);
128
+ collapsed.clear();
129
+ for (const i of saved.collapsed ?? []) if (canCollapse[i]) collapsed.add(i);
130
+ }
131
+ } catch {
132
+ // Unreadable: the given sizes stand.
133
+ }
134
+ }
135
+ // A shut panel gives its room to its neighbour; it opens back to what it had.
136
+ for (const i of collapsed) {
137
+ if (sizes[i]! > 0) {
138
+ before.set(i, sizes[i]!);
139
+ const neighbour = i + 1 < count ? i + 1 : i - 1;
140
+ if (neighbour >= 0) sizes[neighbour]! += sizes[i]!;
141
+ sizes[i] = 0;
142
+ }
143
+ }
144
+
145
+ // ── The parts ────────────────────────────────────────────────────────────
146
+ scope.attr(root, 'data-mk-ready', '');
147
+ scope.attr(root, 'data-mk-orientation', orientation);
148
+ panels.forEach((panel, i) => {
149
+ scope.attr(panel, 'data-mk-panel', '');
150
+ if (!panel.id) scope.attr(panel, 'id', `${uid}-panel-${i}`);
151
+ scope.attr(panel, 'style', panel.getAttribute('style'));
152
+ });
153
+ const bubble = document.createElement('span');
154
+ bubble.dataset.mkResizeBubble = '';
155
+ bubble.setAttribute('aria-hidden', 'true');
156
+ bubble.hidden = true;
157
+ const handles = panels.slice(0, -1).map((panel, i) => {
158
+ const handle = document.createElement('div');
159
+ handle.dataset.mkResizeHandle = '';
160
+ handle.dataset.index = String(i);
161
+ handle.setAttribute('role', 'separator');
162
+ handle.tabIndex = 0;
163
+ handle.setAttribute('aria-controls', panel.id);
164
+ handle.setAttribute('aria-label', `Redimensionar ${names[i]} y ${names[i + 1]}`);
165
+ const grip = document.createElement('span');
166
+ grip.dataset.mkResizeGrip = '';
167
+ grip.setAttribute('aria-hidden', 'true');
168
+ handle.append(grip);
169
+ if (options.handleButtons) {
170
+ for (const [side, target] of [['start', i], ['end', i + 1]] as const) {
171
+ if (!canCollapse[target]) continue;
172
+ const button = document.createElement('button');
173
+ button.type = 'button';
174
+ button.tabIndex = -1;
175
+ button.dataset.mkResizeButton = side;
176
+ handle.append(button);
177
+ }
178
+ }
179
+ panel.after(handle);
180
+ return handle;
181
+ });
182
+ root.append(bubble);
183
+ scope.add(() => {
184
+ for (const effect of effects) effect.kill();
185
+ effects.clear();
186
+ for (const handle of handles) handle.remove();
187
+ bubble.remove();
188
+ for (const panel of panels) panel.removeAttribute('data-mk-collapsed');
189
+ });
190
+
191
+ // ── Drawing the sizes ────────────────────────────────────────────────────
192
+ const horizontal = () => orientation === 'horizontal';
193
+ const apply = (next: number[]) => {
194
+ panels.forEach((panel, i) => {
195
+ const size = Math.max(0, next[i]!);
196
+ panel.style.flex = `${round(size * 100) / 100} 1 0px`;
197
+ panel.toggleAttribute('data-mk-collapsed', collapsed.has(i) && size < 0.5);
198
+ });
199
+ handles.forEach((handle, i) => {
200
+ // A separator pushed to an edge by a shut panel keeps its buttons inside.
201
+ const edge = i === count - 2 && collapsed.has(i + 1) && next[i + 1]! < 0.5 ? 'end' : i === 0 && collapsed.has(0) && next[0]! < 0.5 ? 'start' : null;
202
+ if (edge) handle.dataset.edge = edge;
203
+ else delete handle.dataset.edge;
204
+ handle.setAttribute('aria-valuenow', String(Math.round(Math.max(0, next[i]!))));
205
+ handle.setAttribute('aria-valuemin', String(canCollapse[i] ? 0 : Math.round(mins[i]!)));
206
+ handle.setAttribute('aria-valuemax', String(Math.round(Math.min(maxs[i]!, 100 - (canCollapse[i + 1] ? 0 : mins[i + 1]!)))));
207
+ handle.setAttribute('aria-valuetext', `${Math.round(Math.max(0, next[i]!))} %${collapsed.has(i) ? ', cerrado' : ''}`);
208
+ for (const button of handle.querySelectorAll<HTMLButtonElement>('[data-mk-resize-button]')) {
209
+ const start = button.dataset.mkResizeButton === 'start';
210
+ const index = start ? i : i + 1;
211
+ const shut = collapsed.has(index);
212
+ // The arrow points where the panel goes: toward its edge to shut it, away to open it.
213
+ button.innerHTML = horizontal() ? (start === !shut ? ARROWS.left : ARROWS.right) : start === !shut ? ARROWS.up : ARROWS.down;
214
+ const label = `${shut ? 'Abrir' : 'Cerrar'} ${names[index]}`;
215
+ button.setAttribute('aria-label', label);
216
+ button.title = label;
217
+ }
218
+ });
219
+ };
220
+ const paintOrientation = () => {
221
+ root.setAttribute('data-mk-orientation', orientation);
222
+ for (const handle of handles) handle.setAttribute('aria-orientation', horizontal() ? 'vertical' : 'horizontal');
223
+ };
224
+ paintOrientation();
225
+ apply(sizes);
226
+
227
+ const save = () => {
228
+ if (!storage || !options.storageKey) return;
229
+ try {
230
+ storage.setItem(options.storageKey, JSON.stringify({ sizes: sizes.map(round), collapsed: [...collapsed] }));
231
+ } catch {
232
+ // Full or blocked: not remembered.
233
+ }
234
+ };
235
+ let pendingNotify: (() => void) | null = null;
236
+ const notify = () => {
237
+ if (pendingNotify || !options.onResize) return;
238
+ pendingNotify = requestFrame(() => {
239
+ pendingNotify = null;
240
+ options.onResize?.(sizes.map(round));
241
+ });
242
+ };
243
+ scope.add(() => pendingNotify?.());
244
+ const settle = () => {
245
+ save();
246
+ options.onResizeEnd?.(sizes.map(round));
247
+ root.dispatchEvent(new CustomEvent('mk:resize', { bubbles: true, detail: { sizes: sizes.map(round) } }));
248
+ };
249
+
250
+ let tween: gsap.core.Tween | null = null;
251
+ /** Glide to `target` (a spring by default). */
252
+ const animateTo = (target: number[], { duration = 0.45, ease = EASE.signature, done }: { duration?: number; ease?: string; done?: () => void } = {}) => {
253
+ tween?.kill();
254
+ if (reduced()) {
255
+ sizes = target;
256
+ apply(sizes);
257
+ done?.();
258
+ return;
259
+ }
260
+ const from = [...sizes];
261
+ const progress = { t: 0 };
262
+ tween = gsap.to(progress, {
263
+ t: 1,
264
+ duration,
265
+ ease,
266
+ onUpdate: () => {
267
+ sizes = from.map((size, i) => Math.max(0, size + (target[i]! - size) * progress.t));
268
+ apply(sizes);
269
+ notify();
270
+ },
271
+ onComplete: () => {
272
+ sizes = [...target];
273
+ apply(sizes);
274
+ tween = null;
275
+ done?.();
276
+ },
277
+ });
278
+ keep(tween);
279
+ };
280
+
281
+ // ── Limits ───────────────────────────────────────────────────────────────
282
+ const lowest = (i: number) => (collapsed.has(i) ? 0 : mins[i]!);
283
+ /** How far the separator `i` may move (in percent) from `start` sizes: [most negative, most positive]. */
284
+ const room = (i: number, start: number[]) => {
285
+ const a = start[i]!;
286
+ const b = start[i + 1]!;
287
+ const down = Math.max(lowest(i) - a, b - maxs[i + 1]!);
288
+ const up = Math.min(maxs[i]! - a, b - lowest(i + 1));
289
+ return [Math.min(0, down), Math.max(0, up)] as const;
290
+ };
291
+
292
+ const setCollapsed = (index: number, shut: boolean, animate = true) => {
293
+ if (!canCollapse[index] || collapsed.has(index) === shut) return;
294
+ // The neighbour that gives or takes the room: the next panel, or the one before the last.
295
+ const neighbour = index + 1 < count ? index + 1 : index - 1;
296
+ const target = [...sizes];
297
+ if (shut) {
298
+ before.set(index, sizes[index]! > 0.5 ? sizes[index]! : before.get(index) ?? initial[index]!);
299
+ target[neighbour] = sizes[neighbour]! + sizes[index]!;
300
+ target[index] = 0;
301
+ collapsed.add(index);
302
+ } else {
303
+ collapsed.delete(index);
304
+ const wanted = Math.max(mins[index]!, before.get(index) ?? initial[index]!);
305
+ const give = Math.min(wanted, Math.max(0, sizes[neighbour]! - mins[neighbour]!));
306
+ target[index] = give;
307
+ target[neighbour] = sizes[neighbour]! - give;
308
+ }
309
+ const finish = () => {
310
+ settle();
311
+ options.onCollapse?.(index, shut);
312
+ root.dispatchEvent(new CustomEvent('mk:collapse', { bubbles: true, detail: { index, collapsed: shut } }));
313
+ };
314
+ status.textContent = `${names[index]} ${shut ? 'cerrado' : 'abierto'}`;
315
+ if (animate) animateTo(target, { duration: 0.3, ease: EASE.swatch, done: finish });
316
+ else {
317
+ sizes = target;
318
+ apply(sizes);
319
+ finish();
320
+ }
321
+ };
322
+
323
+ const status = document.createElement('span');
324
+ status.className = 'mk-sr-only';
325
+ status.setAttribute('role', 'status');
326
+ root.append(status);
327
+ scope.add(() => status.remove());
328
+
329
+ // ── Dragging ─────────────────────────────────────────────────────────────
330
+ interface Drag {
331
+ index: number;
332
+ pointerId: number;
333
+ start: number[];
334
+ origin: number;
335
+ /** Pixels the panels share (the root without its separators). */
336
+ space: number;
337
+ moved: boolean;
338
+ }
339
+ let drag: Drag | null = null;
340
+ const spaceOf = () => {
341
+ const box = root.getBoundingClientRect();
342
+ const handlesSize = handles.reduce((sum, handle) => sum + (horizontal() ? handle.offsetWidth : handle.offsetHeight), 0);
343
+ return Math.max(1, (horizontal() ? box.width : box.height) - handlesSize);
344
+ };
345
+ const showBubble = (i: number, at: number) => {
346
+ bubble.hidden = false;
347
+ bubble.textContent = `${Math.round(sizes[i]!)} % · ${Math.round(sizes[i + 1]!)} %`;
348
+ const handle = handles[i]!;
349
+ const box = handle.getBoundingClientRect();
350
+ const rootBox = root.getBoundingClientRect();
351
+ if (horizontal()) {
352
+ bubble.style.left = `${box.left - rootBox.left + box.width / 2}px`;
353
+ bubble.style.top = `${Math.max(16, Math.min(rootBox.height - 16, at - rootBox.top))}px`;
354
+ } else {
355
+ bubble.style.top = `${box.top - rootBox.top + box.height / 2}px`;
356
+ bubble.style.left = `${Math.max(40, Math.min(rootBox.width - 40, at - rootBox.left))}px`;
357
+ }
358
+ };
359
+ const hideBubble = () => {
360
+ if (bubble.hidden) return;
361
+ if (reduced()) {
362
+ bubble.hidden = true;
363
+ return;
364
+ }
365
+ // Opacity only: the bubble is centred with CSS translate, which transforms would reset.
366
+ keep(gsap.to(bubble, { opacity: 0, duration: 0.18, ease: 'power1.in', onComplete: () => {
367
+ bubble.hidden = true;
368
+ gsap.set(bubble, { clearProps: 'opacity' });
369
+ } }));
370
+ };
371
+
372
+ const move = (event: PointerEvent) => {
373
+ if (!drag || event.pointerId !== drag.pointerId) return;
374
+ event.preventDefault();
375
+ const i = drag.index;
376
+ const position = horizontal() ? event.clientX : event.clientY;
377
+ const wanted = ((position - drag.origin) / drag.space) * 100;
378
+ if (!drag.moved && Math.abs(wanted) > 0.2) {
379
+ drag.moved = true;
380
+ handles[i]!.setAttribute('data-mk-dragging', '');
381
+ if (!reduced()) keep(gsap.fromTo(bubble, { opacity: 0 }, { opacity: 1, duration: 0.2, ease: 'power1.out', clearProps: 'opacity' }));
382
+ }
383
+ // A collapsible panel dragged well under its minimum snaps shut; dragged back out, it opens.
384
+ for (const [index, sign] of [[i, 1], [i + 1, -1]] as const) {
385
+ if (!canCollapse[index]) continue;
386
+ const size = drag.start[index]! + sign * wanted;
387
+ const threshold = mins[index]! / 2;
388
+ if (!collapsed.has(index) && size < threshold) {
389
+ collapsed.add(index);
390
+ before.set(index, drag.start[index]! > 0.5 ? drag.start[index]! : before.get(index) ?? initial[index]!);
391
+ const target = [...drag.start];
392
+ target[index] = 0;
393
+ target[index === i ? i + 1 : i] = drag.start[i]! + drag.start[i + 1]!;
394
+ // If the drag is over when it lands, it settles then.
395
+ animateTo(target, { duration: 0.3, ease: EASE.swatch, done: () => (drag ? undefined : settle()) });
396
+ status.textContent = `${names[index]} cerrado`;
397
+ options.onCollapse?.(index, true);
398
+ return;
399
+ }
400
+ if (collapsed.has(index)) {
401
+ // Still shut while the pointer stays near it.
402
+ if (size <= threshold) return;
403
+ collapsed.delete(index);
404
+ status.textContent = `${names[index]} abierto`;
405
+ options.onCollapse?.(index, false);
406
+ }
407
+ }
408
+ if (tween) return;
409
+ const [down, up] = room(i, drag.start);
410
+ // Past a limit the panel gives a quarter of the way (rubber band).
411
+ const delta = wanted < down ? down + (wanted - down) / 4 : wanted > up ? up + (wanted - up) / 4 : wanted;
412
+ const next = [...drag.start];
413
+ next[i] = Math.max(0, drag.start[i]! + delta);
414
+ next[i + 1] = Math.max(0, drag.start[i + 1]! - delta);
415
+ sizes = next;
416
+ apply(sizes);
417
+ showBubble(i, horizontal() ? event.clientY : event.clientX);
418
+ notify();
419
+ };
420
+ const end = (event: PointerEvent) => {
421
+ if (!drag || event.pointerId !== drag.pointerId) return;
422
+ const { index } = drag;
423
+ const moved = drag.moved;
424
+ drag = null;
425
+ window.removeEventListener('pointermove', move);
426
+ window.removeEventListener('pointerup', end);
427
+ window.removeEventListener('pointercancel', end);
428
+ handles[index]!.removeAttribute('data-mk-dragging');
429
+ root.removeAttribute('data-mk-resizing');
430
+ hideBubble();
431
+ // A snap on its way settles when it lands.
432
+ if (!moved || tween) return;
433
+ // Back inside the limits with a spring, if the drag went past them.
434
+ const clamped = [...sizes];
435
+ for (const i of [index, index + 1]) {
436
+ if (collapsed.has(i)) continue;
437
+ const fixed = Math.min(maxs[i]!, Math.max(mins[i]!, clamped[i]!));
438
+ const other = i === index ? index + 1 : index;
439
+ clamped[other] = clamped[other]! + clamped[i]! - fixed;
440
+ clamped[i] = fixed;
441
+ }
442
+ if (clamped.some((size, i) => Math.abs(size - sizes[i]!) > 0.05)) animateTo(clamped, { duration: 0.45, ease: EASE.swatch, done: settle });
443
+ else settle();
444
+ // The grip settles with a little pop.
445
+ const grip = handles[index]!.querySelector('[data-mk-resize-grip]');
446
+ if (grip && !reduced()) keep(gsap.fromTo(grip, { scale: 1.25 }, { scale: 1, duration: 0.4, ease: EASE.pop, clearProps: 'transform' }));
447
+ };
448
+ scope.add(() => {
449
+ window.removeEventListener('pointermove', move);
450
+ window.removeEventListener('pointerup', end);
451
+ window.removeEventListener('pointercancel', end);
452
+ });
453
+
454
+ handles.forEach((handle, i) => {
455
+ scope.on(handle, 'pointerdown', (event) => {
456
+ const pointer = event as PointerEvent;
457
+ if (pointer.button !== 0 || (pointer.target as Element).closest('[data-mk-resize-button]')) return;
458
+ pointer.preventDefault();
459
+ handle.focus({ preventScroll: true });
460
+ tween?.kill();
461
+ tween = null;
462
+ drag = { index: i, pointerId: pointer.pointerId, start: [...sizes], origin: horizontal() ? pointer.clientX : pointer.clientY, space: spaceOf(), moved: false };
463
+ root.setAttribute('data-mk-resizing', '');
464
+ window.addEventListener('pointermove', move, { passive: false });
465
+ window.addEventListener('pointerup', end);
466
+ window.addEventListener('pointercancel', end);
467
+ });
468
+ scope.on(handle, 'dblclick', (event) => {
469
+ if ((event.target as Element).closest('[data-mk-resize-button]')) return;
470
+ collapsed.clear();
471
+ status.textContent = 'Tamaños iniciales';
472
+ animateTo([...initial], { done: settle });
473
+ });
474
+ scope.on(handle, 'click', (event) => {
475
+ const button = (event.target as Element).closest<HTMLElement>('[data-mk-resize-button]');
476
+ if (!button) return;
477
+ const index = button.dataset.mkResizeButton === 'start' ? i : i + 1;
478
+ setCollapsed(index, !collapsed.has(index));
479
+ });
480
+ scope.on(handle, 'keydown', (event) => {
481
+ const key = event as KeyboardEvent;
482
+ const less = horizontal() ? 'ArrowLeft' : 'ArrowUp';
483
+ const more = horizontal() ? 'ArrowRight' : 'ArrowDown';
484
+ let delta: number | null = null;
485
+ const [down, up] = room(i, sizes);
486
+ if (key.key === less) delta = -step * (key.shiftKey ? 4 : 1);
487
+ else if (key.key === more) delta = step * (key.shiftKey ? 4 : 1);
488
+ else if (key.key === 'Home') delta = down;
489
+ else if (key.key === 'End') delta = up;
490
+ else if (key.key === 'Enter') {
491
+ key.preventDefault();
492
+ // The panel before it shuts or opens (or the one after, when only that one can).
493
+ const index = canCollapse[i] ? i : canCollapse[i + 1] ? i + 1 : -1;
494
+ if (index >= 0) setCollapsed(index, !collapsed.has(index));
495
+ return;
496
+ }
497
+ if (delta === null) return;
498
+ key.preventDefault();
499
+ const moveBy = Math.max(down, Math.min(up, delta));
500
+ if (Math.abs(moveBy) < 0.01) {
501
+ // At the limit: a nudge says so.
502
+ if (!reduced()) keep(gsap.fromTo(handle.querySelector('[data-mk-resize-grip]'), { [horizontal() ? 'x' : 'y']: Math.sign(delta) * 3 }, { [horizontal() ? 'x' : 'y']: 0, duration: 0.4, ease: EASE.pop, clearProps: 'transform' }));
503
+ return;
504
+ }
505
+ const target = [...sizes];
506
+ target[i] = sizes[i]! + moveBy;
507
+ target[i + 1] = sizes[i + 1]! - moveBy;
508
+ animateTo(target, { duration: 0.2, ease: 'power2.out', done: settle });
509
+ });
510
+ });
511
+
512
+ return {
513
+ setSizes(next, animate = true) {
514
+ if (scope.disposed) return;
515
+ const target = normaliseSizes(next, count);
516
+ collapsed.clear();
517
+ target.forEach((size, i) => {
518
+ if (size < 0.5 && canCollapse[i]) collapsed.add(i);
519
+ });
520
+ if (animate) animateTo(target, { done: settle });
521
+ else {
522
+ tween?.kill();
523
+ sizes = target;
524
+ apply(sizes);
525
+ }
526
+ },
527
+ collapse: (index) => setCollapsed(index, true),
528
+ expand: (index) => setCollapsed(index, false),
529
+ toggle: (index) => setCollapsed(index, !collapsed.has(index)),
530
+ reset() {
531
+ collapsed.clear();
532
+ animateTo([...initial], { done: settle });
533
+ },
534
+ setOrientation(next) {
535
+ if (next === orientation || scope.disposed) return;
536
+ orientation = next;
537
+ paintOrientation();
538
+ apply(sizes);
539
+ },
540
+ get sizes() {
541
+ return sizes.map(round);
542
+ },
543
+ get collapsed() {
544
+ return [...collapsed];
545
+ },
546
+ get orientation() {
547
+ return orientation;
548
+ },
549
+ destroy: () => scope.dispose(),
550
+ };
551
+ }
@@ -0,0 +1,74 @@
1
+ 'use client';
2
+ import { Children, forwardRef, useImperativeHandle, useRef, type HTMLAttributes } from 'react';
3
+ import { useIsomorphicLayoutEffect, useLatest } from '../../react/use-recipe';
4
+ import { createResizablePanel, type ResizablePanelInstance, type ResizablePanelOptions } from './engine';
5
+
6
+ export interface ResizablePanelProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onResize'>, ResizablePanelOptions {}
7
+
8
+ export type ResizablePanelHandle = Pick<ResizablePanelInstance, 'setSizes' | 'collapse' | 'expand' | 'toggle' | 'reset'>;
9
+
10
+ /**
11
+ * <ResizablePanel sizes={[25, 75]} collapsible={[0]} onResizeEnd={save}><aside /><main /></ResizablePanel>.
12
+ * New `sizes` glide there; adding or taking away a panel starts it again.
13
+ */
14
+ export const ResizablePanel = forwardRef<ResizablePanelHandle, ResizablePanelProps>(function ResizablePanel(
15
+ { orientation, sizes, min, max, collapsible, collapsed, step, storageKey, handleButtons, labels, onResize, onResizeEnd, onCollapse, className, children, ...props },
16
+ handle,
17
+ ) {
18
+ const ref = useRef<HTMLDivElement>(null);
19
+ const instance = useRef<ResizablePanelInstance | null>(null);
20
+ const resize = useLatest(onResize);
21
+ const resizeEnd = useLatest(onResizeEnd);
22
+ const collapse = useLatest(onCollapse);
23
+ const shown = useRef(sizes);
24
+ useImperativeHandle(
25
+ handle,
26
+ () => ({
27
+ setSizes: (next, animate) => instance.current?.setSizes(next, animate),
28
+ collapse: (index) => instance.current?.collapse(index),
29
+ expand: (index) => instance.current?.expand(index),
30
+ toggle: (index) => instance.current?.toggle(index),
31
+ reset: () => instance.current?.reset(),
32
+ }),
33
+ [],
34
+ );
35
+ const count = Children.count(children);
36
+ useIsomorphicLayoutEffect(() => {
37
+ const created = createResizablePanel(ref.current, {
38
+ orientation,
39
+ sizes: shown.current,
40
+ min,
41
+ max,
42
+ collapsible,
43
+ collapsed,
44
+ step,
45
+ storageKey,
46
+ handleButtons,
47
+ labels,
48
+ onResize: (next) => resize.current?.(next),
49
+ onResizeEnd: (next) => resizeEnd.current?.(next),
50
+ onCollapse: (index, shut) => collapse.current?.(index, shut),
51
+ });
52
+ instance.current = created;
53
+ return () => {
54
+ created.destroy();
55
+ instance.current = null;
56
+ };
57
+ // eslint-disable-next-line react-hooks/exhaustive-deps
58
+ }, [count, min, max, String(collapsible), step, storageKey, handleButtons, String(labels)]);
59
+ useIsomorphicLayoutEffect(() => {
60
+ if (orientation) instance.current?.setOrientation(orientation);
61
+ }, [orientation]);
62
+ const sizesKey = JSON.stringify(sizes ?? null);
63
+ useIsomorphicLayoutEffect(() => {
64
+ if (!sizes || JSON.stringify(shown.current ?? null) === sizesKey) return;
65
+ shown.current = sizes;
66
+ instance.current?.setSizes(sizes);
67
+ // eslint-disable-next-line react-hooks/exhaustive-deps
68
+ }, [sizesKey]);
69
+ return (
70
+ <div {...props} ref={ref} className={['mk-resizable-panel', className].filter(Boolean).join(' ')}>
71
+ {children}
72
+ </div>
73
+ );
74
+ });