@nikala-ui/docs 0.12.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 (463) hide show
  1. package/README.md +22 -0
  2. package/dist/cli/commands/build.d.ts +5 -0
  3. package/dist/cli/commands/build.d.ts.map +1 -0
  4. package/dist/cli/commands/build.js +27 -0
  5. package/dist/cli/commands/build.js.map +1 -0
  6. package/dist/cli/commands/dev.d.ts +7 -0
  7. package/dist/cli/commands/dev.d.ts.map +1 -0
  8. package/dist/cli/commands/dev.js +32 -0
  9. package/dist/cli/commands/dev.js.map +1 -0
  10. package/dist/cli/commands/init.d.ts +2 -0
  11. package/dist/cli/commands/init.d.ts.map +1 -0
  12. package/dist/cli/commands/init.js +308 -0
  13. package/dist/cli/commands/init.js.map +1 -0
  14. package/dist/cli/commands/preview.d.ts +7 -0
  15. package/dist/cli/commands/preview.d.ts.map +1 -0
  16. package/dist/cli/commands/preview.js +24 -0
  17. package/dist/cli/commands/preview.js.map +1 -0
  18. package/dist/cli/commands/serve.d.ts +7 -0
  19. package/dist/cli/commands/serve.d.ts.map +1 -0
  20. package/dist/cli/commands/serve.js +33 -0
  21. package/dist/cli/commands/serve.js.map +1 -0
  22. package/dist/cli/index.d.ts +3 -0
  23. package/dist/cli/index.d.ts.map +1 -0
  24. package/dist/cli/index.js +53 -0
  25. package/dist/cli/index.js.map +1 -0
  26. package/dist/client/App.d.ts +5 -0
  27. package/dist/client/App.d.ts.map +1 -0
  28. package/dist/client/App.jsx +31 -0
  29. package/dist/client/App.jsx.map +1 -0
  30. package/dist/client/app-types.d.ts +14 -0
  31. package/dist/client/app-types.d.ts.map +1 -0
  32. package/dist/client/app-types.js +2 -0
  33. package/dist/client/app-types.js.map +1 -0
  34. package/dist/client/components/DocsLayoutShell.d.ts +21 -0
  35. package/dist/client/components/DocsLayoutShell.d.ts.map +1 -0
  36. package/dist/client/components/DocsLayoutShell.jsx +14 -0
  37. package/dist/client/components/DocsLayoutShell.jsx.map +1 -0
  38. package/dist/client/components/DocsPageContent.d.ts +9 -0
  39. package/dist/client/components/DocsPageContent.d.ts.map +1 -0
  40. package/dist/client/components/DocsPageContent.jsx +10 -0
  41. package/dist/client/components/DocsPageContent.jsx.map +1 -0
  42. package/dist/client/entry.d.ts +2 -0
  43. package/dist/client/entry.d.ts.map +1 -0
  44. package/dist/client/entry.jsx +28 -0
  45. package/dist/client/entry.jsx.map +1 -0
  46. package/dist/client/index.html +21 -0
  47. package/dist/client/navigation/page-navigation.d.ts +9 -0
  48. package/dist/client/navigation/page-navigation.d.ts.map +1 -0
  49. package/dist/client/navigation/page-navigation.js +51 -0
  50. package/dist/client/navigation/page-navigation.js.map +1 -0
  51. package/dist/client/routing/use-docs-router.d.ts +17 -0
  52. package/dist/client/routing/use-docs-router.d.ts.map +1 -0
  53. package/dist/client/routing/use-docs-router.js +71 -0
  54. package/dist/client/routing/use-docs-router.js.map +1 -0
  55. package/dist/client/ssr-entry.d.ts +3 -0
  56. package/dist/client/ssr-entry.d.ts.map +1 -0
  57. package/dist/client/ssr-entry.jsx +13 -0
  58. package/dist/client/ssr-entry.jsx.map +1 -0
  59. package/dist/client/style.css +183 -0
  60. package/dist/client/utils/sidebar.d.ts +2 -0
  61. package/dist/client/utils/sidebar.d.ts.map +1 -0
  62. package/dist/client/utils/sidebar.js +2 -0
  63. package/dist/client/utils/sidebar.js.map +1 -0
  64. package/dist/components/mdx-components.d.ts +34 -0
  65. package/dist/components/mdx-components.d.ts.map +1 -0
  66. package/dist/components/mdx-components.jsx +131 -0
  67. package/dist/components/mdx-components.jsx.map +1 -0
  68. package/dist/config.d.ts +6 -0
  69. package/dist/config.d.ts.map +1 -0
  70. package/dist/config.js +105 -0
  71. package/dist/config.js.map +1 -0
  72. package/dist/core/content-scanner.d.ts +10 -0
  73. package/dist/core/content-scanner.d.ts.map +1 -0
  74. package/dist/core/content-scanner.js +153 -0
  75. package/dist/core/content-scanner.js.map +1 -0
  76. package/dist/core/route-tree.d.ts +19 -0
  77. package/dist/core/route-tree.d.ts.map +1 -0
  78. package/dist/core/route-tree.js +176 -0
  79. package/dist/core/route-tree.js.map +1 -0
  80. package/dist/index.d.ts +13 -0
  81. package/dist/index.d.ts.map +1 -0
  82. package/dist/index.js +14 -0
  83. package/dist/index.js.map +1 -0
  84. package/dist/lib/cn.d.ts +6 -0
  85. package/dist/lib/cn.d.ts.map +1 -0
  86. package/dist/lib/cn.js +9 -0
  87. package/dist/lib/cn.js.map +1 -0
  88. package/dist/mdx/compiler.d.ts +13 -0
  89. package/dist/mdx/compiler.d.ts.map +1 -0
  90. package/dist/mdx/compiler.js +38 -0
  91. package/dist/mdx/compiler.js.map +1 -0
  92. package/dist/mdx/highlighter.d.ts +22 -0
  93. package/dist/mdx/highlighter.d.ts.map +1 -0
  94. package/dist/mdx/highlighter.js +139 -0
  95. package/dist/mdx/highlighter.js.map +1 -0
  96. package/dist/mdx/rehype-shiki.d.ts +3 -0
  97. package/dist/mdx/rehype-shiki.d.ts.map +1 -0
  98. package/dist/mdx/rehype-shiki.js +83 -0
  99. package/dist/mdx/rehype-shiki.js.map +1 -0
  100. package/dist/navigation/index.d.ts +2 -0
  101. package/dist/navigation/index.d.ts.map +1 -0
  102. package/dist/navigation/index.js +2 -0
  103. package/dist/navigation/index.js.map +1 -0
  104. package/dist/navigation/sidebar-state.d.ts +6 -0
  105. package/dist/navigation/sidebar-state.d.ts.map +1 -0
  106. package/dist/navigation/sidebar-state.js +20 -0
  107. package/dist/navigation/sidebar-state.js.map +1 -0
  108. package/dist/navigation/sidebar-tree.d.ts +7 -0
  109. package/dist/navigation/sidebar-tree.d.ts.map +1 -0
  110. package/dist/navigation/sidebar-tree.js +11 -0
  111. package/dist/navigation/sidebar-tree.js.map +1 -0
  112. package/dist/registry/accordion.json +18 -0
  113. package/dist/registry/alert.json +18 -0
  114. package/dist/registry/api-table.json +21 -0
  115. package/dist/registry/aspect-ratio.json +17 -0
  116. package/dist/registry/avatar.json +17 -0
  117. package/dist/registry/badge.json +18 -0
  118. package/dist/registry/banner.json +19 -0
  119. package/dist/registry/breadcrumb.json +17 -0
  120. package/dist/registry/bubble.json +18 -0
  121. package/dist/registry/button-group.json +20 -0
  122. package/dist/registry/button.json +21 -0
  123. package/dist/registry/callout.json +19 -0
  124. package/dist/registry/card.json +17 -0
  125. package/dist/registry/checkbox.json +20 -0
  126. package/dist/registry/code-block.json +26 -0
  127. package/dist/registry/code-group.json +20 -0
  128. package/dist/registry/collapsible.json +18 -0
  129. package/dist/registry/combobox.json +21 -0
  130. package/dist/registry/command.json +27 -0
  131. package/dist/registry/component-viewer.json +25 -0
  132. package/dist/registry/container.json +18 -0
  133. package/dist/registry/context-menu.json +24 -0
  134. package/dist/registry/create-active-element.json +13 -0
  135. package/dist/registry/create-app-updater.json +13 -0
  136. package/dist/registry/create-audio.json +7 -0
  137. package/dist/registry/create-battery.json +13 -0
  138. package/dist/registry/create-chat-scroll.json +13 -0
  139. package/dist/registry/create-click-outside.json +13 -0
  140. package/dist/registry/create-clipboard.json +13 -0
  141. package/dist/registry/create-color-mode.json +13 -0
  142. package/dist/registry/create-controllable-signal.json +13 -0
  143. package/dist/registry/create-debounce.json +13 -0
  144. package/dist/registry/create-disclosure.json +13 -0
  145. package/dist/registry/create-document-tabs.json +13 -0
  146. package/dist/registry/create-document-title.json +13 -0
  147. package/dist/registry/create-drop-zone.json +13 -0
  148. package/dist/registry/create-event-source.json +13 -0
  149. package/dist/registry/create-favicon.json +13 -0
  150. package/dist/registry/create-fetch.json +13 -0
  151. package/dist/registry/create-focus-trap.json +13 -0
  152. package/dist/registry/create-form.json +13 -0
  153. package/dist/registry/create-fullscreen.json +13 -0
  154. package/dist/registry/create-geolocation.json +13 -0
  155. package/dist/registry/create-global-shortcut.json +13 -0
  156. package/dist/registry/create-hover.json +13 -0
  157. package/dist/registry/create-idle.json +13 -0
  158. package/dist/registry/create-infinite-scroll.json +13 -0
  159. package/dist/registry/create-input-mask.json +13 -0
  160. package/dist/registry/create-intersection-observer.json +13 -0
  161. package/dist/registry/create-keybindings.json +13 -0
  162. package/dist/registry/create-lock-scroll.json +13 -0
  163. package/dist/registry/create-long-press.json +13 -0
  164. package/dist/registry/create-media-query.json +13 -0
  165. package/dist/registry/create-mouse-position.json +13 -0
  166. package/dist/registry/create-network-status.json +13 -0
  167. package/dist/registry/create-orientation.json +13 -0
  168. package/dist/registry/create-pagination.json +13 -0
  169. package/dist/registry/create-permission.json +13 -0
  170. package/dist/registry/create-previous.json +13 -0
  171. package/dist/registry/create-resize-observer.json +13 -0
  172. package/dist/registry/create-scroll-into-view.json +13 -0
  173. package/dist/registry/create-scroll-position.json +13 -0
  174. package/dist/registry/create-storage.json +13 -0
  175. package/dist/registry/create-tauri-window.json +13 -0
  176. package/dist/registry/create-timer.json +13 -0
  177. package/dist/registry/create-tiptap-editor.json +34 -0
  178. package/dist/registry/create-undo-redo.json +13 -0
  179. package/dist/registry/create-web-notification.json +13 -0
  180. package/dist/registry/create-websocket.json +13 -0
  181. package/dist/registry/create-window-size.json +13 -0
  182. package/dist/registry/dialog.json +21 -0
  183. package/dist/registry/dropdown-menu.json +22 -0
  184. package/dist/registry/dropzone.json +21 -0
  185. package/dist/registry/empty.json +17 -0
  186. package/dist/registry/field.json +20 -0
  187. package/dist/registry/file-tree.json +21 -0
  188. package/dist/registry/footer.json +18 -0
  189. package/dist/registry/forgot-password-01.json +28 -0
  190. package/dist/registry/form-message.json +17 -0
  191. package/dist/registry/form.json +17 -0
  192. package/dist/registry/hero-01.json +22 -0
  193. package/dist/registry/hover-card.json +18 -0
  194. package/dist/registry/icon-button.json +20 -0
  195. package/dist/registry/index.json +1489 -0
  196. package/dist/registry/input-group.json +21 -0
  197. package/dist/registry/input.json +17 -0
  198. package/dist/registry/kbd.json +18 -0
  199. package/dist/registry/label.json +18 -0
  200. package/dist/registry/list.json +20 -0
  201. package/dist/registry/login-01.json +28 -0
  202. package/dist/registry/logo.json +17 -0
  203. package/dist/registry/marker.json +17 -0
  204. package/dist/registry/marquee.json +17 -0
  205. package/dist/registry/message.json +17 -0
  206. package/dist/registry/navbar.json +19 -0
  207. package/dist/registry/navigation-menu.json +22 -0
  208. package/dist/registry/number-input.json +24 -0
  209. package/dist/registry/otp-verification-01.json +26 -0
  210. package/dist/registry/package-manager-tabs.json +24 -0
  211. package/dist/registry/pager.json +21 -0
  212. package/dist/registry/pagination.json +22 -0
  213. package/dist/registry/pin-input.json +17 -0
  214. package/dist/registry/popover.json +22 -0
  215. package/dist/registry/progress.json +18 -0
  216. package/dist/registry/radio-group.json +18 -0
  217. package/dist/registry/rating.json +19 -0
  218. package/dist/registry/register-01.json +31 -0
  219. package/dist/registry/resizable.json +21 -0
  220. package/dist/registry/review-card.json +23 -0
  221. package/dist/registry/rich-text-editor.json +95 -0
  222. package/dist/registry/scroll-area.json +21 -0
  223. package/dist/registry/section-heading.json +21 -0
  224. package/dist/registry/select.json +22 -0
  225. package/dist/registry/separator.json +17 -0
  226. package/dist/registry/sheet.json +22 -0
  227. package/dist/registry/sidebar.json +24 -0
  228. package/dist/registry/skeleton.json +17 -0
  229. package/dist/registry/slider.json +18 -0
  230. package/dist/registry/spinner.json +18 -0
  231. package/dist/registry/stat.json +19 -0
  232. package/dist/registry/status.json +18 -0
  233. package/dist/registry/steps.json +20 -0
  234. package/dist/registry/switch.json +20 -0
  235. package/dist/registry/table-of-contents.json +23 -0
  236. package/dist/registry/table.json +17 -0
  237. package/dist/registry/tabs.json +20 -0
  238. package/dist/registry/textarea.json +17 -0
  239. package/dist/registry/theme-manager.json +39 -0
  240. package/dist/registry/timeline.json +18 -0
  241. package/dist/registry/titlebar-tabs.json +24 -0
  242. package/dist/registry/titlebar.json +26 -0
  243. package/dist/registry/toast.json +20 -0
  244. package/dist/registry/toggle-group.json +21 -0
  245. package/dist/registry/toggle.json +18 -0
  246. package/dist/registry/tooltip.json +18 -0
  247. package/dist/registry/updater-modal.json +26 -0
  248. package/dist/server/index.d.ts +18 -0
  249. package/dist/server/index.d.ts.map +1 -0
  250. package/dist/server/index.js +526 -0
  251. package/dist/server/index.js.map +1 -0
  252. package/dist/server/plugin.d.ts +10 -0
  253. package/dist/server/plugin.d.ts.map +1 -0
  254. package/dist/server/plugin.js +271 -0
  255. package/dist/server/plugin.js.map +1 -0
  256. package/dist/themes/default/content/breadcrumbs.d.ts +4 -0
  257. package/dist/themes/default/content/breadcrumbs.d.ts.map +1 -0
  258. package/dist/themes/default/content/breadcrumbs.jsx +31 -0
  259. package/dist/themes/default/content/breadcrumbs.jsx.map +1 -0
  260. package/dist/themes/default/content/pager.d.ts +5 -0
  261. package/dist/themes/default/content/pager.d.ts.map +1 -0
  262. package/dist/themes/default/content/pager.jsx +9 -0
  263. package/dist/themes/default/content/pager.jsx.map +1 -0
  264. package/dist/themes/default/content/table-of-contents.d.ts +4 -0
  265. package/dist/themes/default/content/table-of-contents.d.ts.map +1 -0
  266. package/dist/themes/default/content/table-of-contents.jsx +19 -0
  267. package/dist/themes/default/content/table-of-contents.jsx.map +1 -0
  268. package/dist/themes/default/index.d.ts +11 -0
  269. package/dist/themes/default/index.d.ts.map +1 -0
  270. package/dist/themes/default/index.js +30 -0
  271. package/dist/themes/default/index.js.map +1 -0
  272. package/dist/themes/default/layout.d.ts +4 -0
  273. package/dist/themes/default/layout.d.ts.map +1 -0
  274. package/dist/themes/default/layout.jsx +75 -0
  275. package/dist/themes/default/layout.jsx.map +1 -0
  276. package/dist/themes/default/navbar.d.ts +4 -0
  277. package/dist/themes/default/navbar.d.ts.map +1 -0
  278. package/dist/themes/default/navbar.jsx +74 -0
  279. package/dist/themes/default/navbar.jsx.map +1 -0
  280. package/dist/themes/default/navigation/mobile-table-of-contents.d.ts +4 -0
  281. package/dist/themes/default/navigation/mobile-table-of-contents.d.ts.map +1 -0
  282. package/dist/themes/default/navigation/mobile-table-of-contents.jsx +22 -0
  283. package/dist/themes/default/navigation/mobile-table-of-contents.jsx.map +1 -0
  284. package/dist/themes/default/navigation/sidebar-tree.d.ts +8 -0
  285. package/dist/themes/default/navigation/sidebar-tree.d.ts.map +1 -0
  286. package/dist/themes/default/navigation/sidebar-tree.jsx +100 -0
  287. package/dist/themes/default/navigation/sidebar-tree.jsx.map +1 -0
  288. package/dist/themes/default/overlays/search-dialog.d.ts +4 -0
  289. package/dist/themes/default/overlays/search-dialog.d.ts.map +1 -0
  290. package/dist/themes/default/overlays/search-dialog.jsx +34 -0
  291. package/dist/themes/default/overlays/search-dialog.jsx.map +1 -0
  292. package/dist/themes/default/sidebar.d.ts +4 -0
  293. package/dist/themes/default/sidebar.d.ts.map +1 -0
  294. package/dist/themes/default/sidebar.jsx +60 -0
  295. package/dist/themes/default/sidebar.jsx.map +1 -0
  296. package/dist/themes/index.d.ts +4 -0
  297. package/dist/themes/index.d.ts.map +1 -0
  298. package/dist/themes/index.js +5 -0
  299. package/dist/themes/index.js.map +1 -0
  300. package/dist/themes/types.d.ts +83 -0
  301. package/dist/themes/types.d.ts.map +1 -0
  302. package/dist/themes/types.js +2 -0
  303. package/dist/themes/types.js.map +1 -0
  304. package/dist/types.d.ts +97 -0
  305. package/dist/types.d.ts.map +1 -0
  306. package/dist/types.js +3 -0
  307. package/dist/types.js.map +1 -0
  308. package/dist/vendor/core-src/index.css +11 -0
  309. package/dist/vendor/core-src/index.ts +48 -0
  310. package/dist/vendor/core-src/lib/cn.ts +9 -0
  311. package/dist/vendor/core-src/registry/blocks/forgot-password-01.tsx +141 -0
  312. package/dist/vendor/core-src/registry/blocks/hero-01.tsx +28 -0
  313. package/dist/vendor/core-src/registry/blocks/login-01.tsx +231 -0
  314. package/dist/vendor/core-src/registry/blocks/otp-verification-01.tsx +170 -0
  315. package/dist/vendor/core-src/registry/blocks/register-01.tsx +318 -0
  316. package/dist/vendor/core-src/registry/components/ui/accordion.tsx +128 -0
  317. package/dist/vendor/core-src/registry/components/ui/alert.tsx +155 -0
  318. package/dist/vendor/core-src/registry/components/ui/api-table.tsx +117 -0
  319. package/dist/vendor/core-src/registry/components/ui/aspect-ratio.tsx +31 -0
  320. package/dist/vendor/core-src/registry/components/ui/avatar.tsx +114 -0
  321. package/dist/vendor/core-src/registry/components/ui/badge.tsx +56 -0
  322. package/dist/vendor/core-src/registry/components/ui/banner.tsx +187 -0
  323. package/dist/vendor/core-src/registry/components/ui/breadcrumb.tsx +136 -0
  324. package/dist/vendor/core-src/registry/components/ui/bubble.tsx +142 -0
  325. package/dist/vendor/core-src/registry/components/ui/button-group.tsx +42 -0
  326. package/dist/vendor/core-src/registry/components/ui/button.tsx +82 -0
  327. package/dist/vendor/core-src/registry/components/ui/callout.tsx +137 -0
  328. package/dist/vendor/core-src/registry/components/ui/card.tsx +113 -0
  329. package/dist/vendor/core-src/registry/components/ui/checkbox.tsx +74 -0
  330. package/dist/vendor/core-src/registry/components/ui/code-block.tsx +326 -0
  331. package/dist/vendor/core-src/registry/components/ui/code-group.tsx +105 -0
  332. package/dist/vendor/core-src/registry/components/ui/collapsible.tsx +73 -0
  333. package/dist/vendor/core-src/registry/components/ui/combobox.tsx +299 -0
  334. package/dist/vendor/core-src/registry/components/ui/command.tsx +378 -0
  335. package/dist/vendor/core-src/registry/components/ui/component-viewer.tsx +363 -0
  336. package/dist/vendor/core-src/registry/components/ui/container.tsx +45 -0
  337. package/dist/vendor/core-src/registry/components/ui/context-menu.tsx +237 -0
  338. package/dist/vendor/core-src/registry/components/ui/dialog.tsx +200 -0
  339. package/dist/vendor/core-src/registry/components/ui/dropdown-menu.tsx +298 -0
  340. package/dist/vendor/core-src/registry/components/ui/dropzone.tsx +189 -0
  341. package/dist/vendor/core-src/registry/components/ui/empty.tsx +83 -0
  342. package/dist/vendor/core-src/registry/components/ui/field.tsx +71 -0
  343. package/dist/vendor/core-src/registry/components/ui/file-tree.tsx +181 -0
  344. package/dist/vendor/core-src/registry/components/ui/footer.tsx +247 -0
  345. package/dist/vendor/core-src/registry/components/ui/form-message.tsx +36 -0
  346. package/dist/vendor/core-src/registry/components/ui/form.tsx +21 -0
  347. package/dist/vendor/core-src/registry/components/ui/hover-card.tsx +105 -0
  348. package/dist/vendor/core-src/registry/components/ui/icon-button.tsx +34 -0
  349. package/dist/vendor/core-src/registry/components/ui/input-group.tsx +80 -0
  350. package/dist/vendor/core-src/registry/components/ui/input.tsx +28 -0
  351. package/dist/vendor/core-src/registry/components/ui/kbd.tsx +73 -0
  352. package/dist/vendor/core-src/registry/components/ui/label.tsx +30 -0
  353. package/dist/vendor/core-src/registry/components/ui/list.tsx +222 -0
  354. package/dist/vendor/core-src/registry/components/ui/logo.tsx +68 -0
  355. package/dist/vendor/core-src/registry/components/ui/marker.tsx +102 -0
  356. package/dist/vendor/core-src/registry/components/ui/marquee.tsx +118 -0
  357. package/dist/vendor/core-src/registry/components/ui/message.tsx +168 -0
  358. package/dist/vendor/core-src/registry/components/ui/navbar.tsx +375 -0
  359. package/dist/vendor/core-src/registry/components/ui/navigation-menu.tsx +358 -0
  360. package/dist/vendor/core-src/registry/components/ui/number-input.tsx +150 -0
  361. package/dist/vendor/core-src/registry/components/ui/package-manager-tabs.tsx +226 -0
  362. package/dist/vendor/core-src/registry/components/ui/pager.tsx +102 -0
  363. package/dist/vendor/core-src/registry/components/ui/pagination.tsx +258 -0
  364. package/dist/vendor/core-src/registry/components/ui/pin-input.tsx +198 -0
  365. package/dist/vendor/core-src/registry/components/ui/popover.tsx +90 -0
  366. package/dist/vendor/core-src/registry/components/ui/progress.tsx +66 -0
  367. package/dist/vendor/core-src/registry/components/ui/radio-group.tsx +95 -0
  368. package/dist/vendor/core-src/registry/components/ui/rating.tsx +185 -0
  369. package/dist/vendor/core-src/registry/components/ui/resizable.tsx +195 -0
  370. package/dist/vendor/core-src/registry/components/ui/review-card.tsx +195 -0
  371. package/dist/vendor/core-src/registry/components/ui/rich-text-editor/bubble-menu.tsx +236 -0
  372. package/dist/vendor/core-src/registry/components/ui/rich-text-editor/editor.tsx +308 -0
  373. package/dist/vendor/core-src/registry/components/ui/rich-text-editor/extensions.ts +116 -0
  374. package/dist/vendor/core-src/registry/components/ui/rich-text-editor/footer.tsx +36 -0
  375. package/dist/vendor/core-src/registry/components/ui/rich-text-editor/image-dialog.tsx +75 -0
  376. package/dist/vendor/core-src/registry/components/ui/rich-text-editor/index.ts +11 -0
  377. package/dist/vendor/core-src/registry/components/ui/rich-text-editor/link-dialog.tsx +48 -0
  378. package/dist/vendor/core-src/registry/components/ui/rich-text-editor/markdown.ts +170 -0
  379. package/dist/vendor/core-src/registry/components/ui/rich-text-editor/slash-command.tsx +301 -0
  380. package/dist/vendor/core-src/registry/components/ui/rich-text-editor/table-controls.tsx +68 -0
  381. package/dist/vendor/core-src/registry/components/ui/rich-text-editor/toolbar.tsx +465 -0
  382. package/dist/vendor/core-src/registry/components/ui/rich-text-editor/use-editor.ts +231 -0
  383. package/dist/vendor/core-src/registry/components/ui/scroll-area.tsx +228 -0
  384. package/dist/vendor/core-src/registry/components/ui/section-heading.tsx +108 -0
  385. package/dist/vendor/core-src/registry/components/ui/select.tsx +156 -0
  386. package/dist/vendor/core-src/registry/components/ui/separator.tsx +37 -0
  387. package/dist/vendor/core-src/registry/components/ui/sheet.tsx +220 -0
  388. package/dist/vendor/core-src/registry/components/ui/sidebar.tsx +692 -0
  389. package/dist/vendor/core-src/registry/components/ui/skeleton.tsx +24 -0
  390. package/dist/vendor/core-src/registry/components/ui/slider.tsx +153 -0
  391. package/dist/vendor/core-src/registry/components/ui/spinner.tsx +41 -0
  392. package/dist/vendor/core-src/registry/components/ui/stat.tsx +245 -0
  393. package/dist/vendor/core-src/registry/components/ui/status.tsx +121 -0
  394. package/dist/vendor/core-src/registry/components/ui/steps.tsx +198 -0
  395. package/dist/vendor/core-src/registry/components/ui/switch.tsx +68 -0
  396. package/dist/vendor/core-src/registry/components/ui/table-of-contents.tsx +131 -0
  397. package/dist/vendor/core-src/registry/components/ui/table.tsx +160 -0
  398. package/dist/vendor/core-src/registry/components/ui/tabs.tsx +204 -0
  399. package/dist/vendor/core-src/registry/components/ui/textarea.tsx +82 -0
  400. package/dist/vendor/core-src/registry/components/ui/theme-toggle.tsx +238 -0
  401. package/dist/vendor/core-src/registry/components/ui/timeline.tsx +350 -0
  402. package/dist/vendor/core-src/registry/components/ui/titlebar-tabs.tsx +773 -0
  403. package/dist/vendor/core-src/registry/components/ui/titlebar.tsx +468 -0
  404. package/dist/vendor/core-src/registry/components/ui/toast.tsx +124 -0
  405. package/dist/vendor/core-src/registry/components/ui/toggle-group.tsx +203 -0
  406. package/dist/vendor/core-src/registry/components/ui/toggle.tsx +101 -0
  407. package/dist/vendor/core-src/registry/components/ui/tooltip.tsx +41 -0
  408. package/dist/vendor/core-src/registry/components/ui/updater-modal.tsx +254 -0
  409. package/dist/vendor/core-src/registry/index.ts +50 -0
  410. package/dist/vendor/core-src/registry/metadata.ts +742 -0
  411. package/dist/vendor/core-src/registry/providers/theme-provider.tsx +216 -0
  412. package/dist/vendor/core-src/registry/providers/theme-script.tsx +78 -0
  413. package/dist/vendor/core-src/registry/providers/theme-transitions.ts +139 -0
  414. package/dist/vendor/hooks-src/create-active-element.ts +51 -0
  415. package/dist/vendor/hooks-src/create-app-updater.ts +272 -0
  416. package/dist/vendor/hooks-src/create-audio-video.ts +444 -0
  417. package/dist/vendor/hooks-src/create-battery.ts +78 -0
  418. package/dist/vendor/hooks-src/create-chat-scroll.ts +113 -0
  419. package/dist/vendor/hooks-src/create-click-outside.ts +82 -0
  420. package/dist/vendor/hooks-src/create-clipboard.ts +69 -0
  421. package/dist/vendor/hooks-src/create-color-mode.ts +115 -0
  422. package/dist/vendor/hooks-src/create-controllable-signal.ts +56 -0
  423. package/dist/vendor/hooks-src/create-debounce.ts +90 -0
  424. package/dist/vendor/hooks-src/create-disclosure.ts +82 -0
  425. package/dist/vendor/hooks-src/create-document-tabs.ts +267 -0
  426. package/dist/vendor/hooks-src/create-document-title.ts +33 -0
  427. package/dist/vendor/hooks-src/create-drop-zone.ts +317 -0
  428. package/dist/vendor/hooks-src/create-event-source.ts +126 -0
  429. package/dist/vendor/hooks-src/create-favicon.ts +52 -0
  430. package/dist/vendor/hooks-src/create-fetch.ts +93 -0
  431. package/dist/vendor/hooks-src/create-focus-trap.ts +94 -0
  432. package/dist/vendor/hooks-src/create-form.ts +200 -0
  433. package/dist/vendor/hooks-src/create-fullscreen.ts +105 -0
  434. package/dist/vendor/hooks-src/create-geolocation.ts +140 -0
  435. package/dist/vendor/hooks-src/create-global-shortcut.ts +140 -0
  436. package/dist/vendor/hooks-src/create-hover.ts +88 -0
  437. package/dist/vendor/hooks-src/create-idle.ts +109 -0
  438. package/dist/vendor/hooks-src/create-infinite-scroll.ts +90 -0
  439. package/dist/vendor/hooks-src/create-input-mask.ts +109 -0
  440. package/dist/vendor/hooks-src/create-intersection-observer.ts +82 -0
  441. package/dist/vendor/hooks-src/create-keybindings.ts +148 -0
  442. package/dist/vendor/hooks-src/create-lock-scroll.ts +97 -0
  443. package/dist/vendor/hooks-src/create-long-press.ts +85 -0
  444. package/dist/vendor/hooks-src/create-media-query.ts +94 -0
  445. package/dist/vendor/hooks-src/create-mouse-position.ts +87 -0
  446. package/dist/vendor/hooks-src/create-network-status.ts +100 -0
  447. package/dist/vendor/hooks-src/create-orientation.ts +129 -0
  448. package/dist/vendor/hooks-src/create-pagination.ts +208 -0
  449. package/dist/vendor/hooks-src/create-permission.ts +91 -0
  450. package/dist/vendor/hooks-src/create-previous.ts +21 -0
  451. package/dist/vendor/hooks-src/create-resize-observer.ts +89 -0
  452. package/dist/vendor/hooks-src/create-scroll-into-view.ts +57 -0
  453. package/dist/vendor/hooks-src/create-scroll-position.ts +129 -0
  454. package/dist/vendor/hooks-src/create-storage.ts +106 -0
  455. package/dist/vendor/hooks-src/create-tauri-window.ts +628 -0
  456. package/dist/vendor/hooks-src/create-timer.ts +150 -0
  457. package/dist/vendor/hooks-src/create-tiptap-editor.ts +326 -0
  458. package/dist/vendor/hooks-src/create-undo-redo.ts +100 -0
  459. package/dist/vendor/hooks-src/create-web-notification.ts +111 -0
  460. package/dist/vendor/hooks-src/create-websocket.ts +179 -0
  461. package/dist/vendor/hooks-src/create-window-size.ts +41 -0
  462. package/dist/vendor/hooks-src/index.ts +48 -0
  463. package/package.json +87 -0
@@ -0,0 +1,267 @@
1
+ import {
2
+ createSignal,
3
+ createMemo,
4
+ onMount,
5
+ onCleanup,
6
+ type Accessor,
7
+ } from "solid-js";
8
+
9
+ export interface TabItem<T = any> {
10
+ id: string;
11
+ title: string;
12
+ icon?: any;
13
+ isDirty?: boolean;
14
+ isPinned?: boolean;
15
+ closable?: boolean;
16
+ data?: T;
17
+ }
18
+
19
+ export interface CreateDocumentTabsOptions<T = any> {
20
+ /** Initial array of tab items. */
21
+ initialTabs?: TabItem<T>[];
22
+ /** Default active tab id. Defaults to first tab if available. */
23
+ defaultActiveId?: string;
24
+ /** Whether to enable keyboard shortcuts (Ctrl/Cmd+W to close active, Ctrl/Cmd+T for new tab). */
25
+ enableKeybindings?: boolean;
26
+ /** Callback triggered when the active tab changes. */
27
+ onTabChange?: (tab: TabItem<T> | undefined) => void;
28
+ /** Callback triggered before or when a tab closes. Return false to prevent closing. */
29
+ onTabClose?: (tab: TabItem<T>) => boolean | void;
30
+ /** Callback triggered when a new tab is created. */
31
+ onTabAdd?: (tab: TabItem<T>) => void;
32
+ }
33
+
34
+ export interface CreateDocumentTabsReturn<T = any> {
35
+ /** All tabs list. */
36
+ tabs: Accessor<TabItem<T>[]>;
37
+ /** Currently active tab ID. */
38
+ activeTabId: Accessor<string>;
39
+ /** Currently active tab object. */
40
+ activeTab: Accessor<TabItem<T> | undefined>;
41
+ /** Pinned tabs only. */
42
+ pinnedTabs: Accessor<TabItem<T>[]>;
43
+ /** Standard unpinned tabs. */
44
+ unpinnedTabs: Accessor<TabItem<T>[]>;
45
+ /** Whether any open tab has unsaved changes (isDirty). */
46
+ hasDirtyTabs: Accessor<boolean>;
47
+ /** Count of total open tabs. */
48
+ count: Accessor<number>;
49
+ /** Add a new tab to the list. */
50
+ addTab: (tab: TabItem<T>, activate?: boolean) => void;
51
+ /** Close a tab by ID with auto-switching to adjacent tab. */
52
+ closeTab: (id: string) => boolean;
53
+ /** Set the active tab. */
54
+ setActiveTab: (id: string) => void;
55
+ /** Mark or unmark a tab as dirty (unsaved changes). */
56
+ markDirty: (id: string, isDirty?: boolean) => void;
57
+ /** Toggle pinned state of a tab. */
58
+ togglePin: (id: string) => void;
59
+ /** Close all tabs except the specified one. */
60
+ closeOthers: (id: string) => void;
61
+ /** Close all open unpinned tabs. */
62
+ closeAll: (includePinned?: boolean) => void;
63
+ /** Switch to the next tab in sequence. */
64
+ nextTab: () => void;
65
+ /** Switch to the previous tab in sequence. */
66
+ prevTab: () => void;
67
+ /** Reorder tabs from one position to another. */
68
+ reorderTabs: (fromIndex: number, toIndex: number) => void;
69
+ }
70
+
71
+ function findLastPinnedIndex<T>(items: TabItem<T>[]): number {
72
+ for (let i = items.length - 1; i >= 0; i--) {
73
+ if (items[i].isPinned) return i;
74
+ }
75
+ return -1;
76
+ }
77
+
78
+ /**
79
+ * SolidJS reactive primitive for managing multi-document tabs, editor buffers, and browser tab states.
80
+ */
81
+ export function createDocumentTabs<T = any>(
82
+ options: CreateDocumentTabsOptions<T> = {}
83
+ ): CreateDocumentTabsReturn<T> {
84
+ const initial = options.initialTabs || [];
85
+ const [tabs, setTabs] = createSignal<TabItem<T>[]>(initial);
86
+ const [activeTabId, setActiveTabId] = createSignal<string>(
87
+ options.defaultActiveId || (initial.length > 0 ? initial[0].id : "")
88
+ );
89
+
90
+ const activeTab = createMemo(() => tabs().find((t) => t.id === activeTabId()));
91
+ const pinnedTabs = createMemo(() => tabs().filter((t) => t.isPinned));
92
+ const unpinnedTabs = createMemo(() => tabs().filter((t) => !t.isPinned));
93
+ const hasDirtyTabs = createMemo(() => tabs().some((t) => t.isDirty));
94
+ const count = createMemo(() => tabs().length);
95
+
96
+ const setActive = (id: string) => {
97
+ const target = tabs().find((t) => t.id === id);
98
+ if (target) {
99
+ setActiveTabId(id);
100
+ options.onTabChange?.(target);
101
+ }
102
+ };
103
+
104
+ const addTab = (tab: TabItem<T>, activate = true) => {
105
+ const existing = tabs().find((t) => t.id === tab.id);
106
+ if (existing) {
107
+ if (activate) setActive(tab.id);
108
+ return;
109
+ }
110
+
111
+ setTabs((prev) => {
112
+ if (tab.isPinned) {
113
+ const lastPinnedIdx = findLastPinnedIndex(prev);
114
+ if (lastPinnedIdx === -1) return [tab, ...prev];
115
+ const next = [...prev];
116
+ next.splice(lastPinnedIdx + 1, 0, tab);
117
+ return next;
118
+ }
119
+ return [...prev, tab];
120
+ });
121
+
122
+ if (activate) {
123
+ setActiveTabId(tab.id);
124
+ options.onTabChange?.(tab);
125
+ }
126
+ options.onTabAdd?.(tab);
127
+ };
128
+
129
+ const closeTab = (id: string): boolean => {
130
+ const currentTabs = tabs();
131
+ const tabToClose = currentTabs.find((t) => t.id === id);
132
+ if (!tabToClose) return false;
133
+
134
+ if (options.onTabClose && options.onTabClose(tabToClose) === false) {
135
+ return false;
136
+ }
137
+
138
+ const closeIdx = currentTabs.findIndex((t) => t.id === id);
139
+ const nextTabs = currentTabs.filter((t) => t.id !== id);
140
+ setTabs(nextTabs);
141
+
142
+ if (activeTabId() === id) {
143
+ if (nextTabs.length === 0) {
144
+ setActiveTabId("");
145
+ options.onTabChange?.(undefined);
146
+ } else {
147
+ const nextIdx = Math.min(closeIdx, nextTabs.length - 1);
148
+ const nextActive = nextTabs[nextIdx];
149
+ setActiveTabId(nextActive.id);
150
+ options.onTabChange?.(nextActive);
151
+ }
152
+ }
153
+ return true;
154
+ };
155
+
156
+ const markDirty = (id: string, isDirty = true) => {
157
+ setTabs((prev) =>
158
+ prev.map((t) => (t.id === id ? { ...t, isDirty } : t))
159
+ );
160
+ };
161
+
162
+ const togglePin = (id: string) => {
163
+ setTabs((prev) => {
164
+ const target = prev.find((t) => t.id === id);
165
+ if (!target) return prev;
166
+ const updated = { ...target, isPinned: !target.isPinned };
167
+ const remaining = prev.filter((t) => t.id !== id);
168
+
169
+ if (updated.isPinned) {
170
+ const lastPinnedIdx = findLastPinnedIndex(remaining);
171
+ if (lastPinnedIdx === -1) return [updated, ...remaining];
172
+ remaining.splice(lastPinnedIdx + 1, 0, updated);
173
+ return remaining;
174
+ }
175
+ return [...remaining, updated];
176
+ });
177
+ };
178
+
179
+ const closeOthers = (id: string) => {
180
+ setTabs((prev) => prev.filter((t) => t.id === id || t.isPinned));
181
+ setActive(id);
182
+ };
183
+
184
+ const closeAll = (includePinned = false) => {
185
+ if (includePinned) {
186
+ setTabs([]);
187
+ setActiveTabId("");
188
+ options.onTabChange?.(undefined);
189
+ } else {
190
+ const pinned = tabs().filter((t) => t.isPinned);
191
+ setTabs(pinned);
192
+ if (pinned.length > 0) {
193
+ setActiveTabId(pinned[0].id);
194
+ options.onTabChange?.(pinned[0]);
195
+ } else {
196
+ setActiveTabId("");
197
+ options.onTabChange?.(undefined);
198
+ }
199
+ }
200
+ };
201
+
202
+ const nextTab = () => {
203
+ const list = tabs();
204
+ if (list.length <= 1) return;
205
+ const currentIdx = list.findIndex((t) => t.id === activeTabId());
206
+ const nextIdx = (currentIdx + 1) % list.length;
207
+ setActive(list[nextIdx].id);
208
+ };
209
+
210
+ const prevTab = () => {
211
+ const list = tabs();
212
+ if (list.length <= 1) return;
213
+ const currentIdx = list.findIndex((t) => t.id === activeTabId());
214
+ const prevIdx = (currentIdx - 1 + list.length) % list.length;
215
+ setActive(list[prevIdx].id);
216
+ };
217
+
218
+ const reorderTabs = (fromIndex: number, toIndex: number) => {
219
+ setTabs((prev) => {
220
+ if (fromIndex < 0 || fromIndex >= prev.length || toIndex < 0 || toIndex >= prev.length) {
221
+ return prev;
222
+ }
223
+ const clone = [...prev];
224
+ const [moved] = clone.splice(fromIndex, 1);
225
+ clone.splice(toIndex, 0, moved);
226
+ return clone;
227
+ });
228
+ };
229
+
230
+ onMount(() => {
231
+ if (!options.enableKeybindings || typeof window === "undefined") return;
232
+
233
+ const handleKeyDown = (e: KeyboardEvent) => {
234
+ const isCmdOrCtrl = e.metaKey || e.ctrlKey;
235
+ if (isCmdOrCtrl && (e.key === "w" || e.key === "W")) {
236
+ const active = activeTabId();
237
+ if (active) {
238
+ e.preventDefault();
239
+ closeTab(active);
240
+ }
241
+ }
242
+ };
243
+
244
+ window.addEventListener("keydown", handleKeyDown);
245
+ onCleanup(() => window.removeEventListener("keydown", handleKeyDown));
246
+ });
247
+
248
+ return {
249
+ tabs,
250
+ activeTabId,
251
+ activeTab,
252
+ pinnedTabs,
253
+ unpinnedTabs,
254
+ hasDirtyTabs,
255
+ count,
256
+ addTab,
257
+ closeTab,
258
+ setActiveTab: setActive,
259
+ markDirty,
260
+ togglePin,
261
+ closeOthers,
262
+ closeAll,
263
+ nextTab,
264
+ prevTab,
265
+ reorderTabs,
266
+ };
267
+ }
@@ -0,0 +1,33 @@
1
+ import { createEffect, onCleanup, type Accessor } from "solid-js";
2
+
3
+ export interface CreateDocumentTitleOptions {
4
+ /** Whether to restore original title on component unmount. Defaults to true. */
5
+ restoreOnUnmount?: boolean;
6
+ }
7
+
8
+ /**
9
+ * SolidJS reactive primitive for managing document title dynamically.
10
+ */
11
+ export function createDocumentTitle(
12
+ title: string | Accessor<string>,
13
+ options: CreateDocumentTitleOptions = {}
14
+ ): void {
15
+ const getTitle = (): string => (typeof title === "function" ? title() : title);
16
+
17
+ createEffect(() => {
18
+ if (typeof document === "undefined") return;
19
+
20
+ const originalTitle = document.title;
21
+ const newTitle = getTitle();
22
+
23
+ if (newTitle) {
24
+ document.title = newTitle;
25
+ }
26
+
27
+ onCleanup(() => {
28
+ if (typeof document !== "undefined" && (options.restoreOnUnmount ?? true)) {
29
+ document.title = originalTitle;
30
+ }
31
+ });
32
+ });
33
+ }
@@ -0,0 +1,317 @@
1
+ import { createSignal, onCleanup, onMount, type Accessor } from "solid-js";
2
+
3
+ export interface FileRejection {
4
+ file: File;
5
+ errors: Array<{
6
+ code: "file-invalid-type" | "file-too-large" | "file-too-small" | "too-many-files";
7
+ message: string;
8
+ }>;
9
+ }
10
+
11
+ export interface CreateDropZoneOptions {
12
+ /** Accepted file types: MIME types (e.g. "image/*", "application/pdf") or extensions (e.g. ".png", ".jpg") */
13
+ accept?: string | string[];
14
+ /** Maximum number of files allowed */
15
+ maxFiles?: number;
16
+ /** Maximum file size in bytes */
17
+ maxSize?: number;
18
+ /** Minimum file size in bytes */
19
+ minSize?: number;
20
+ /** Whether multiple files are allowed. Defaults to true */
21
+ multiple?: boolean;
22
+ /** Whether the drop zone is disabled */
23
+ disabled?: boolean | Accessor<boolean>;
24
+ /** Prevents browser default behavior of opening files dropped outside dropzone. Defaults to true */
25
+ preventDropOnDocument?: boolean;
26
+ /** Callback fired when valid files are dropped */
27
+ onDrop?: (files: File[], event: DragEvent) => void;
28
+ /** Callback fired when some or all files fail validation */
29
+ onDropRejected?: (rejectedFiles: FileRejection[], event: DragEvent) => void;
30
+ /** Callback fired when drag enters the dropzone */
31
+ onDragEnter?: (event: DragEvent) => void;
32
+ /** Callback fired when drag leaves the dropzone */
33
+ onDragLeave?: (event: DragEvent) => void;
34
+ /** Callback fired when dragging over the dropzone */
35
+ onDragOver?: (event: DragEvent) => void;
36
+ /** Callback fired whenever accepted files list changes */
37
+ onFilesChanged?: (files: File[]) => void;
38
+ }
39
+
40
+ export interface CreateDropZoneReturn {
41
+ /** Whether drag operation is currently active over the target drop zone */
42
+ isOver: Accessor<boolean>;
43
+ /** Whether files are currently being dragged anywhere on the window */
44
+ isDragging: Accessor<boolean>;
45
+ /** Currently accepted dropped files */
46
+ files: Accessor<File[]>;
47
+ /** Currently rejected files with error details */
48
+ rejectedFiles: Accessor<FileRejection[]>;
49
+ /** Clear all accepted and rejected files */
50
+ clear: () => void;
51
+ /** Programmatically set files (e.g. from an <input type="file" /> change event) */
52
+ setFiles: (files: File[]) => void;
53
+ /** Programmatically open the native browser file selector dialog */
54
+ openFileDialog: () => void;
55
+ /** Ref callback to attach to target DOM element */
56
+ ref: (el: HTMLElement) => void;
57
+ /** Event handler props to spread directly onto target JSX element */
58
+ props: {
59
+ onDragEnter: (e: DragEvent) => void;
60
+ onDragLeave: (e: DragEvent) => void;
61
+ onDragOver: (e: DragEvent) => void;
62
+ onDrop: (e: DragEvent) => void;
63
+ };
64
+ }
65
+
66
+ function matchesAccept(file: File, acceptList: string[]): boolean {
67
+ if (acceptList.length === 0) return true;
68
+ const fileName = file.name.toLowerCase();
69
+ const fileType = file.type.toLowerCase();
70
+
71
+ return acceptList.some((pattern) => {
72
+ const p = pattern.trim().toLowerCase();
73
+ if (p.startsWith(".")) {
74
+ return fileName.endsWith(p);
75
+ }
76
+ if (p.endsWith("/*")) {
77
+ const typePrefix = p.slice(0, -2);
78
+ return fileType.startsWith(typePrefix + "/");
79
+ }
80
+ return fileType === p;
81
+ });
82
+ }
83
+
84
+ function validateFiles(
85
+ incomingFiles: File[],
86
+ options: CreateDropZoneOptions
87
+ ): { accepted: File[]; rejected: FileRejection[] } {
88
+ const acceptList = options.accept
89
+ ? (Array.isArray(options.accept) ? options.accept : options.accept.split(","))
90
+ .map((s) => s.trim())
91
+ .filter(Boolean)
92
+ : [];
93
+
94
+ const maxFiles = options.maxFiles ?? (options.multiple === false ? 1 : Infinity);
95
+ const maxSize = options.maxSize;
96
+ const minSize = options.minSize;
97
+
98
+ const accepted: File[] = [];
99
+ const rejected: FileRejection[] = [];
100
+
101
+ incomingFiles.forEach((file, index) => {
102
+ const errors: FileRejection["errors"] = [];
103
+
104
+ if (index >= maxFiles) {
105
+ errors.push({
106
+ code: "too-many-files",
107
+ message: `Maximum allowed files is ${maxFiles}.`,
108
+ });
109
+ }
110
+
111
+ if (acceptList.length > 0 && !matchesAccept(file, acceptList)) {
112
+ errors.push({
113
+ code: "file-invalid-type",
114
+ message: `File type "${file.type || file.name.split(".").pop()}" is not allowed.`,
115
+ });
116
+ }
117
+
118
+ if (maxSize !== undefined && file.size > maxSize) {
119
+ errors.push({
120
+ code: "file-too-large",
121
+ message: `File size exceeds ${(maxSize / (1024 * 1024)).toFixed(1)}MB limit.`,
122
+ });
123
+ }
124
+
125
+ if (minSize !== undefined && file.size < minSize) {
126
+ errors.push({
127
+ code: "file-too-small",
128
+ message: `File size is below ${(minSize / 1024).toFixed(1)}KB limit.`,
129
+ });
130
+ }
131
+
132
+ if (errors.length > 0) {
133
+ rejected.push({ file, errors });
134
+ } else {
135
+ accepted.push(file);
136
+ }
137
+ });
138
+
139
+ return { accepted, rejected };
140
+ }
141
+
142
+ /**
143
+ * SolidJS reactive primitive for managing file drag & drop zones with validation and file dialog support.
144
+ *
145
+ * @param options Configuration options for file acceptance, size limits, and callbacks.
146
+ */
147
+ export function createDropZone(options: CreateDropZoneOptions = {}): CreateDropZoneReturn {
148
+ const [isOver, setIsOver] = createSignal(false);
149
+ const [isDragging, setIsDragging] = createSignal(false);
150
+ const [files, setFilesInternal] = createSignal<File[]>([]);
151
+ const [rejectedFiles, setRejectedFilesInternal] = createSignal<FileRejection[]>([]);
152
+
153
+ let dragCounter = 0;
154
+ let windowDragCounter = 0;
155
+ let targetElement: HTMLElement | null = null;
156
+
157
+ const isDisabled = () => {
158
+ if (typeof options.disabled === "function") {
159
+ return (options.disabled as Accessor<boolean>)();
160
+ }
161
+ return options.disabled ?? false;
162
+ };
163
+
164
+ const processFiles = (incomingFiles: File[], event: DragEvent) => {
165
+ const { accepted, rejected } = validateFiles(incomingFiles, options);
166
+
167
+ setFilesInternal(accepted);
168
+ setRejectedFilesInternal(rejected);
169
+
170
+ if (accepted.length > 0) {
171
+ options.onDrop?.(accepted, event);
172
+ options.onFilesChanged?.(accepted);
173
+ }
174
+
175
+ if (rejected.length > 0) {
176
+ options.onDropRejected?.(rejected, event);
177
+ }
178
+ };
179
+
180
+ const onDragEnter = (e: DragEvent) => {
181
+ if (isDisabled()) return;
182
+ e.preventDefault();
183
+ dragCounter++;
184
+ if (dragCounter === 1) {
185
+ setIsOver(true);
186
+ options.onDragEnter?.(e);
187
+ }
188
+ };
189
+
190
+ const onDragOver = (e: DragEvent) => {
191
+ if (isDisabled()) return;
192
+ e.preventDefault();
193
+ if (e.dataTransfer) {
194
+ e.dataTransfer.dropEffect = "copy";
195
+ }
196
+ options.onDragOver?.(e);
197
+ };
198
+
199
+ const onDragLeave = (e: DragEvent) => {
200
+ if (isDisabled()) return;
201
+ e.preventDefault();
202
+ dragCounter--;
203
+ if (dragCounter <= 0) {
204
+ dragCounter = 0;
205
+ setIsOver(false);
206
+ options.onDragLeave?.(e);
207
+ }
208
+ };
209
+
210
+ const onDrop = (e: DragEvent) => {
211
+ if (isDisabled()) return;
212
+ e.preventDefault();
213
+ dragCounter = 0;
214
+ setIsOver(false);
215
+
216
+ if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {
217
+ processFiles(Array.from(e.dataTransfer.files), e);
218
+ }
219
+ };
220
+
221
+ const clear = () => {
222
+ setFilesInternal([]);
223
+ setRejectedFilesInternal([]);
224
+ options.onFilesChanged?.([]);
225
+ };
226
+
227
+ const setFiles = (newFiles: File[]) => {
228
+ const dummyEvent = new Event("drop") as unknown as DragEvent;
229
+ processFiles(newFiles, dummyEvent);
230
+ };
231
+
232
+ const openFileDialog = () => {
233
+ if (typeof document === "undefined" || isDisabled()) return;
234
+ const input = document.createElement("input");
235
+ input.type = "file";
236
+ if (options.multiple !== false && (options.maxFiles === undefined || options.maxFiles > 1)) {
237
+ input.multiple = true;
238
+ }
239
+ if (options.accept) {
240
+ input.accept = Array.isArray(options.accept) ? options.accept.join(",") : options.accept;
241
+ }
242
+ input.onchange = (e) => {
243
+ const target = e.target as HTMLInputElement;
244
+ if (target.files && target.files.length > 0) {
245
+ processFiles(Array.from(target.files), e as unknown as DragEvent);
246
+ }
247
+ };
248
+ input.click();
249
+ };
250
+
251
+ const ref = (el: HTMLElement) => {
252
+ targetElement = el;
253
+ };
254
+
255
+ // Window-level drag detection and document drop prevention
256
+ onMount(() => {
257
+ if (typeof window === "undefined") return;
258
+
259
+ const handleWindowDragEnter = (e: DragEvent) => {
260
+ windowDragCounter++;
261
+ if (windowDragCounter === 1) {
262
+ setIsDragging(true);
263
+ }
264
+ };
265
+
266
+ const handleWindowDragLeave = (e: DragEvent) => {
267
+ windowDragCounter--;
268
+ if (windowDragCounter <= 0) {
269
+ windowDragCounter = 0;
270
+ setIsDragging(false);
271
+ }
272
+ };
273
+
274
+ const handleWindowDrop = (e: DragEvent) => {
275
+ windowDragCounter = 0;
276
+ setIsDragging(false);
277
+ if (options.preventDropOnDocument !== false) {
278
+ e.preventDefault();
279
+ }
280
+ };
281
+
282
+ const handleWindowDragOver = (e: DragEvent) => {
283
+ if (options.preventDropOnDocument !== false) {
284
+ e.preventDefault();
285
+ }
286
+ };
287
+
288
+ window.addEventListener("dragenter", handleWindowDragEnter);
289
+ window.addEventListener("dragleave", handleWindowDragLeave);
290
+ window.addEventListener("dragover", handleWindowDragOver);
291
+ window.addEventListener("drop", handleWindowDrop);
292
+
293
+ onCleanup(() => {
294
+ window.removeEventListener("dragenter", handleWindowDragEnter);
295
+ window.removeEventListener("dragleave", handleWindowDragLeave);
296
+ window.removeEventListener("dragover", handleWindowDragOver);
297
+ window.removeEventListener("drop", handleWindowDrop);
298
+ });
299
+ });
300
+
301
+ return {
302
+ isOver,
303
+ isDragging,
304
+ files,
305
+ rejectedFiles,
306
+ clear,
307
+ setFiles,
308
+ openFileDialog,
309
+ ref,
310
+ props: {
311
+ onDragEnter,
312
+ onDragLeave,
313
+ onDragOver,
314
+ onDrop,
315
+ },
316
+ };
317
+ }