@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,465 @@
1
+ import {
2
+ createSignal,
3
+ splitProps,
4
+ Show,
5
+ For,
6
+ onCleanup,
7
+ createEffect,
8
+ type Component,
9
+ type ComponentProps,
10
+ } from "solid-js";
11
+ import { useRichTextEditor } from "./editor.js";
12
+ import { EditorTableControls } from "./table-controls.js";
13
+ import { cn } from "@/lib/cn";
14
+ import {
15
+ Bold,
16
+ Italic,
17
+ Underline as UnderlineIcon,
18
+ Strikethrough,
19
+ Code,
20
+ Type,
21
+ Heading1,
22
+ Heading2,
23
+ Heading3,
24
+ List,
25
+ ListOrdered,
26
+ ListTodo,
27
+ Quote,
28
+ Table as TableIcon,
29
+ Link as LinkIcon,
30
+ Unlink,
31
+ Image as ImageIcon,
32
+ Undo,
33
+ Redo,
34
+ Maximize2,
35
+ Minimize2,
36
+ AlignLeft,
37
+ AlignCenter,
38
+ AlignRight,
39
+ Highlighter,
40
+ Sparkles,
41
+ RemoveFormatting,
42
+ FileCode2,
43
+ Eye,
44
+ ChevronDown,
45
+ } from "lucide-solid";
46
+
47
+ export const HIGHLIGHT_PALETTE = [
48
+ { name: "Yellow", value: "#eab308" },
49
+ { name: "Amber", value: "#f59e0b" },
50
+ { name: "Orange", value: "#f97316" },
51
+ { name: "Red", value: "#ef4444" },
52
+ { name: "Rose", value: "#f43f5e" },
53
+ { name: "Pink", value: "#ec4899" },
54
+ { name: "Purple", value: "#a855f7" },
55
+ { name: "Violet", value: "#8b5cf6" },
56
+ { name: "Indigo", value: "#6366f1" },
57
+ { name: "Blue", value: "#3b82f6" },
58
+ { name: "Cyan", value: "#06b6d4" },
59
+ { name: "Teal", value: "#14b8a6" },
60
+ { name: "Emerald", value: "#10b981" },
61
+ { name: "Green", value: "#22c55e" },
62
+ { name: "Lime", value: "#84cc16" },
63
+ ];
64
+
65
+ export interface ToolbarButtonProps extends ComponentProps<"button"> {
66
+ isActive?: boolean;
67
+ tooltip?: string;
68
+ }
69
+
70
+ export const ToolbarButton: Component<ToolbarButtonProps> = (props) => {
71
+ const [local, others] = splitProps(props, ["class", "isActive", "tooltip", "children"]);
72
+
73
+ return (
74
+ <button
75
+ type="button"
76
+ title={local.tooltip}
77
+ class={cn(
78
+ "inline-flex items-center justify-center h-8 w-8 rounded-md text-xs font-medium transition-colors cursor-pointer shrink-0 select-none",
79
+ "text-muted-foreground hover:bg-muted hover:text-foreground",
80
+ "focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring",
81
+ local.isActive &&
82
+ "bg-primary text-primary-foreground font-semibold shadow-xs hover:bg-primary/90 hover:text-primary-foreground",
83
+ local.class
84
+ )}
85
+ {...others}
86
+ >
87
+ {local.children}
88
+ </button>
89
+ );
90
+ };
91
+
92
+ export const EditorToolbar: Component<ComponentProps<"div">> = (props) => {
93
+ const [local, others] = splitProps(props, ["class"]);
94
+ const {
95
+ actions,
96
+ isFullscreen,
97
+ toggleFullscreen,
98
+ viewMode,
99
+ toggleViewMode,
100
+ setShowLinkDialog,
101
+ setShowImageDialog,
102
+ setShowTableMenu,
103
+ } = useRichTextEditor();
104
+
105
+ const [showTypography, setShowTypography] = createSignal(false);
106
+ const [showAlign, setShowAlign] = createSignal(false);
107
+ const [showHighlightPalette, setShowHighlightPalette] = createSignal(false);
108
+
109
+ // Close menus on outside click
110
+ createEffect(() => {
111
+ if (typeof window === "undefined") return;
112
+ const handleClickOutside = (e: MouseEvent) => {
113
+ const target = e.target as HTMLElement;
114
+ if (!target.closest(".editor-popover-trigger") && !target.closest(".editor-popover-content")) {
115
+ setShowTypography(false);
116
+ setShowAlign(false);
117
+ setShowHighlightPalette(false);
118
+ }
119
+ };
120
+ document.addEventListener("click", handleClickOutside);
121
+ onCleanup(() => document.removeEventListener("click", handleClickOutside));
122
+ });
123
+
124
+ const currentTypographyLabel = () => {
125
+ if (actions.isActive("heading", { level: 1 })) return "H1";
126
+ if (actions.isActive("heading", { level: 2 })) return "H2";
127
+ if (actions.isActive("heading", { level: 3 })) return "H3";
128
+ return "Normal";
129
+ };
130
+
131
+ const CurrentAlignIcon = () => {
132
+ if (actions.isActive({ textAlign: "center" })) return AlignCenter;
133
+ if (actions.isActive({ textAlign: "right" })) return AlignRight;
134
+ return AlignLeft;
135
+ };
136
+
137
+ const isEditable = () => actions.editor()?.isEditable ?? true;
138
+
139
+ return (
140
+ <div
141
+ class={cn(
142
+ "sticky top-0 z-10 flex flex-wrap items-center gap-1 border-b border-border bg-card/95 backdrop-blur-xs p-1.5 rounded-t-lg",
143
+ local.class
144
+ )}
145
+ {...others}
146
+ >
147
+ {/* Editing Controls Group (Disabled in Read-Only Mode) */}
148
+ <div
149
+ class="flex flex-wrap items-center gap-1"
150
+ classList={{
151
+ "opacity-40 pointer-events-none select-none": !isEditable(),
152
+ }}
153
+ >
154
+ {/* 1. History (Undo / Redo) */}
155
+ <div class="flex items-center gap-0.5 pr-1 border-r border-border shrink-0">
156
+ <ToolbarButton onClick={actions.undo} disabled={!isEditable() || !actions.canUndo()} tooltip="Undo (Ctrl+Z)">
157
+ <Undo class="h-4 w-4" />
158
+ </ToolbarButton>
159
+ <ToolbarButton onClick={actions.redo} disabled={!isEditable() || !actions.canRedo()} tooltip="Redo (Ctrl+Y)">
160
+ <Redo class="h-4 w-4" />
161
+ </ToolbarButton>
162
+ </div>
163
+
164
+ {/* 2. Compact Typography Dropdown */}
165
+ <div class="relative shrink-0 editor-popover-trigger">
166
+ <button
167
+ type="button"
168
+ onClick={() => setShowTypography((p) => !p)}
169
+ class="inline-flex items-center gap-1 h-8 px-2 rounded-md text-xs font-medium text-foreground bg-muted/50 hover:bg-muted transition-colors cursor-pointer border border-border/40"
170
+ title="Typography"
171
+ >
172
+ <Type class="h-3.5 w-3.5 text-muted-foreground" />
173
+ <span class="font-semibold text-xs min-w-[44px] text-left">{currentTypographyLabel()}</span>
174
+ <ChevronDown class="h-3 w-3 text-muted-foreground" />
175
+ </button>
176
+
177
+ <Show when={showTypography()}>
178
+ <div class="absolute top-full left-0 mt-1 z-30 flex flex-col gap-0.5 p-1 bg-popover text-popover-foreground border border-border rounded-lg shadow-xl min-w-[140px] editor-popover-content animate-in fade-in zoom-in-95">
179
+ <button
180
+ type="button"
181
+ class={cn(
182
+ "flex items-center gap-2 px-2.5 py-1.5 rounded-md text-xs text-left cursor-pointer hover:bg-muted transition-colors",
183
+ !actions.isActive("heading") && "bg-primary text-primary-foreground font-semibold hover:bg-primary"
184
+ )}
185
+ onClick={() => {
186
+ actions.setParagraph();
187
+ setShowTypography(false);
188
+ }}
189
+ >
190
+ <Type class="h-3.5 w-3.5" />
191
+ <span>Normal text</span>
192
+ </button>
193
+ <button
194
+ type="button"
195
+ class={cn(
196
+ "flex items-center gap-2 px-2.5 py-1.5 rounded-md text-xs text-left cursor-pointer hover:bg-muted transition-colors",
197
+ actions.isActive("heading", { level: 1 }) && "bg-primary text-primary-foreground font-semibold hover:bg-primary"
198
+ )}
199
+ onClick={() => {
200
+ actions.setHeading(1);
201
+ setShowTypography(false);
202
+ }}
203
+ >
204
+ <Heading1 class="h-3.5 w-3.5" />
205
+ <span class="font-bold">Heading 1</span>
206
+ </button>
207
+ <button
208
+ type="button"
209
+ class={cn(
210
+ "flex items-center gap-2 px-2.5 py-1.5 rounded-md text-xs text-left cursor-pointer hover:bg-muted transition-colors",
211
+ actions.isActive("heading", { level: 2 }) && "bg-primary text-primary-foreground font-semibold hover:bg-primary"
212
+ )}
213
+ onClick={() => {
214
+ actions.setHeading(2);
215
+ setShowTypography(false);
216
+ }}
217
+ >
218
+ <Heading2 class="h-3.5 w-3.5" />
219
+ <span class="font-semibold">Heading 2</span>
220
+ </button>
221
+ <button
222
+ type="button"
223
+ class={cn(
224
+ "flex items-center gap-2 px-2.5 py-1.5 rounded-md text-xs text-left cursor-pointer hover:bg-muted transition-colors",
225
+ actions.isActive("heading", { level: 3 }) && "bg-primary text-primary-foreground font-semibold hover:bg-primary"
226
+ )}
227
+ onClick={() => {
228
+ actions.setHeading(3);
229
+ setShowTypography(false);
230
+ }}
231
+ >
232
+ <Heading3 class="h-3.5 w-3.5" />
233
+ <span class="font-medium">Heading 3</span>
234
+ </button>
235
+ </div>
236
+ </Show>
237
+ </div>
238
+
239
+ {/* 3. Inline Marks (Bold, Italic, Underline, Strike, Code, Highlight) */}
240
+ <div class="flex items-center gap-0.5 px-1 border-r border-border shrink-0">
241
+ <ToolbarButton onClick={actions.toggleBold} isActive={actions.isActive("bold")} tooltip="Bold (Ctrl+B)">
242
+ <Bold class="h-4 w-4" />
243
+ </ToolbarButton>
244
+ <ToolbarButton onClick={actions.toggleItalic} isActive={actions.isActive("italic")} tooltip="Italic (Ctrl+I)">
245
+ <Italic class="h-4 w-4" />
246
+ </ToolbarButton>
247
+ <ToolbarButton
248
+ onClick={actions.toggleUnderline}
249
+ isActive={actions.isActive("underline")}
250
+ tooltip="Underline (Ctrl+U)"
251
+ >
252
+ <UnderlineIcon class="h-4 w-4" />
253
+ </ToolbarButton>
254
+ <ToolbarButton onClick={actions.toggleStrike} isActive={actions.isActive("strike")} tooltip="Strikethrough">
255
+ <Strikethrough class="h-4 w-4" />
256
+ </ToolbarButton>
257
+ <ToolbarButton onClick={actions.toggleCode} isActive={actions.isActive("code")} tooltip="Inline Code">
258
+ <Code class="h-4 w-4" />
259
+ </ToolbarButton>
260
+
261
+ {/* Highlighter Color Palette */}
262
+ <div class="relative shrink-0 editor-popover-trigger">
263
+ <ToolbarButton
264
+ onClick={() => setShowHighlightPalette((p) => !p)}
265
+ isActive={actions.isActive("highlight")}
266
+ tooltip="Highlight Color"
267
+ >
268
+ <Highlighter class="h-4 w-4" />
269
+ </ToolbarButton>
270
+
271
+ <Show when={showHighlightPalette()}>
272
+ <div class="absolute top-full left-0 mt-1 z-30 flex flex-col gap-1.5 p-2 bg-popover text-popover-foreground border border-border rounded-lg shadow-xl min-w-[200px] editor-popover-content animate-in fade-in zoom-in-95">
273
+ <div class="text-[10px] font-semibold text-muted-foreground uppercase tracking-wider">
274
+ Tailwind Highlight Colors
275
+ </div>
276
+ <div class="grid grid-cols-5 gap-1.5">
277
+ <For each={HIGHLIGHT_PALETTE}>
278
+ {(color) => (
279
+ <button
280
+ type="button"
281
+ title={color.name}
282
+ class="h-6 w-6 rounded-md border border-border/60 hover:scale-110 transition-transform cursor-pointer shadow-2xs"
283
+ style={{ "background-color": color.value }}
284
+ onClick={() => {
285
+ actions.toggleHighlight(color.value);
286
+ setShowHighlightPalette(false);
287
+ }}
288
+ />
289
+ )}
290
+ </For>
291
+ </div>
292
+ <button
293
+ type="button"
294
+ class="w-full text-center py-1 mt-1 text-xs rounded-md bg-muted hover:bg-muted/80 text-foreground transition-colors cursor-pointer font-medium"
295
+ onClick={() => {
296
+ actions.toggleHighlight();
297
+ setShowHighlightPalette(false);
298
+ }}
299
+ >
300
+ Clear Highlight
301
+ </button>
302
+ </div>
303
+ </Show>
304
+ </div>
305
+ </div>
306
+
307
+ {/* 4. Compact Alignment Dropdown */}
308
+ <div class="relative shrink-0 editor-popover-trigger">
309
+ <button
310
+ type="button"
311
+ onClick={() => setShowAlign((p) => !p)}
312
+ class="inline-flex items-center justify-center h-8 w-8 rounded-md text-xs font-medium text-muted-foreground hover:bg-muted hover:text-foreground transition-colors cursor-pointer"
313
+ title="Text Alignment"
314
+ >
315
+ {(() => {
316
+ const Icon = CurrentAlignIcon();
317
+ return <Icon class="h-4 w-4" />;
318
+ })()}
319
+ </button>
320
+
321
+ <Show when={showAlign()}>
322
+ <div class="absolute top-full left-0 mt-1 z-30 flex items-center gap-0.5 p-1 bg-popover text-popover-foreground border border-border rounded-lg shadow-xl editor-popover-content animate-in fade-in zoom-in-95">
323
+ <ToolbarButton
324
+ onClick={() => {
325
+ actions.setTextAlign("left");
326
+ setShowAlign(false);
327
+ }}
328
+ isActive={actions.isActive({ textAlign: "left" })}
329
+ tooltip="Align Left"
330
+ >
331
+ <AlignLeft class="h-4 w-4" />
332
+ </ToolbarButton>
333
+ <ToolbarButton
334
+ onClick={() => {
335
+ actions.setTextAlign("center");
336
+ setShowAlign(false);
337
+ }}
338
+ isActive={actions.isActive({ textAlign: "center" })}
339
+ tooltip="Align Center"
340
+ >
341
+ <AlignCenter class="h-4 w-4" />
342
+ </ToolbarButton>
343
+ <ToolbarButton
344
+ onClick={() => {
345
+ actions.setTextAlign("right");
346
+ setShowAlign(false);
347
+ }}
348
+ isActive={actions.isActive({ textAlign: "right" })}
349
+ tooltip="Align Right"
350
+ >
351
+ <AlignRight class="h-4 w-4" />
352
+ </ToolbarButton>
353
+ </div>
354
+ </Show>
355
+ </div>
356
+
357
+ {/* 5. Lists & Blocks */}
358
+ <div class="flex items-center gap-0.5 px-1 border-r border-border shrink-0">
359
+ <ToolbarButton
360
+ onClick={actions.toggleBulletList}
361
+ isActive={actions.isActive("bulletList")}
362
+ tooltip="Bullet List"
363
+ >
364
+ <List class="h-4 w-4" />
365
+ </ToolbarButton>
366
+ <ToolbarButton
367
+ onClick={actions.toggleOrderedList}
368
+ isActive={actions.isActive("orderedList")}
369
+ tooltip="Numbered List"
370
+ >
371
+ <ListOrdered class="h-4 w-4" />
372
+ </ToolbarButton>
373
+ <ToolbarButton onClick={actions.toggleTaskList} isActive={actions.isActive("taskList")} tooltip="Task Checklist">
374
+ <ListTodo class="h-4 w-4" />
375
+ </ToolbarButton>
376
+ <ToolbarButton
377
+ onClick={actions.toggleBlockquote}
378
+ isActive={actions.isActive("blockquote")}
379
+ tooltip="Blockquote"
380
+ >
381
+ <Quote class="h-4 w-4" />
382
+ </ToolbarButton>
383
+ <ToolbarButton
384
+ onClick={actions.toggleCodeBlock}
385
+ isActive={actions.isActive("codeBlock")}
386
+ tooltip="Code Block"
387
+ >
388
+ <Sparkles class="h-4 w-4" />
389
+ </ToolbarButton>
390
+ </div>
391
+
392
+ {/* 6. Inserts: Link, Image, Table */}
393
+ <div class="flex items-center gap-0.5 px-1 shrink-0">
394
+ <ToolbarButton
395
+ onClick={() => {
396
+ if (actions.isActive("link")) {
397
+ actions.unsetLink();
398
+ } else {
399
+ setShowLinkDialog(true);
400
+ }
401
+ }}
402
+ isActive={actions.isActive("link")}
403
+ tooltip={actions.isActive("link") ? "Remove Link" : "Insert Link"}
404
+ >
405
+ <Show when={actions.isActive("link")} fallback={<LinkIcon class="h-4 w-4" />}>
406
+ <Unlink class="h-4 w-4" />
407
+ </Show>
408
+ </ToolbarButton>
409
+
410
+ <ToolbarButton onClick={() => setShowImageDialog(true)} tooltip="Insert Image">
411
+ <ImageIcon class="h-4 w-4" />
412
+ </ToolbarButton>
413
+
414
+ <div class="relative shrink-0">
415
+ <ToolbarButton
416
+ onClick={() => setShowTableMenu((prev) => !prev)}
417
+ isActive={actions.isActive("table")}
418
+ tooltip="Table Controls"
419
+ >
420
+ <TableIcon class="h-4 w-4" />
421
+ </ToolbarButton>
422
+
423
+ <EditorTableControls />
424
+ </div>
425
+ </div>
426
+ </div>
427
+
428
+ {/* 7. Markdown Toggle, Clear Formatting, Fullscreen */}
429
+ <div class="flex items-center gap-1 border-l border-border pl-1.5 shrink-0 ml-auto">
430
+ <ToolbarButton
431
+ onClick={toggleViewMode}
432
+ isActive={viewMode() === "markdown"}
433
+ tooltip={viewMode() === "markdown" ? "Switch to Visual Editor" : "Switch to Markdown Mode"}
434
+ >
435
+ <Show when={viewMode() === "markdown"} fallback={<FileCode2 class="h-4 w-4" />}>
436
+ <Eye class="h-4 w-4" />
437
+ </Show>
438
+ </ToolbarButton>
439
+
440
+ <ToolbarButton onClick={actions.clearContent} disabled={!isEditable()} tooltip="Clear All Content">
441
+ <RemoveFormatting class="h-4 w-4" />
442
+ </ToolbarButton>
443
+
444
+ <Show
445
+ when={isFullscreen()}
446
+ fallback={
447
+ <ToolbarButton onClick={toggleFullscreen} tooltip="Fullscreen Mode">
448
+ <Maximize2 class="h-4 w-4" />
449
+ </ToolbarButton>
450
+ }
451
+ >
452
+ <button
453
+ type="button"
454
+ onClick={toggleFullscreen}
455
+ class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md text-xs font-semibold bg-primary text-primary-foreground hover:bg-primary/90 transition-colors cursor-pointer shadow-xs ml-0.5 shrink-0"
456
+ title="Exit Fullscreen (Esc)"
457
+ >
458
+ <Minimize2 class="h-3.5 w-3.5" />
459
+ <span>Exit Fullscreen</span>
460
+ </button>
461
+ </Show>
462
+ </div>
463
+ </div>
464
+ );
465
+ };
@@ -0,0 +1,231 @@
1
+ import {
2
+ createSignal,
3
+ onMount,
4
+ onCleanup,
5
+ type Accessor,
6
+ } from "solid-js";
7
+ import { Editor, type EditorOptions, type Extension } from "@tiptap/core";
8
+ import { getDefaultExtensions } from "./extensions.js";
9
+
10
+ export interface UseEditorOptions extends Partial<Omit<EditorOptions, "element">> {
11
+ placeholder?: string;
12
+ characterLimit?: number;
13
+ }
14
+
15
+ export interface UseEditorReturn {
16
+ editor: Accessor<Editor | null>;
17
+ html: Accessor<string>;
18
+ text: Accessor<string>;
19
+ markdown: Accessor<string>;
20
+ isEmpty: Accessor<boolean>;
21
+ characterCount: Accessor<number>;
22
+ wordCount: Accessor<number>;
23
+ canUndo: Accessor<boolean>;
24
+ canRedo: Accessor<boolean>;
25
+ mount: (element: HTMLElement) => void;
26
+ destroy: () => void;
27
+ isActive: (name: string | Record<string, any>, attributes?: Record<string, any>) => boolean;
28
+ toggleBold: () => void;
29
+ toggleItalic: () => void;
30
+ toggleUnderline: () => void;
31
+ toggleStrike: () => void;
32
+ toggleCode: () => void;
33
+ toggleHighlight: (color?: string) => void;
34
+ setHeading: (level: 1 | 2 | 3 | 4 | 5 | 6) => void;
35
+ setParagraph: () => void;
36
+ toggleBulletList: () => void;
37
+ toggleOrderedList: () => void;
38
+ toggleTaskList: () => void;
39
+ toggleBlockquote: () => void;
40
+ toggleCodeBlock: () => void;
41
+ setTextAlign: (alignment: "left" | "center" | "right" | "justify") => void;
42
+ setLink: (options: string | { href: string; target?: string }) => void;
43
+ unsetLink: () => void;
44
+ setImage: (options: string | { src: string; alt?: string; title?: string }) => void;
45
+ insertTable: (options?: { rows?: number; cols?: number; withHeaderRow?: boolean }) => void;
46
+ insertHorizontalRule: () => void;
47
+ clearContent: () => void;
48
+ setContent: (content: string) => void;
49
+ setEditable: (editable: boolean) => void;
50
+ undo: () => void;
51
+ redo: () => void;
52
+ }
53
+
54
+ export function useEditor(options: UseEditorOptions = {}): UseEditorReturn {
55
+ const [editorInstance, setEditorInstance] = createSignal<Editor | null>(null);
56
+ const [html, setHtml] = createSignal<string>("");
57
+ const [text, setText] = createSignal<string>("");
58
+ const [markdown, setMarkdown] = createSignal<string>("");
59
+ const [isEmpty, setIsEmpty] = createSignal<boolean>(true);
60
+ const [characterCount, setCharacterCount] = createSignal<number>(0);
61
+ const [wordCount, setWordCount] = createSignal<number>(0);
62
+ const [canUndo, setCanUndo] = createSignal<boolean>(false);
63
+ const [canRedo, setCanRedo] = createSignal<boolean>(false);
64
+ const [transactionVersion, setTransactionVersion] = createSignal<number>(0);
65
+
66
+ let targetElement: HTMLElement | null = null;
67
+
68
+ const updateStats = (ed: Editor) => {
69
+ const currentHtml = ed.getHTML();
70
+ const currentText = ed.getText();
71
+ const currentMd = (ed.storage as any).markdown?.getMarkdown?.() || "";
72
+ setHtml(currentHtml);
73
+ setText(currentText);
74
+ setMarkdown(currentMd);
75
+ setIsEmpty(ed.isEmpty);
76
+ setCharacterCount(ed.storage.characterCount?.characters?.() ?? currentText.length);
77
+ setWordCount(ed.storage.characterCount?.words?.() ?? currentText.split(/\s+/).filter(Boolean).length);
78
+ setCanUndo(ed.can().undo());
79
+ setCanRedo(ed.can().redo());
80
+ setTransactionVersion((v) => v + 1);
81
+ };
82
+
83
+ const initEditor = (el: HTMLElement) => {
84
+ if (typeof window === "undefined") return;
85
+
86
+ const extensions = [
87
+ ...getDefaultExtensions({
88
+ placeholder: options.placeholder,
89
+ characterLimit: options.characterLimit,
90
+ }),
91
+ ...(options.extensions || []),
92
+ ];
93
+
94
+ const editor = new Editor({
95
+ element: el,
96
+ content: options.content,
97
+ editable: options.editable ?? true,
98
+ autofocus: options.autofocus ?? false,
99
+ extensions,
100
+ editorProps: {
101
+ attributes: {
102
+ class:
103
+ "focus:outline-hidden min-h-[220px] w-full max-w-none text-foreground leading-relaxed text-sm " +
104
+ "[&_h1]:text-3xl [&_h1]:font-bold [&_h1]:tracking-tight [&_h1]:mt-6 [&_h1]:mb-3 " +
105
+ "[&_h2]:text-2xl [&_h2]:font-semibold [&_h2]:tracking-tight [&_h2]:mt-5 [&_h2]:mb-2.5 " +
106
+ "[&_h3]:text-xl [&_h3]:font-semibold [&_h3]:mt-4 [&_h3]:mb-2 " +
107
+ "[&_h4]:text-lg [&_h4]:font-semibold [&_h4]:mt-3 [&_h4]:mb-1.5 " +
108
+ "[&_p]:my-2 [&_p]:leading-7 " +
109
+ "[&_ul]:list-disc [&_ul]:pl-6 [&_ul]:my-3 [&_ul]:space-y-1 " +
110
+ "[&_ol]:list-decimal [&_ol]:pl-6 [&_ol]:my-3 [&_ol]:space-y-1 " +
111
+ "[&_li]:my-0.5 " +
112
+ "[&_ul[data-type=taskList]]:list-none [&_ul[data-type=taskList]]:pl-0 [&_ul[data-type=taskList]]:my-3 [&_ul[data-type=taskList]]:space-y-2 " +
113
+ "[&_ul[data-type=taskList]_li]:flex [&_ul[data-type=taskList]_li]:items-start [&_ul[data-type=taskList]_li]:gap-2.5 " +
114
+ "[&_ul[data-type=taskList]_input[type=checkbox]]:mt-1 [&_ul[data-type=taskList]_input[type=checkbox]]:h-4 [&_ul[data-type=taskList]_input[type=checkbox]]:w-4 [&_ul[data-type=taskList]_input[type=checkbox]]:rounded [&_ul[data-type=taskList]_input[type=checkbox]]:border-border [&_ul[data-type=taskList]_input[type=checkbox]]:accent-primary [&_ul[data-type=taskList]_input[type=checkbox]]:cursor-pointer " +
115
+ "[&_mark]:text-foreground [&_mark]:dark:text-background [&_mark]:font-medium [&_mark]:rounded-xs [&_mark]:px-1 [&_mark]:py-0.5 " +
116
+ "[&_.is-editor-empty:first-child::before]:content-[attr(data-placeholder)] [&_.is-editor-empty:first-child::before]:text-muted-foreground [&_.is-editor-empty:first-child::before]:float-left [&_.is-editor-empty:first-child::before]:pointer-events-none [&_.is-editor-empty:first-child::before]:h-0",
117
+ },
118
+ ...options.editorProps,
119
+ },
120
+ onUpdate: (props) => {
121
+ updateStats(props.editor);
122
+ options.onUpdate?.(props);
123
+ },
124
+ onSelectionUpdate: (props) => {
125
+ updateStats(props.editor);
126
+ options.onSelectionUpdate?.(props);
127
+ },
128
+ onTransaction: (props) => {
129
+ updateStats(props.editor);
130
+ options.onTransaction?.(props);
131
+ },
132
+ onFocus: (args) => options.onFocus?.(args),
133
+ onBlur: (args) => options.onBlur?.(args),
134
+ });
135
+
136
+ setEditorInstance(editor);
137
+ updateStats(editor);
138
+ };
139
+
140
+ const mount = (element: HTMLElement) => {
141
+ targetElement = element;
142
+ initEditor(element);
143
+ };
144
+
145
+ const destroy = () => {
146
+ editorInstance()?.destroy();
147
+ setEditorInstance(null);
148
+ };
149
+
150
+ onCleanup(() => {
151
+ destroy();
152
+ });
153
+
154
+ const isActive = (name: string | Record<string, any>, attributes?: Record<string, any>) => {
155
+ transactionVersion();
156
+ const ed = editorInstance();
157
+ if (!ed) return false;
158
+ if (typeof name === "string") {
159
+ return ed.isActive(name, attributes);
160
+ }
161
+ return ed.isActive(name);
162
+ };
163
+
164
+ return {
165
+ editor: editorInstance,
166
+ html,
167
+ text,
168
+ markdown,
169
+ isEmpty,
170
+ characterCount,
171
+ wordCount,
172
+ canUndo,
173
+ canRedo,
174
+ mount,
175
+ destroy,
176
+ isActive,
177
+ toggleBold: () => editorInstance()?.chain().focus().toggleBold().run(),
178
+ toggleItalic: () => editorInstance()?.chain().focus().toggleItalic().run(),
179
+ toggleUnderline: () => editorInstance()?.chain().focus().toggleUnderline().run(),
180
+ toggleStrike: () => editorInstance()?.chain().focus().toggleStrike().run(),
181
+ toggleCode: () => editorInstance()?.chain().focus().toggleCode().run(),
182
+ toggleHighlight: (color) => {
183
+ const ed = editorInstance();
184
+ if (!ed) return;
185
+ if (color) {
186
+ ed.chain().focus().toggleHighlight({ color }).run();
187
+ } else {
188
+ ed.chain().focus().toggleHighlight().run();
189
+ }
190
+ },
191
+ setHeading: (level) => editorInstance()?.chain().focus().toggleHeading({ level }).run(),
192
+ setParagraph: () => editorInstance()?.chain().focus().setParagraph().run(),
193
+ toggleBulletList: () => editorInstance()?.chain().focus().toggleBulletList().run(),
194
+ toggleOrderedList: () => editorInstance()?.chain().focus().toggleOrderedList().run(),
195
+ toggleTaskList: () => editorInstance()?.chain().focus().toggleTaskList().run(),
196
+ toggleBlockquote: () => editorInstance()?.chain().focus().toggleBlockquote().run(),
197
+ toggleCodeBlock: () => editorInstance()?.chain().focus().toggleCodeBlock().run(),
198
+ setTextAlign: (alignment) => editorInstance()?.chain().focus().setTextAlign(alignment).run(),
199
+ setLink: (opts) => {
200
+ const ed = editorInstance();
201
+ if (!ed) return;
202
+ if (typeof opts === "string") {
203
+ ed.chain().focus().setLink({ href: opts, target: "_blank" }).run();
204
+ } else {
205
+ ed.chain().focus().setLink({ href: opts.href, target: opts.target ?? "_blank" }).run();
206
+ }
207
+ },
208
+ unsetLink: () => editorInstance()?.chain().focus().unsetLink().run(),
209
+ setImage: (opts) => {
210
+ const ed = editorInstance();
211
+ if (!ed) return;
212
+ if (typeof opts === "string") {
213
+ ed.chain().focus().setImage({ src: opts }).run();
214
+ } else {
215
+ ed.chain().focus().setImage(opts).run();
216
+ }
217
+ },
218
+ insertTable: (opts) =>
219
+ editorInstance()?.chain().focus().insertTable({
220
+ rows: opts?.rows ?? 3,
221
+ cols: opts?.cols ?? 3,
222
+ withHeaderRow: opts?.withHeaderRow ?? true,
223
+ }).run(),
224
+ insertHorizontalRule: () => editorInstance()?.chain().focus().setHorizontalRule().run(),
225
+ clearContent: () => editorInstance()?.chain().focus().clearContent().run(),
226
+ setContent: (c) => editorInstance()?.commands.setContent(c),
227
+ setEditable: (editable: boolean) => editorInstance()?.setEditable(editable),
228
+ undo: () => editorInstance()?.chain().focus().undo().run(),
229
+ redo: () => editorInstance()?.chain().focus().redo().run(),
230
+ };
231
+ }