@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,272 @@
1
+ import { createSignal, onMount, type Accessor } from "solid-js";
2
+ import { isTauriEnvironment } from "./create-tauri-window";
3
+
4
+ export type UpdaterStatus =
5
+ | "idle"
6
+ | "checking"
7
+ | "available"
8
+ | "up-to-date"
9
+ | "downloading"
10
+ | "downloaded"
11
+ | "error";
12
+
13
+ export interface UpdateManifestInfo {
14
+ version: string;
15
+ currentVersion?: string;
16
+ date?: string;
17
+ body?: string;
18
+ }
19
+
20
+ export interface UpdateProgressInfo {
21
+ downloaded: number;
22
+ total: number;
23
+ percentage: number;
24
+ }
25
+
26
+ export interface CreateAppUpdaterOptions {
27
+ /** Automatically check for updates on mount. Defaults to false. */
28
+ autoCheck?: boolean;
29
+ /** Current application version fallback if not detected. */
30
+ currentVersion?: string;
31
+ /** Callback fired when an update is available. */
32
+ onUpdateAvailable?: (info: UpdateManifestInfo) => void;
33
+ /** Callback fired when download finishes. */
34
+ onDownloadFinished?: () => void;
35
+ /** Callback fired on update check or download error. */
36
+ onError?: (error: Error | string) => void;
37
+ }
38
+
39
+ export interface CreateAppUpdaterReturn {
40
+ /** Current lifecycle status of the updater. */
41
+ status: Accessor<UpdaterStatus>;
42
+ /** Update metadata (new version, release notes, release date). */
43
+ updateInfo: Accessor<UpdateManifestInfo | null>;
44
+ /** Download progress (bytes downloaded, total bytes, percentage). */
45
+ progress: Accessor<UpdateProgressInfo>;
46
+ /** Error message if an operation failed. */
47
+ error: Accessor<string | null>;
48
+ /** Whether an update is currently being checked or downloaded. */
49
+ isLoading: Accessor<boolean>;
50
+ /** Check update endpoint for a new release. */
51
+ checkForUpdates: () => Promise<boolean>;
52
+ /** Download and install the available update. */
53
+ downloadAndInstall: () => Promise<void>;
54
+ /** Restart application to apply the downloaded update. */
55
+ relaunch: () => Promise<void>;
56
+ /** Dismiss current update prompt or clear error state. */
57
+ dismiss: () => void;
58
+ /** Simulate an update cycle in web / playground preview environments. */
59
+ simulateUpdate: (mockInfo?: Partial<UpdateManifestInfo>) => void;
60
+ }
61
+
62
+ /**
63
+ * SolidJS reactive primitive for controlling and observing Tauri v2 application updates.
64
+ * Integrates with @tauri-apps/plugin-updater with full web simulation support.
65
+ */
66
+ export function createAppUpdater(
67
+ options: CreateAppUpdaterOptions = {}
68
+ ): CreateAppUpdaterReturn {
69
+ const [status, setStatus] = createSignal<UpdaterStatus>("idle");
70
+ const [updateInfo, setUpdateInfo] = createSignal<UpdateManifestInfo | null>(null);
71
+ const [progress, setProgress] = createSignal<UpdateProgressInfo>({
72
+ downloaded: 0,
73
+ total: 0,
74
+ percentage: 0,
75
+ });
76
+ const [error, setError] = createSignal<string | null>(null);
77
+
78
+ let activeTauriUpdate: any = null;
79
+ let simulatedTimer: any = null;
80
+
81
+ const getTauriUpdaterPlugin = async () => {
82
+ if (typeof window === "undefined") return null;
83
+ try {
84
+ if ((window as any).__TAURI__?.updater) {
85
+ return (window as any).__TAURI__.updater;
86
+ }
87
+ const moduleName = "@tauri-apps/plugin-updater";
88
+ // @ts-ignore - Optional runtime dependency in Tauri apps
89
+ const plugin = await import(/* @vite-ignore */ moduleName).catch(() => null);
90
+ return plugin;
91
+ } catch {
92
+ return null;
93
+ }
94
+ };
95
+
96
+ const getTauriProcessPlugin = async () => {
97
+ if (typeof window === "undefined") return null;
98
+ try {
99
+ if ((window as any).__TAURI__?.process) {
100
+ return (window as any).__TAURI__.process;
101
+ }
102
+ const moduleName = "@tauri-apps/plugin-process";
103
+ // @ts-ignore - Optional runtime dependency in Tauri apps
104
+ const plugin = await import(/* @vite-ignore */ moduleName).catch(() => null);
105
+ return plugin;
106
+ } catch {
107
+ return null;
108
+ }
109
+ };
110
+
111
+ const checkForUpdates = async (): Promise<boolean> => {
112
+ setStatus("checking");
113
+ setError(null);
114
+
115
+ if (isTauriEnvironment()) {
116
+ try {
117
+ const updaterPlugin = await getTauriUpdaterPlugin();
118
+ if (updaterPlugin?.check) {
119
+ const update = await updaterPlugin.check();
120
+ if (update?.available) {
121
+ activeTauriUpdate = update;
122
+ const info: UpdateManifestInfo = {
123
+ version: update.version,
124
+ currentVersion: update.currentVersion || options.currentVersion || "v1.0.0",
125
+ date: update.date,
126
+ body: update.body || "Bug fixes and performance enhancements.",
127
+ };
128
+ setUpdateInfo(info);
129
+ setStatus("available");
130
+ options.onUpdateAvailable?.(info);
131
+ return true;
132
+ } else {
133
+ setStatus("up-to-date");
134
+ return false;
135
+ }
136
+ }
137
+ } catch (err: any) {
138
+ const errMsg = err?.message || String(err);
139
+ setError(errMsg);
140
+ setStatus("error");
141
+ options.onError?.(errMsg);
142
+ return false;
143
+ }
144
+ }
145
+
146
+ // In web preview / non-tauri mode, simulate checking
147
+ await new Promise((resolve) => setTimeout(resolve, 800));
148
+ setStatus("up-to-date");
149
+ return false;
150
+ };
151
+
152
+ const downloadAndInstall = async (): Promise<void> => {
153
+ if (status() !== "available" && status() !== "error") return;
154
+ setStatus("downloading");
155
+ setError(null);
156
+ setProgress({ downloaded: 0, total: 100, percentage: 0 });
157
+
158
+ if (isTauriEnvironment() && activeTauriUpdate?.downloadAndInstall) {
159
+ try {
160
+ let downloadedBytes = 0;
161
+ let contentLength = 0;
162
+
163
+ await activeTauriUpdate.downloadAndInstall((event: any) => {
164
+ if (event.event === "Started") {
165
+ contentLength = event.data?.contentLength || 100;
166
+ } else if (event.event === "Progress") {
167
+ downloadedBytes += event.data?.chunkLength || 0;
168
+ const pct = contentLength > 0 ? Math.min(100, Math.round((downloadedBytes / contentLength) * 100)) : 50;
169
+ setProgress({
170
+ downloaded: downloadedBytes,
171
+ total: contentLength,
172
+ percentage: pct,
173
+ });
174
+ } else if (event.event === "Finished") {
175
+ setProgress({
176
+ downloaded: contentLength,
177
+ total: contentLength,
178
+ percentage: 100,
179
+ });
180
+ }
181
+ });
182
+
183
+ setStatus("downloaded");
184
+ options.onDownloadFinished?.();
185
+ return;
186
+ } catch (err: any) {
187
+ const errMsg = err?.message || String(err);
188
+ setError(errMsg);
189
+ setStatus("error");
190
+ options.onError?.(errMsg);
191
+ return;
192
+ }
193
+ }
194
+
195
+ // Web simulation mode with smooth progress step
196
+ let currentPct = 0;
197
+ simulatedTimer = setInterval(() => {
198
+ currentPct += 15;
199
+ if (currentPct >= 100) {
200
+ clearInterval(simulatedTimer);
201
+ setProgress({ downloaded: 45.8 * 1024 * 1024, total: 45.8 * 1024 * 1024, percentage: 100 });
202
+ setStatus("downloaded");
203
+ options.onDownloadFinished?.();
204
+ } else {
205
+ const downloaded = (45.8 * 1024 * 1024 * currentPct) / 100;
206
+ setProgress({ downloaded, total: 45.8 * 1024 * 1024, percentage: currentPct });
207
+ }
208
+ }, 250);
209
+ };
210
+
211
+ const relaunch = async (): Promise<void> => {
212
+ if (isTauriEnvironment()) {
213
+ try {
214
+ const processPlugin = await getTauriProcessPlugin();
215
+ if (processPlugin?.relaunch) {
216
+ await processPlugin.relaunch();
217
+ return;
218
+ }
219
+ } catch {
220
+ // Fallback
221
+ }
222
+ }
223
+
224
+ if (typeof window !== "undefined") {
225
+ window.location.reload();
226
+ }
227
+ };
228
+
229
+ const dismiss = (): void => {
230
+ if (simulatedTimer) clearInterval(simulatedTimer);
231
+ setStatus("idle");
232
+ setError(null);
233
+ };
234
+
235
+ const simulateUpdate = (mockInfo?: Partial<UpdateManifestInfo>): void => {
236
+ if (simulatedTimer) clearInterval(simulatedTimer);
237
+ const info: UpdateManifestInfo = {
238
+ version: mockInfo?.version || "v1.2.0",
239
+ currentVersion: mockInfo?.currentVersion || options.currentVersion || "v1.0.0",
240
+ date: mockInfo?.date || new Date().toISOString().split("T")[0],
241
+ body:
242
+ mockInfo?.body ||
243
+ "### What's New in v1.2.0\n- Added native Window Titlebar tabs\n- Enhanced Tauri v2 capability security\n- Optimized SolidJS signal reactivity\n- Fixed titlebar drag region jitter on Linux",
244
+ };
245
+ setUpdateInfo(info);
246
+ setStatus("available");
247
+ setError(null);
248
+ setProgress({ downloaded: 0, total: 100, percentage: 0 });
249
+ options.onUpdateAvailable?.(info);
250
+ };
251
+
252
+ onMount(() => {
253
+ if (options.autoCheck) {
254
+ checkForUpdates();
255
+ }
256
+ });
257
+
258
+ const isLoading = () => status() === "checking" || status() === "downloading";
259
+
260
+ return {
261
+ status,
262
+ updateInfo,
263
+ progress,
264
+ error,
265
+ isLoading,
266
+ checkForUpdates,
267
+ downloadAndInstall,
268
+ relaunch,
269
+ dismiss,
270
+ simulateUpdate,
271
+ };
272
+ }
@@ -0,0 +1,444 @@
1
+ import { createSignal, createEffect, onCleanup, type Accessor } from "solid-js";
2
+ import { createControllableSignal } from "./create-controllable-signal";
3
+
4
+ export interface CreateAudioOptions {
5
+ /** Controlled playing state. */
6
+ playing?: boolean | Accessor<boolean | undefined>;
7
+ /** Uncontrolled default playing state. Defaults to false. */
8
+ defaultPlaying?: boolean;
9
+ /** Controlled muted state. */
10
+ muted?: boolean | Accessor<boolean | undefined>;
11
+ /** Uncontrolled default muted state. Defaults to false. */
12
+ defaultMuted?: boolean;
13
+ /** Initial volume level between 0.0 and 1.0. Defaults to 1.0. */
14
+ volume?: number;
15
+ /** Whether the audio should loop upon finishing. Defaults to false. */
16
+ loop?: boolean;
17
+ /** Whether the audio should start playing automatically. Defaults to false. */
18
+ autoplay?: boolean;
19
+ /** Playback speed rate. Defaults to 1.0. */
20
+ playbackRate?: number;
21
+ /** Callback fired when playing state changes. */
22
+ onPlayingChange?: (playing: boolean) => void;
23
+ /** Callback fired when muted state changes. */
24
+ onMutedChange?: (muted: boolean) => void;
25
+ /** Callback fired when audio finishes playing. */
26
+ onEnded?: () => void;
27
+ /** Callback fired when audio playback encounters an error. */
28
+ onError?: (err: Event) => void;
29
+ }
30
+
31
+ export interface CreateAudioReturn {
32
+ /** Signal indicating if audio is currently playing. */
33
+ isPlaying: Accessor<boolean>;
34
+ /** Signal indicating current playback time in seconds. */
35
+ currentTime: Accessor<number>;
36
+ /** Signal indicating total duration in seconds. */
37
+ duration: Accessor<number>;
38
+ /** Signal indicating volume level (0.0 to 1.0). */
39
+ volume: Accessor<number>;
40
+ /** Signal indicating if audio is muted. */
41
+ isMuted: Accessor<boolean>;
42
+ /** Signal indicating if audio source is loaded and ready. */
43
+ isReady: Accessor<boolean>;
44
+ /** Play audio. */
45
+ play: () => Promise<void>;
46
+ /** Pause audio. */
47
+ pause: () => void;
48
+ /** Toggle play/pause state. */
49
+ toggle: () => void;
50
+ /** Seek to specified time in seconds. */
51
+ seek: (time: number) => void;
52
+ /** Set volume level between 0.0 and 1.0. */
53
+ setVolume: (vol: number) => void;
54
+ /** Toggle audio mute status. */
55
+ toggleMute: () => void;
56
+ }
57
+
58
+ /**
59
+ * SolidJS reactive primitive for controlling audio playback state with controlled/uncontrolled signal support.
60
+ */
61
+ export function createAudio(
62
+ src: string | Accessor<string>,
63
+ options: CreateAudioOptions = {}
64
+ ): CreateAudioReturn {
65
+ const playingAccessor = (): boolean | undefined => {
66
+ if (typeof options.playing === "function") {
67
+ return options.playing();
68
+ }
69
+ return options.playing;
70
+ };
71
+
72
+ const mutedAccessor = (): boolean | undefined => {
73
+ if (typeof options.muted === "function") {
74
+ return options.muted();
75
+ }
76
+ return options.muted;
77
+ };
78
+
79
+ const [isPlayingVal, setIsPlayingVal] = createControllableSignal<boolean>({
80
+ value: playingAccessor,
81
+ defaultValue: options.defaultPlaying ?? false,
82
+ onChange: options.onPlayingChange,
83
+ });
84
+
85
+ const [isMutedVal, setIsMutedVal] = createControllableSignal<boolean>({
86
+ value: mutedAccessor,
87
+ defaultValue: options.defaultMuted ?? false,
88
+ onChange: options.onMutedChange,
89
+ });
90
+
91
+ const [audioEl, setAudioEl] = createSignal<HTMLAudioElement | null>(null);
92
+ const [currentTime, setCurrentTime] = createSignal(0);
93
+ const [duration, setDuration] = createSignal(0);
94
+ const [volume, setVolumeSignal] = createSignal(options.volume ?? 1.0);
95
+ const [isReady, setIsReady] = createSignal(false);
96
+
97
+ const isPlaying = (): boolean => Boolean(isPlayingVal());
98
+ const isMuted = (): boolean => Boolean(isMutedVal());
99
+
100
+ const getSrc = (): string => {
101
+ return typeof src === "function" ? src() : src;
102
+ };
103
+
104
+ /* Initialize Audio instance */
105
+ createEffect(() => {
106
+ if (typeof window === "undefined") return;
107
+
108
+ const audio = new Audio(getSrc());
109
+ setAudioEl(audio);
110
+
111
+ const handleLoadedMetadata = (): void => {
112
+ setDuration(audio.duration || 0);
113
+ setIsReady(true);
114
+ };
115
+
116
+ const handleTimeUpdate = (): void => {
117
+ setCurrentTime(audio.currentTime || 0);
118
+ };
119
+
120
+ const handlePlay = (): void => setIsPlayingVal(true);
121
+ const handlePause = (): void => setIsPlayingVal(false);
122
+ const handleEnded = (): void => {
123
+ setIsPlayingVal(false);
124
+ options.onEnded?.();
125
+ };
126
+
127
+ const handleError = (e: Event): void => {
128
+ setIsReady(false);
129
+ options.onError?.(e);
130
+ };
131
+
132
+ audio.addEventListener("loadedmetadata", handleLoadedMetadata);
133
+ audio.addEventListener("timeupdate", handleTimeUpdate);
134
+ audio.addEventListener("play", handlePlay);
135
+ audio.addEventListener("pause", handlePause);
136
+ audio.addEventListener("ended", handleEnded);
137
+ audio.addEventListener("error", handleError);
138
+
139
+ onCleanup(() => {
140
+ audio.pause();
141
+ audio.removeEventListener("loadedmetadata", handleLoadedMetadata);
142
+ audio.removeEventListener("timeupdate", handleTimeUpdate);
143
+ audio.removeEventListener("play", handlePlay);
144
+ audio.removeEventListener("pause", handlePause);
145
+ audio.removeEventListener("ended", handleEnded);
146
+ audio.removeEventListener("error", handleError);
147
+ setAudioEl(null);
148
+ });
149
+ });
150
+
151
+ /* Sync properties with audio element */
152
+ createEffect(() => {
153
+ const audio = audioEl();
154
+ if (!audio) return;
155
+
156
+ audio.volume = volume();
157
+ audio.muted = isMuted();
158
+ audio.loop = options.loop ?? false;
159
+ audio.autoplay = options.autoplay ?? false;
160
+ if (options.playbackRate) {
161
+ audio.playbackRate = options.playbackRate;
162
+ }
163
+ });
164
+
165
+ /* Sync controlled playing state with HTMLAudioElement */
166
+ createEffect(() => {
167
+ const audio = audioEl();
168
+ const shouldPlay = isPlaying();
169
+ if (!audio) return;
170
+ if (shouldPlay && audio.paused) {
171
+ audio.play().catch(() => setIsPlayingVal(false));
172
+ } else if (!shouldPlay && !audio.paused) {
173
+ audio.pause();
174
+ }
175
+ });
176
+
177
+ const play = async (): Promise<void> => {
178
+ setIsPlayingVal(true);
179
+ const audio = audioEl();
180
+ if (audio) await audio.play();
181
+ };
182
+
183
+ const pause = (): void => {
184
+ setIsPlayingVal(false);
185
+ const audio = audioEl();
186
+ if (audio) audio.pause();
187
+ };
188
+
189
+ const toggle = (): void => {
190
+ if (isPlaying()) {
191
+ pause();
192
+ } else {
193
+ play();
194
+ }
195
+ };
196
+
197
+ const seek = (time: number): void => {
198
+ const audio = audioEl();
199
+ if (audio) {
200
+ audio.currentTime = Math.max(0, Math.min(time, duration()));
201
+ setCurrentTime(audio.currentTime);
202
+ }
203
+ };
204
+
205
+ const setVolume = (vol: number): void => {
206
+ const clamped = Math.max(0, Math.min(vol, 1.0));
207
+ setVolumeSignal(clamped);
208
+ const audio = audioEl();
209
+ if (audio) {
210
+ audio.volume = clamped;
211
+ }
212
+ };
213
+
214
+ const toggleMute = (): void => {
215
+ const nextMuted = !isMuted();
216
+ setIsMutedVal(nextMuted);
217
+ const audio = audioEl();
218
+ if (audio) {
219
+ audio.muted = nextMuted;
220
+ }
221
+ };
222
+
223
+ return {
224
+ isPlaying,
225
+ currentTime,
226
+ duration,
227
+ volume,
228
+ isMuted,
229
+ isReady,
230
+ play,
231
+ pause,
232
+ toggle,
233
+ seek,
234
+ setVolume,
235
+ toggleMute,
236
+ };
237
+ }
238
+
239
+ export interface CreateVideoOptions {
240
+ /** Controlled playing state. */
241
+ playing?: boolean | Accessor<boolean | undefined>;
242
+ /** Uncontrolled default playing state. Defaults to false. */
243
+ defaultPlaying?: boolean;
244
+ /** Controlled muted state. */
245
+ muted?: boolean | Accessor<boolean | undefined>;
246
+ /** Uncontrolled default muted state. Defaults to false. */
247
+ defaultMuted?: boolean;
248
+ /** Initial volume level between 0.0 and 1.0. Defaults to 1.0. */
249
+ volume?: number;
250
+ /** Whether video should loop upon finishing. Defaults to false. */
251
+ loop?: boolean;
252
+ /** Callback fired when playing state changes. */
253
+ onPlayingChange?: (playing: boolean) => void;
254
+ /** Callback fired when muted state changes. */
255
+ onMutedChange?: (muted: boolean) => void;
256
+ /** Callback fired when video playback finishes. */
257
+ onEnded?: () => void;
258
+ }
259
+
260
+ export interface CreateVideoReturn {
261
+ /** Ref callback function to bind to HTMLVideoElement. */
262
+ setVideoRef: (el: HTMLVideoElement | null) => void;
263
+ /** Signal indicating if video is playing. */
264
+ isPlaying: Accessor<boolean>;
265
+ /** Signal indicating current playback time in seconds. */
266
+ currentTime: Accessor<number>;
267
+ /** Signal indicating total video duration in seconds. */
268
+ duration: Accessor<number>;
269
+ /** Signal indicating volume level (0.0 to 1.0). */
270
+ volume: Accessor<number>;
271
+ /** Signal indicating if video is muted. */
272
+ isMuted: Accessor<boolean>;
273
+ /** Play video. */
274
+ play: () => Promise<void>;
275
+ /** Pause video. */
276
+ pause: () => void;
277
+ /** Toggle play/pause. */
278
+ toggle: () => void;
279
+ /** Seek to time position. */
280
+ seek: (time: number) => void;
281
+ /** Set volume level. */
282
+ setVolume: (vol: number) => void;
283
+ /** Toggle mute status. */
284
+ toggleMute: () => void;
285
+ }
286
+
287
+ /**
288
+ * SolidJS reactive primitive for controlling media element video playback with controlled/uncontrolled signal support.
289
+ */
290
+ export function createVideo(
291
+ options: CreateVideoOptions = {}
292
+ ): CreateVideoReturn {
293
+ const [videoEl, setVideoEl] = createSignal<HTMLVideoElement | null>(null);
294
+
295
+ const playingAccessor = (): boolean | undefined => {
296
+ if (typeof options.playing === "function") {
297
+ return options.playing();
298
+ }
299
+ return options.playing;
300
+ };
301
+
302
+ const mutedAccessor = (): boolean | undefined => {
303
+ if (typeof options.muted === "function") {
304
+ return options.muted();
305
+ }
306
+ return options.muted;
307
+ };
308
+
309
+ const [isPlayingVal, setIsPlayingVal] = createControllableSignal<boolean>({
310
+ value: playingAccessor,
311
+ defaultValue: options.defaultPlaying ?? false,
312
+ onChange: options.onPlayingChange,
313
+ });
314
+
315
+ const [isMutedVal, setIsMutedVal] = createControllableSignal<boolean>({
316
+ value: mutedAccessor,
317
+ defaultValue: options.defaultMuted ?? false,
318
+ onChange: options.onMutedChange,
319
+ });
320
+
321
+ const [currentTime, setCurrentTime] = createSignal(0);
322
+ const [duration, setDuration] = createSignal(0);
323
+ const [volume, setVolumeSignal] = createSignal(options.volume ?? 1.0);
324
+
325
+ const isPlaying = (): boolean => Boolean(isPlayingVal());
326
+ const isMuted = (): boolean => Boolean(isMutedVal());
327
+
328
+ createEffect(() => {
329
+ const el = videoEl();
330
+ if (!el) return;
331
+
332
+ el.volume = volume();
333
+ el.muted = isMuted();
334
+ el.loop = options.loop ?? false;
335
+
336
+ const handleLoadedMetadata = (): void => {
337
+ setDuration(el.duration || 0);
338
+ };
339
+ const handleTimeUpdate = (): void => {
340
+ setCurrentTime(el.currentTime || 0);
341
+ };
342
+ const handlePlay = (): void => setIsPlayingVal(true);
343
+ const handlePause = (): void => setIsPlayingVal(false);
344
+ const handleEnded = (): void => {
345
+ setIsPlayingVal(false);
346
+ options.onEnded?.();
347
+ };
348
+
349
+ el.addEventListener("loadedmetadata", handleLoadedMetadata);
350
+ el.addEventListener("timeupdate", handleTimeUpdate);
351
+ el.addEventListener("play", handlePlay);
352
+ el.addEventListener("pause", handlePause);
353
+ el.addEventListener("ended", handleEnded);
354
+
355
+ onCleanup(() => {
356
+ el.removeEventListener("loadedmetadata", handleLoadedMetadata);
357
+ el.removeEventListener("timeupdate", handleTimeUpdate);
358
+ el.removeEventListener("play", handlePlay);
359
+ el.removeEventListener("pause", handlePause);
360
+ el.removeEventListener("ended", handleEnded);
361
+ });
362
+ });
363
+
364
+ /* Sync controlled playing state with video HTML element */
365
+ createEffect(() => {
366
+ const el = videoEl();
367
+ const shouldPlay = isPlaying();
368
+ if (!el) return;
369
+ if (shouldPlay && el.paused) {
370
+ el.play().catch(() => setIsPlayingVal(false));
371
+ } else if (!shouldPlay && !el.paused) {
372
+ el.pause();
373
+ }
374
+ });
375
+
376
+ /* Sync controlled muted state with video HTML element */
377
+ createEffect(() => {
378
+ const el = videoEl();
379
+ if (el) {
380
+ el.muted = isMuted();
381
+ }
382
+ });
383
+
384
+ const play = async (): Promise<void> => {
385
+ setIsPlayingVal(true);
386
+ const el = videoEl();
387
+ if (el) await el.play();
388
+ };
389
+
390
+ const pause = (): void => {
391
+ setIsPlayingVal(false);
392
+ const el = videoEl();
393
+ if (el) el.pause();
394
+ };
395
+
396
+ const toggle = (): void => {
397
+ if (isPlaying()) {
398
+ pause();
399
+ } else {
400
+ play();
401
+ }
402
+ };
403
+
404
+ const seek = (time: number): void => {
405
+ const el = videoEl();
406
+ if (el) {
407
+ el.currentTime = Math.max(0, Math.min(time, duration()));
408
+ setCurrentTime(el.currentTime);
409
+ }
410
+ };
411
+
412
+ const setVolume = (vol: number): void => {
413
+ const clamped = Math.max(0, Math.min(vol, 1.0));
414
+ setVolumeSignal(clamped);
415
+ const el = videoEl();
416
+ if (el) {
417
+ el.volume = clamped;
418
+ }
419
+ };
420
+
421
+ const toggleMute = (): void => {
422
+ const nextMuted = !isMuted();
423
+ setIsMutedVal(nextMuted);
424
+ const el = videoEl();
425
+ if (el) {
426
+ el.muted = nextMuted;
427
+ }
428
+ };
429
+
430
+ return {
431
+ setVideoRef: setVideoEl,
432
+ isPlaying,
433
+ currentTime,
434
+ duration,
435
+ volume,
436
+ isMuted,
437
+ play,
438
+ pause,
439
+ toggle,
440
+ seek,
441
+ setVolume,
442
+ toggleMute,
443
+ };
444
+ }