@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,773 @@
1
+ import {
2
+ createContext,
3
+ useContext,
4
+ splitProps,
5
+ createSignal,
6
+ createEffect,
7
+ onMount,
8
+ onCleanup,
9
+ Show,
10
+ For,
11
+ type Component,
12
+ type JSX,
13
+ type ParentComponent,
14
+ type Accessor,
15
+ } from "solid-js";
16
+ import { cva, type VariantProps } from "class-variance-authority";
17
+ import { Plus, X, Pin, XCircle, CircleX } from "lucide-solid";
18
+ import * as ContextMenuPrimitive from "@kobalte/core/context-menu";
19
+ import { Button } from "@/components/ui/button";
20
+ import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
21
+ import {
22
+ type CreateDocumentTabsReturn,
23
+ type TabItem,
24
+ } from "@/hooks/create-document-tabs";
25
+ import { cn } from "@/lib/cn";
26
+
27
+ /* --- 1. Context & Variants --- */
28
+
29
+ export type TitlebarTabsVariant = "editor" | "chrome" | "pills";
30
+
31
+ interface TitlebarTabsContextValue {
32
+ value: Accessor<string | undefined>;
33
+ setValue: (value: string) => void;
34
+ variant: Accessor<TitlebarTabsVariant>;
35
+ manager?: CreateDocumentTabsReturn<any>;
36
+ reorderable?: boolean;
37
+ enableContextMenu?: boolean;
38
+ draggedTabId: Accessor<string | null>;
39
+ dropTargetId: Accessor<string | null>;
40
+ dropPosition: Accessor<"left" | "right" | null>;
41
+ setDragState: (draggedId: string | null, targetId: string | null, position: "left" | "right" | null) => void;
42
+ handleDropReorder: (sourceId: string, targetId: string, position: "left" | "right") => void;
43
+ }
44
+
45
+ const TitlebarTabsContext = createContext<TitlebarTabsContextValue>();
46
+
47
+ export function useTitlebarTabs() {
48
+ const ctx = useContext(TitlebarTabsContext);
49
+ if (!ctx) {
50
+ throw new Error("useTitlebarTabs must be used within a <TitlebarTabs /> container");
51
+ }
52
+ return ctx;
53
+ }
54
+
55
+ export const titlebarTabVariants = cva(
56
+ "group relative inline-flex items-center gap-1.5 px-3 text-xs font-medium select-none cursor-pointer transition-colors shrink-0 max-w-[180px] min-w-[80px]",
57
+ {
58
+ variants: {
59
+ variant: {
60
+ editor:
61
+ "h-full py-1 border-r border-border/40 border-t-2 border-t-transparent hover:bg-muted/40 data-[active=true]:bg-background data-[active=true]:border-t-primary data-[active=true]:text-foreground data-[active=false]:text-muted-foreground",
62
+ chrome:
63
+ "h-[calc(100%-2px)] py-1 rounded-t-lg border-t border-x border-transparent hover:bg-muted/60 data-[active=true]:border-border/70 data-[active=true]:bg-background data-[active=true]:text-foreground data-[active=true]:-mb-px data-[active=true]:shadow-xs data-[active=false]:text-muted-foreground",
64
+ pills:
65
+ "h-7 py-0.5 rounded-md mx-0.5 hover:bg-muted/50 data-[active=true]:bg-primary/10 data-[active=true]:text-primary data-[active=true]:font-semibold data-[active=false]:text-muted-foreground",
66
+ },
67
+ },
68
+ defaultVariants: {
69
+ variant: "editor",
70
+ },
71
+ }
72
+ );
73
+
74
+ /* --- 2. TitlebarTabs Root Container --- */
75
+
76
+ export interface TitlebarTabsProps extends JSX.HTMLAttributes<HTMLElement> {
77
+ /** Reactive tabs manager instance from createDocumentTabs(). */
78
+ manager?: CreateDocumentTabsReturn<any>;
79
+ /** Controlled active tab identifier value (when not using manager). */
80
+ value?: string;
81
+ /** Uncontrolled default active tab identifier value. */
82
+ defaultValue?: string;
83
+ /** Callback triggered when active tab changes. */
84
+ onValueChange?: (value: string) => void;
85
+ /** Callback triggered when the "+" add tab button is clicked. */
86
+ onAddTab?: () => void;
87
+ /** Whether tabs can be reordered via Drag & Drop. Defaults to true when manager is present. */
88
+ reorderable?: boolean;
89
+ /** Whether right-click context menu is enabled on tabs and empty space. Defaults to true. */
90
+ enableContextMenu?: boolean;
91
+ /** Custom render function for the empty tabstrip context menu. */
92
+ renderEmptyContextMenu?: () => JSX.Element;
93
+ /** Visual chrome styling variant. */
94
+ variant?: TitlebarTabsVariant;
95
+ class?: string;
96
+ }
97
+
98
+ export const TitlebarTabs: ParentComponent<TitlebarTabsProps> = (props) => {
99
+ const [local, rest] = splitProps(props, [
100
+ "manager",
101
+ "value",
102
+ "defaultValue",
103
+ "onValueChange",
104
+ "onAddTab",
105
+ "reorderable",
106
+ "enableContextMenu",
107
+ "renderEmptyContextMenu",
108
+ "variant",
109
+ "class",
110
+ "children",
111
+ ]);
112
+
113
+ let scrollContainerRef: HTMLDivElement | undefined;
114
+
115
+ const [internalValue, setInternalValue] = createSignal(local.defaultValue || local.value);
116
+ const [draggedTabId, setDraggedTabId] = createSignal<string | null>(null);
117
+ const [dropTargetId, setDropTargetId] = createSignal<string | null>(null);
118
+ const [dropPosition, setDropPosition] = createSignal<"left" | "right" | null>(null);
119
+
120
+ const activeValue = () => {
121
+ if (local.manager) return local.manager.activeTabId();
122
+ return local.value !== undefined ? local.value : internalValue();
123
+ };
124
+
125
+ const variant = () => local.variant || "editor";
126
+
127
+ const setValue = (val: string) => {
128
+ if (local.manager) {
129
+ local.manager.setActiveTab(val);
130
+ } else {
131
+ setInternalValue(val);
132
+ local.onValueChange?.(val);
133
+ }
134
+ };
135
+
136
+ const setDragState = (
137
+ draggedId: string | null,
138
+ targetId: string | null,
139
+ pos: "left" | "right" | null
140
+ ) => {
141
+ setDraggedTabId(draggedId);
142
+ setDropTargetId(targetId);
143
+ setDropPosition(pos);
144
+ };
145
+
146
+ const handleDropReorder = (sourceId: string, targetId: string, pos: "left" | "right") => {
147
+ if (!local.manager) return;
148
+ const list = local.manager.tabs();
149
+ const fromIndex = list.findIndex((t) => t.id === sourceId);
150
+ const targetIndex = list.findIndex((t) => t.id === targetId);
151
+ if (fromIndex === -1 || targetIndex === -1 || fromIndex === targetIndex) return;
152
+
153
+ let finalIndex = targetIndex;
154
+ if (fromIndex < targetIndex && pos === "left") {
155
+ finalIndex = targetIndex - 1;
156
+ } else if (fromIndex > targetIndex && pos === "right") {
157
+ finalIndex = targetIndex + 1;
158
+ }
159
+
160
+ if (fromIndex !== finalIndex && finalIndex >= 0 && finalIndex < list.length) {
161
+ local.manager.reorderTabs(fromIndex, finalIndex);
162
+ }
163
+ };
164
+
165
+ // Mouse wheel horizontal scroll listener (converts vertical wheel deltaY to horizontal scroll)
166
+ onMount(() => {
167
+ if (!scrollContainerRef) return;
168
+
169
+ const handleWheel = (e: WheelEvent) => {
170
+ if (e.deltaY !== 0) {
171
+ e.preventDefault();
172
+ scrollContainerRef!.scrollLeft += e.deltaY;
173
+ }
174
+ };
175
+
176
+ scrollContainerRef.addEventListener("wheel", handleWheel, { passive: false });
177
+ onCleanup(() => {
178
+ scrollContainerRef?.removeEventListener("wheel", handleWheel);
179
+ });
180
+ });
181
+
182
+ // Auto-scroll to end when tabs are added
183
+ createEffect(() => {
184
+ if (local.manager?.count() && scrollContainerRef) {
185
+ scrollContainerRef.scrollTo({
186
+ left: scrollContainerRef.scrollWidth,
187
+ behavior: "smooth",
188
+ });
189
+ }
190
+ });
191
+
192
+ const contextValue: TitlebarTabsContextValue = {
193
+ value: activeValue,
194
+ setValue,
195
+ variant,
196
+ manager: local.manager,
197
+ reorderable: local.reorderable ?? Boolean(local.manager),
198
+ enableContextMenu: local.enableContextMenu ?? true,
199
+ draggedTabId,
200
+ dropTargetId,
201
+ dropPosition,
202
+ setDragState,
203
+ handleDropReorder,
204
+ };
205
+
206
+ const hasEmptyContextMenu = () =>
207
+ (local.enableContextMenu ?? true) &&
208
+ (Boolean(local.onAddTab) || Boolean(local.manager) || Boolean(local.renderEmptyContextMenu));
209
+
210
+ const renderNavContent = () => (
211
+ <nav
212
+ aria-label="Window Tabs"
213
+ class={cn(
214
+ "flex flex-1 h-full overflow-hidden z-10 min-w-0 pointer-events-auto [app-region:drag] [-webkit-app-region:drag]",
215
+ variant() === "chrome" ? "items-end" : "items-center",
216
+ local.class
217
+ )}
218
+ {...rest}
219
+ >
220
+ <Show
221
+ when={local.children}
222
+ fallback={
223
+ /* Automatic Declarative Mode: Tab List with Mouse Wheel Scroll + Anchored Add Button */
224
+ <>
225
+ <div
226
+ ref={scrollContainerRef}
227
+ class={cn(
228
+ "flex h-full overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] gap-0 items-center min-w-0 flex-1 scroll-smooth [app-region:drag] [-webkit-app-region:drag]",
229
+ variant() === "chrome" && "items-end pt-1.5"
230
+ )}
231
+ >
232
+ <Show when={local.manager}>
233
+ <For each={local.manager!.tabs()}>
234
+ {(tab) => <TitlebarTab tab={tab} />}
235
+ </For>
236
+ </Show>
237
+ </div>
238
+
239
+ {/* Anchored Add Tab Button (Always visible outside scroll container) */}
240
+ <Show when={local.onAddTab}>
241
+ <div class={cn("shrink-0 px-1 z-20 flex items-center", variant() === "chrome" ? "mb-1" : "my-auto")}>
242
+ <TitlebarTabAddButton onClick={local.onAddTab} />
243
+ </div>
244
+ </Show>
245
+ </>
246
+ }
247
+ >
248
+ {local.children}
249
+ </Show>
250
+ </nav>
251
+ );
252
+
253
+ return (
254
+ <TitlebarTabsContext.Provider value={contextValue}>
255
+ <Show when={hasEmptyContextMenu()} fallback={renderNavContent()}>
256
+ <ContextMenuPrimitive.Root>
257
+ <ContextMenuPrimitive.Trigger
258
+ as="div"
259
+ style={("-webkit-app-region: no-drag; app-region: no-drag; outline: none !important; -webkit-focus-ring-color: transparent !important;") as any}
260
+ class="flex flex-1 h-full min-w-0 outline-none ring-0 focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0"
261
+ >
262
+ {renderNavContent()}
263
+ </ContextMenuPrimitive.Trigger>
264
+ <ContextMenuPrimitive.Portal>
265
+ <ContextMenuPrimitive.Content
266
+ data-no-drag
267
+ data-tauri-drag-region="false"
268
+ style="-webkit-app-region: no-drag; app-region: no-drag; outline: none !important; -webkit-focus-ring-color: transparent !important;"
269
+ onMouseDown={(e) => e.stopPropagation()}
270
+ onPointerDown={(e) => e.stopPropagation()}
271
+ class={cn(
272
+ "z-50 min-w-[160px] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md",
273
+ "animate-in fade-in-80 slide-in-from-top-1 text-xs pointer-events-auto [app-region:no-drag] [-webkit-app-region:no-drag]",
274
+ "outline-none ring-0 focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0"
275
+ )}
276
+ >
277
+ <Show
278
+ when={local.renderEmptyContextMenu}
279
+ fallback={
280
+ <>
281
+ <Show when={local.onAddTab}>
282
+ <ContextMenuPrimitive.Item
283
+ data-no-drag
284
+ data-tauri-drag-region="false"
285
+ style="-webkit-app-region: no-drag; app-region: no-drag;"
286
+ onMouseDown={(e) => e.stopPropagation()}
287
+ onPointerDown={(e) => e.stopPropagation()}
288
+ onSelect={() => {
289
+ setTimeout(() => local.onAddTab?.(), 0);
290
+ }}
291
+ class="relative flex cursor-pointer select-none items-center justify-between gap-2 rounded-xs px-2 py-1.5 text-xs outline-none transition-colors hover:bg-accent hover:text-accent-foreground pointer-events-auto [app-region:no-drag] [-webkit-app-region:no-drag]"
292
+ >
293
+ <span class="flex items-center gap-2">
294
+ <Plus class="size-3.5 text-muted-foreground" />
295
+ New Tab
296
+ </span>
297
+ <span class="ml-auto text-[10px] text-muted-foreground font-mono">Ctrl+T</span>
298
+ </ContextMenuPrimitive.Item>
299
+ </Show>
300
+
301
+ <Show when={local.manager && local.manager.tabs().length > 0}>
302
+ <Show when={local.onAddTab}>
303
+ <ContextMenuPrimitive.Separator class="my-1 h-px bg-border/60" />
304
+ </Show>
305
+ <ContextMenuPrimitive.Item
306
+ data-no-drag
307
+ data-tauri-drag-region="false"
308
+ style="-webkit-app-region: no-drag; app-region: no-drag;"
309
+ onMouseDown={(e) => e.stopPropagation()}
310
+ onPointerDown={(e) => e.stopPropagation()}
311
+ onSelect={() => {
312
+ setTimeout(() => local.manager?.closeAll(), 0);
313
+ }}
314
+ class="relative flex cursor-pointer select-none items-center gap-2 rounded-xs px-2 py-1.5 text-xs outline-none transition-colors hover:bg-accent hover:text-accent-foreground pointer-events-auto [app-region:no-drag] [-webkit-app-region:no-drag]"
315
+ >
316
+ <CircleX class="size-3.5 text-muted-foreground" />
317
+ <span>Close All Tabs</span>
318
+ </ContextMenuPrimitive.Item>
319
+ </Show>
320
+ </>
321
+ }
322
+ >
323
+ {local.renderEmptyContextMenu!()}
324
+ </Show>
325
+ </ContextMenuPrimitive.Content>
326
+ </ContextMenuPrimitive.Portal>
327
+ </ContextMenuPrimitive.Root>
328
+ </Show>
329
+ </TitlebarTabsContext.Provider>
330
+ );
331
+ };
332
+
333
+ /* --- 3. TitlebarTabList --- */
334
+
335
+ export interface TitlebarTabListProps extends JSX.HTMLAttributes<HTMLDivElement> {
336
+ class?: string;
337
+ }
338
+
339
+ export const TitlebarTabList: ParentComponent<TitlebarTabListProps> = (props) => {
340
+ const [local, rest] = splitProps(props, ["class", "children"]);
341
+ const ctx = useTitlebarTabs();
342
+ let listRef: HTMLDivElement | undefined;
343
+
344
+ onMount(() => {
345
+ if (!listRef) return;
346
+ const handleWheel = (e: WheelEvent) => {
347
+ if (e.deltaY !== 0) {
348
+ e.preventDefault();
349
+ listRef!.scrollLeft += e.deltaY;
350
+ }
351
+ };
352
+ listRef.addEventListener("wheel", handleWheel, { passive: false });
353
+ onCleanup(() => listRef?.removeEventListener("wheel", handleWheel));
354
+ });
355
+
356
+ return (
357
+ <div
358
+ ref={listRef}
359
+ class={cn(
360
+ "flex h-full overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] gap-0 items-center min-w-0 flex-1 scroll-smooth [app-region:drag] [-webkit-app-region:drag]",
361
+ ctx.variant() === "chrome" && "items-end pt-1.5",
362
+ local.class
363
+ )}
364
+ {...rest}
365
+ >
366
+ {local.children}
367
+ </div>
368
+ );
369
+ };
370
+
371
+ /* --- 4. TitlebarTab Individual Item --- */
372
+
373
+ export interface TitlebarTabProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, "onClose"> {
374
+ /** Tab data object from createDocumentTabs(). Automatically wires all properties. */
375
+ tab?: TabItem<any>;
376
+ value?: string;
377
+ isDirty?: boolean;
378
+ isPinned?: boolean;
379
+ closable?: boolean;
380
+ reorderable?: boolean;
381
+ /** Whether right-click context menu is enabled on this tab. Defaults to true. */
382
+ enableContextMenu?: boolean;
383
+ /** Custom render function for context menu content. */
384
+ renderContextMenu?: (tab: TabItem<any>) => JSX.Element;
385
+ onClose?: (e: MouseEvent) => void;
386
+ class?: string;
387
+ }
388
+
389
+ export const TitlebarTab: ParentComponent<TitlebarTabProps> = (props) => {
390
+ const [local, rest] = splitProps(props, [
391
+ "tab",
392
+ "value",
393
+ "isDirty",
394
+ "isPinned",
395
+ "closable",
396
+ "reorderable",
397
+ "enableContextMenu",
398
+ "renderContextMenu",
399
+ "onClose",
400
+ "class",
401
+ "style",
402
+ "children",
403
+ "onClick",
404
+ "onKeyDown",
405
+ "onDragStart",
406
+ "onDragOver",
407
+ "onDragLeave",
408
+ "onDragEnd",
409
+ "onDrop",
410
+ ]);
411
+
412
+ const ctx = useTitlebarTabs();
413
+ let tabRef: HTMLDivElement | undefined;
414
+
415
+ const tabId = () => local.tab?.id || local.value || "";
416
+ const isPinned = () => local.tab?.isPinned ?? local.isPinned ?? false;
417
+ const isDirty = () => local.tab?.isDirty ?? local.isDirty ?? false;
418
+ const closable = () => local.tab?.closable ?? local.closable ?? true;
419
+ const title = () => local.tab?.title || "";
420
+ const IconComp = () => local.tab?.icon;
421
+
422
+ const isActive = () => ctx.value() === tabId();
423
+ const isDragging = () => ctx.draggedTabId() === tabId();
424
+ const isDropTarget = () => ctx.dropTargetId() === tabId() && ctx.draggedTabId() !== tabId();
425
+ const dropPosition = () => (isDropTarget() ? ctx.dropPosition() : null);
426
+
427
+ const canDrag = () => !isPinned() && (local.reorderable ?? ctx.reorderable ?? true);
428
+ const hasContextMenu = () =>
429
+ (local.enableContextMenu ?? ctx.enableContextMenu ?? true) &&
430
+ (Boolean(ctx.manager) || Boolean(local.renderContextMenu));
431
+
432
+ // Scroll active tab horizontally inside its tablist container
433
+ createEffect(() => {
434
+ if (typeof window !== "undefined" && isActive() && tabRef && tabRef.parentElement) {
435
+ try {
436
+ const container = tabRef.parentElement;
437
+ const tabLeft = tabRef.offsetLeft;
438
+ const tabRight = tabLeft + tabRef.offsetWidth;
439
+ const containerLeft = container.scrollLeft;
440
+ const containerRight = containerLeft + container.clientWidth;
441
+
442
+ if (tabLeft < containerLeft) {
443
+ container.scrollTo({ left: tabLeft, behavior: "smooth" });
444
+ } else if (tabRight > containerRight) {
445
+ container.scrollTo({ left: tabRight - container.clientWidth, behavior: "smooth" });
446
+ }
447
+ } catch {
448
+ // Safe fallback
449
+ }
450
+ }
451
+ });
452
+
453
+ const handleClick = (e: MouseEvent) => {
454
+ ctx.setValue(tabId());
455
+ if (typeof local.onClick === "function") {
456
+ (local.onClick as any)(e);
457
+ }
458
+ };
459
+
460
+ const handleKeyDown = (e: KeyboardEvent) => {
461
+ if (e.key === "Enter" || e.key === " ") {
462
+ e.preventDefault();
463
+ ctx.setValue(tabId());
464
+ }
465
+ if (typeof (local as any).onKeyDown === "function") {
466
+ ((local as any).onKeyDown)(e);
467
+ }
468
+ };
469
+
470
+ const handleClose = (e: MouseEvent) => {
471
+ e.stopPropagation();
472
+ if (local.onClose) {
473
+ local.onClose(e);
474
+ } else if (ctx.manager) {
475
+ ctx.manager.closeTab(tabId());
476
+ }
477
+ };
478
+
479
+ const handleDragStart: JSX.EventHandlerUnion<HTMLDivElement, DragEvent> = (e) => {
480
+ if (!canDrag()) {
481
+ e.preventDefault();
482
+ return;
483
+ }
484
+ if (e.dataTransfer) {
485
+ e.dataTransfer.setData("text/plain", tabId());
486
+ e.dataTransfer.effectAllowed = "move";
487
+ }
488
+ ctx.setDragState(tabId(), null, null);
489
+ if (typeof local.onDragStart === "function") {
490
+ (local.onDragStart as any)(e);
491
+ }
492
+ };
493
+
494
+ const handleDragOver: JSX.EventHandlerUnion<HTMLDivElement, DragEvent> = (e) => {
495
+ const currentDragged = ctx.draggedTabId();
496
+ if (!currentDragged || currentDragged === tabId() || isPinned()) return;
497
+
498
+ e.preventDefault();
499
+ if (e.dataTransfer) {
500
+ e.dataTransfer.dropEffect = "move";
501
+ }
502
+
503
+ if (tabRef) {
504
+ const rect = tabRef.getBoundingClientRect();
505
+ const midpoint = rect.left + rect.width / 2;
506
+ const pos: "left" | "right" = e.clientX < midpoint ? "left" : "right";
507
+ ctx.setDragState(currentDragged, tabId(), pos);
508
+ }
509
+
510
+ if (typeof local.onDragOver === "function") {
511
+ (local.onDragOver as any)(e);
512
+ }
513
+ };
514
+
515
+ const handleDragLeave: JSX.EventHandlerUnion<HTMLDivElement, DragEvent> = (e) => {
516
+ if (tabRef && !tabRef.contains(e.relatedTarget as Node)) {
517
+ if (ctx.dropTargetId() === tabId()) {
518
+ ctx.setDragState(ctx.draggedTabId(), null, null);
519
+ }
520
+ }
521
+ if (typeof local.onDragLeave === "function") {
522
+ (local.onDragLeave as any)(e);
523
+ }
524
+ };
525
+
526
+ const handleDragEnd: JSX.EventHandlerUnion<HTMLDivElement, DragEvent> = (e) => {
527
+ ctx.setDragState(null, null, null);
528
+ if (typeof local.onDragEnd === "function") {
529
+ (local.onDragEnd as any)(e);
530
+ }
531
+ };
532
+
533
+ const handleDrop: JSX.EventHandlerUnion<HTMLDivElement, DragEvent> = (e) => {
534
+ e.preventDefault();
535
+ const sourceId = e.dataTransfer?.getData("text/plain") || ctx.draggedTabId();
536
+ const pos = ctx.dropPosition();
537
+ if (sourceId && pos && sourceId !== tabId()) {
538
+ ctx.handleDropReorder(sourceId, tabId(), pos);
539
+ }
540
+ ctx.setDragState(null, null, null);
541
+ if (typeof local.onDrop === "function") {
542
+ (local.onDrop as any)(e);
543
+ }
544
+ };
545
+
546
+ const renderTabElement = () => (
547
+ <div
548
+ ref={tabRef}
549
+ role="tab"
550
+ tabindex="0"
551
+ aria-selected={isActive()}
552
+ draggable={canDrag()}
553
+ onDragStart={handleDragStart}
554
+ onDragOver={handleDragOver}
555
+ onDragLeave={handleDragLeave}
556
+ onDragEnd={handleDragEnd}
557
+ onDrop={handleDrop}
558
+ data-no-drag
559
+ data-tauri-drag-region="false"
560
+ style={("-webkit-app-region: no-drag; app-region: no-drag;" + (typeof local.style === "string" ? ` ${local.style}` : "")) as any}
561
+ data-active={isActive() ? "true" : "false"}
562
+ data-dragging={isDragging() ? "true" : undefined}
563
+ onClick={handleClick}
564
+ onKeyDown={handleKeyDown}
565
+ class={cn(
566
+ titlebarTabVariants({ variant: ctx.variant() }),
567
+ isPinned() && "min-w-fit px-2 max-w-fit",
568
+ isDragging() && "opacity-40 scale-95",
569
+ dropPosition() === "left" &&
570
+ "before:absolute before:left-0 before:top-1 before:bottom-1 before:w-0.5 before:bg-primary before:z-30 before:rouded-lg",
571
+ dropPosition() === "right" &&
572
+ "after:absolute after:right-0 after:top-1 after:bottom-1 after:w-0.5 after:bg-primary after:z-30 after:rouded-lg",
573
+ "cursor-pointer outline-none ring-0 focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 [app-region:no-drag] [-webkit-app-region:no-drag] pointer-events-auto transition-all duration-150",
574
+ local.class
575
+ )}
576
+ {...rest}
577
+ >
578
+ {/* Tab Icon & Title Slot */}
579
+ <span class="flex items-center gap-1.5 truncate flex-1 pointer-events-none">
580
+ <Show when={IconComp()}>
581
+ {(() => {
582
+ const Comp = IconComp()!;
583
+ return <Comp class="size-3.5 shrink-0 text-primary" />;
584
+ })()}
585
+ </Show>
586
+ <Show when={local.children} fallback={<span class="truncate">{title()}</span>}>
587
+ {local.children}
588
+ </Show>
589
+ </span>
590
+
591
+ {/* Pinned Tab Badge */}
592
+ <Show when={isPinned()}>
593
+ <Pin class="size-2.5 text-muted-foreground rotate-45 shrink-0" />
594
+ </Show>
595
+
596
+ {/* Close Button / Dirty Dot Indicator using Nikala UI Button */}
597
+ <Show when={!isPinned() && closable()}>
598
+ <Tooltip>
599
+ <TooltipTrigger
600
+ as={Button}
601
+ variant="ghost"
602
+ size="icon"
603
+ onClick={handleClose}
604
+ aria-label={`Close ${tabId()} tab`}
605
+ class="size-4 p-0 rounded-xs text-muted-foreground hover:bg-muted hover:text-foreground shrink-0 ml-0.5 cursor-pointer outline-none ring-0 focus:ring-0 focus-visible:ring-0"
606
+ >
607
+ <Show
608
+ when={isDirty()}
609
+ fallback={<X class="size-3 opacity-60 hover:opacity-100" />}
610
+ >
611
+ <span class="size-1.5 rouded-lg bg-primary group-hover:hidden" />
612
+ <X class="size-3 hidden group-hover:block" />
613
+ </Show>
614
+ </TooltipTrigger>
615
+ <TooltipContent class="text-[10px] py-1 px-2">
616
+ Close tab (Ctrl+W)
617
+ </TooltipContent>
618
+ </Tooltip>
619
+ </Show>
620
+ </div>
621
+ );
622
+
623
+ return (
624
+ <Show when={hasContextMenu()} fallback={renderTabElement()}>
625
+ <ContextMenuPrimitive.Root>
626
+ <ContextMenuPrimitive.Trigger
627
+ as="div"
628
+ data-no-drag
629
+ data-tauri-drag-region="false"
630
+ style={("-webkit-app-region: no-drag; app-region: no-drag; outline: none !important; -webkit-focus-ring-color: transparent !important;" + (typeof local.style === "string" ? ` ${local.style}` : "")) as any}
631
+ class="h-full flex items-center shrink-0 pointer-events-auto [app-region:no-drag] [-webkit-app-region:no-drag] outline-none ring-0 focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0"
632
+ >
633
+ {renderTabElement()}
634
+ </ContextMenuPrimitive.Trigger>
635
+ <ContextMenuPrimitive.Portal>
636
+ <ContextMenuPrimitive.Content
637
+ data-no-drag
638
+ data-tauri-drag-region="false"
639
+ style="-webkit-app-region: no-drag; app-region: no-drag; outline: none !important; -webkit-focus-ring-color: transparent !important;"
640
+ onMouseDown={(e) => e.stopPropagation()}
641
+ onPointerDown={(e) => e.stopPropagation()}
642
+ class={cn(
643
+ "z-50 min-w-[170px] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md",
644
+ "animate-in fade-in-80 slide-in-from-top-1 text-xs pointer-events-auto [app-region:no-drag] [-webkit-app-region:no-drag]",
645
+ "outline-none ring-0 focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0"
646
+ )}
647
+ >
648
+ <Show
649
+ when={local.renderContextMenu}
650
+ fallback={
651
+ <>
652
+ <Show when={ctx.manager}>
653
+ <ContextMenuPrimitive.Item
654
+ data-no-drag
655
+ data-tauri-drag-region="false"
656
+ style="-webkit-app-region: no-drag; app-region: no-drag;"
657
+ onMouseDown={(e) => e.stopPropagation()}
658
+ onPointerDown={(e) => e.stopPropagation()}
659
+ onSelect={() => {
660
+ setTimeout(() => ctx.manager?.togglePin(tabId()), 0);
661
+ }}
662
+ class="relative flex cursor-pointer select-none items-center gap-2 rounded-xs px-2 py-1.5 text-xs outline-none transition-colors hover:bg-accent hover:text-accent-foreground pointer-events-auto [app-region:no-drag] [-webkit-app-region:no-drag]"
663
+ >
664
+ <Pin class="size-3.5 text-muted-foreground" />
665
+ <span>{isPinned() ? "Unpin Tab" : "Pin Tab"}</span>
666
+ </ContextMenuPrimitive.Item>
667
+ <ContextMenuPrimitive.Separator class="my-1 h-px bg-border/60" />
668
+ </Show>
669
+
670
+ <ContextMenuPrimitive.Item
671
+ data-no-drag
672
+ data-tauri-drag-region="false"
673
+ style="-webkit-app-region: no-drag; app-region: no-drag;"
674
+ onMouseDown={(e) => e.stopPropagation()}
675
+ onPointerDown={(e) => e.stopPropagation()}
676
+ disabled={isPinned() || !closable()}
677
+ onSelect={() => {
678
+ setTimeout(() => {
679
+ if (local.onClose) local.onClose(new MouseEvent("click"));
680
+ else ctx.manager?.closeTab(tabId());
681
+ }, 0);
682
+ }}
683
+ class="relative flex cursor-pointer select-none items-center justify-between gap-2 rounded-xs px-2 py-1.5 text-xs outline-none transition-colors hover:bg-accent hover:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 pointer-events-auto [app-region:no-drag] [-webkit-app-region:no-drag]"
684
+ >
685
+ <span class="flex items-center gap-2">
686
+ <X class="size-3.5 text-muted-foreground" />
687
+ Close Tab
688
+ </span>
689
+ <span class="ml-auto text-[10px] text-muted-foreground font-mono">Ctrl+W</span>
690
+ </ContextMenuPrimitive.Item>
691
+
692
+ <Show when={ctx.manager && ctx.manager.tabs().length > 1}>
693
+ <ContextMenuPrimitive.Item
694
+ data-no-drag
695
+ data-tauri-drag-region="false"
696
+ style="-webkit-app-region: no-drag; app-region: no-drag;"
697
+ onMouseDown={(e) => e.stopPropagation()}
698
+ onPointerDown={(e) => e.stopPropagation()}
699
+ onSelect={() => {
700
+ setTimeout(() => ctx.manager?.closeOthers(tabId()), 0);
701
+ }}
702
+ class="relative flex cursor-pointer select-none items-center gap-2 rounded-xs px-2 py-1.5 text-xs outline-none transition-colors hover:bg-accent hover:text-accent-foreground pointer-events-auto [app-region:no-drag] [-webkit-app-region:no-drag]"
703
+ >
704
+ <CircleX class="size-3.5 text-muted-foreground" />
705
+ Close Other Tabs
706
+ </ContextMenuPrimitive.Item>
707
+ <ContextMenuPrimitive.Item
708
+ data-no-drag
709
+ data-tauri-drag-region="false"
710
+ style="-webkit-app-region: no-drag; app-region: no-drag;"
711
+ onMouseDown={(e) => e.stopPropagation()}
712
+ onPointerDown={(e) => e.stopPropagation()}
713
+ onSelect={() => {
714
+ setTimeout(() => ctx.manager?.closeAll(), 0);
715
+ }}
716
+ class="relative flex cursor-pointer select-none items-center gap-2 rounded-xs px-2 py-1.5 text-xs outline-none transition-colors hover:bg-accent hover:text-accent-foreground pointer-events-auto [app-region:no-drag] [-webkit-app-region:no-drag]"
717
+ >
718
+ <CircleX class="size-3.5 text-muted-foreground" />
719
+ <span>Close All Tabs</span>
720
+ </ContextMenuPrimitive.Item>
721
+ </Show>
722
+ </>
723
+ }
724
+ >
725
+ {local.renderContextMenu!(local.tab || { id: tabId(), title: title() })}
726
+ </Show>
727
+ </ContextMenuPrimitive.Content>
728
+ </ContextMenuPrimitive.Portal>
729
+ </ContextMenuPrimitive.Root>
730
+ </Show>
731
+ );
732
+ };
733
+
734
+ /* --- 5. TitlebarTabAddButton using Nikala UI Button & Tooltip --- */
735
+
736
+ export interface TitlebarTabAddButtonProps extends JSX.HTMLAttributes<HTMLButtonElement> {
737
+ class?: string;
738
+ }
739
+
740
+ export const TitlebarTabAddButton: Component<TitlebarTabAddButtonProps> = (props) => {
741
+ const [local, rest] = splitProps(props, ["class", "style"]);
742
+
743
+ return (
744
+ <div
745
+ data-no-drag
746
+ data-tauri-drag-region="false"
747
+ style={("-webkit-app-region: no-drag; app-region: no-drag;" + (typeof local.style === "string" ? ` ${local.style}` : "")) as any}
748
+ class="shrink-0 flex items-center z-20 pointer-events-auto [app-region:no-drag] [-webkit-app-region:no-drag]"
749
+ >
750
+ <Tooltip>
751
+ <TooltipTrigger
752
+ as={Button}
753
+ variant="ghost"
754
+ size="icon"
755
+ data-no-drag
756
+ data-tauri-drag-region="false"
757
+ aria-label="Add new tab"
758
+ class={cn(
759
+ "size-6 rounded-md text-muted-foreground hover:bg-muted/80 hover:text-foreground cursor-pointer shrink-0",
760
+ local.class
761
+ )}
762
+ {...rest}
763
+ >
764
+ <Plus class="size-3.5" />
765
+ </TooltipTrigger>
766
+ <TooltipContent class="text-[10px] py-1 px-2">
767
+ New tab (Ctrl+T)
768
+ </TooltipContent>
769
+ </Tooltip>
770
+ </div>
771
+ );
772
+ };
773
+