@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.
- package/README.md +22 -0
- package/dist/cli/commands/build.d.ts +5 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +27 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +7 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +32 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +308 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/preview.d.ts +7 -0
- package/dist/cli/commands/preview.d.ts.map +1 -0
- package/dist/cli/commands/preview.js +24 -0
- package/dist/cli/commands/preview.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +7 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +33 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +53 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/client/App.d.ts +5 -0
- package/dist/client/App.d.ts.map +1 -0
- package/dist/client/App.jsx +31 -0
- package/dist/client/App.jsx.map +1 -0
- package/dist/client/app-types.d.ts +14 -0
- package/dist/client/app-types.d.ts.map +1 -0
- package/dist/client/app-types.js +2 -0
- package/dist/client/app-types.js.map +1 -0
- package/dist/client/components/DocsLayoutShell.d.ts +21 -0
- package/dist/client/components/DocsLayoutShell.d.ts.map +1 -0
- package/dist/client/components/DocsLayoutShell.jsx +14 -0
- package/dist/client/components/DocsLayoutShell.jsx.map +1 -0
- package/dist/client/components/DocsPageContent.d.ts +9 -0
- package/dist/client/components/DocsPageContent.d.ts.map +1 -0
- package/dist/client/components/DocsPageContent.jsx +10 -0
- package/dist/client/components/DocsPageContent.jsx.map +1 -0
- package/dist/client/entry.d.ts +2 -0
- package/dist/client/entry.d.ts.map +1 -0
- package/dist/client/entry.jsx +28 -0
- package/dist/client/entry.jsx.map +1 -0
- package/dist/client/index.html +21 -0
- package/dist/client/navigation/page-navigation.d.ts +9 -0
- package/dist/client/navigation/page-navigation.d.ts.map +1 -0
- package/dist/client/navigation/page-navigation.js +51 -0
- package/dist/client/navigation/page-navigation.js.map +1 -0
- package/dist/client/routing/use-docs-router.d.ts +17 -0
- package/dist/client/routing/use-docs-router.d.ts.map +1 -0
- package/dist/client/routing/use-docs-router.js +71 -0
- package/dist/client/routing/use-docs-router.js.map +1 -0
- package/dist/client/ssr-entry.d.ts +3 -0
- package/dist/client/ssr-entry.d.ts.map +1 -0
- package/dist/client/ssr-entry.jsx +13 -0
- package/dist/client/ssr-entry.jsx.map +1 -0
- package/dist/client/style.css +183 -0
- package/dist/client/utils/sidebar.d.ts +2 -0
- package/dist/client/utils/sidebar.d.ts.map +1 -0
- package/dist/client/utils/sidebar.js +2 -0
- package/dist/client/utils/sidebar.js.map +1 -0
- package/dist/components/mdx-components.d.ts +34 -0
- package/dist/components/mdx-components.d.ts.map +1 -0
- package/dist/components/mdx-components.jsx +131 -0
- package/dist/components/mdx-components.jsx.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +105 -0
- package/dist/config.js.map +1 -0
- package/dist/core/content-scanner.d.ts +10 -0
- package/dist/core/content-scanner.d.ts.map +1 -0
- package/dist/core/content-scanner.js +153 -0
- package/dist/core/content-scanner.js.map +1 -0
- package/dist/core/route-tree.d.ts +19 -0
- package/dist/core/route-tree.d.ts.map +1 -0
- package/dist/core/route-tree.js +176 -0
- package/dist/core/route-tree.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/cn.d.ts +6 -0
- package/dist/lib/cn.d.ts.map +1 -0
- package/dist/lib/cn.js +9 -0
- package/dist/lib/cn.js.map +1 -0
- package/dist/mdx/compiler.d.ts +13 -0
- package/dist/mdx/compiler.d.ts.map +1 -0
- package/dist/mdx/compiler.js +38 -0
- package/dist/mdx/compiler.js.map +1 -0
- package/dist/mdx/highlighter.d.ts +22 -0
- package/dist/mdx/highlighter.d.ts.map +1 -0
- package/dist/mdx/highlighter.js +139 -0
- package/dist/mdx/highlighter.js.map +1 -0
- package/dist/mdx/rehype-shiki.d.ts +3 -0
- package/dist/mdx/rehype-shiki.d.ts.map +1 -0
- package/dist/mdx/rehype-shiki.js +83 -0
- package/dist/mdx/rehype-shiki.js.map +1 -0
- package/dist/navigation/index.d.ts +2 -0
- package/dist/navigation/index.d.ts.map +1 -0
- package/dist/navigation/index.js +2 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/navigation/sidebar-state.d.ts +6 -0
- package/dist/navigation/sidebar-state.d.ts.map +1 -0
- package/dist/navigation/sidebar-state.js +20 -0
- package/dist/navigation/sidebar-state.js.map +1 -0
- package/dist/navigation/sidebar-tree.d.ts +7 -0
- package/dist/navigation/sidebar-tree.d.ts.map +1 -0
- package/dist/navigation/sidebar-tree.js +11 -0
- package/dist/navigation/sidebar-tree.js.map +1 -0
- package/dist/registry/accordion.json +18 -0
- package/dist/registry/alert.json +18 -0
- package/dist/registry/api-table.json +21 -0
- package/dist/registry/aspect-ratio.json +17 -0
- package/dist/registry/avatar.json +17 -0
- package/dist/registry/badge.json +18 -0
- package/dist/registry/banner.json +19 -0
- package/dist/registry/breadcrumb.json +17 -0
- package/dist/registry/bubble.json +18 -0
- package/dist/registry/button-group.json +20 -0
- package/dist/registry/button.json +21 -0
- package/dist/registry/callout.json +19 -0
- package/dist/registry/card.json +17 -0
- package/dist/registry/checkbox.json +20 -0
- package/dist/registry/code-block.json +26 -0
- package/dist/registry/code-group.json +20 -0
- package/dist/registry/collapsible.json +18 -0
- package/dist/registry/combobox.json +21 -0
- package/dist/registry/command.json +27 -0
- package/dist/registry/component-viewer.json +25 -0
- package/dist/registry/container.json +18 -0
- package/dist/registry/context-menu.json +24 -0
- package/dist/registry/create-active-element.json +13 -0
- package/dist/registry/create-app-updater.json +13 -0
- package/dist/registry/create-audio.json +7 -0
- package/dist/registry/create-battery.json +13 -0
- package/dist/registry/create-chat-scroll.json +13 -0
- package/dist/registry/create-click-outside.json +13 -0
- package/dist/registry/create-clipboard.json +13 -0
- package/dist/registry/create-color-mode.json +13 -0
- package/dist/registry/create-controllable-signal.json +13 -0
- package/dist/registry/create-debounce.json +13 -0
- package/dist/registry/create-disclosure.json +13 -0
- package/dist/registry/create-document-tabs.json +13 -0
- package/dist/registry/create-document-title.json +13 -0
- package/dist/registry/create-drop-zone.json +13 -0
- package/dist/registry/create-event-source.json +13 -0
- package/dist/registry/create-favicon.json +13 -0
- package/dist/registry/create-fetch.json +13 -0
- package/dist/registry/create-focus-trap.json +13 -0
- package/dist/registry/create-form.json +13 -0
- package/dist/registry/create-fullscreen.json +13 -0
- package/dist/registry/create-geolocation.json +13 -0
- package/dist/registry/create-global-shortcut.json +13 -0
- package/dist/registry/create-hover.json +13 -0
- package/dist/registry/create-idle.json +13 -0
- package/dist/registry/create-infinite-scroll.json +13 -0
- package/dist/registry/create-input-mask.json +13 -0
- package/dist/registry/create-intersection-observer.json +13 -0
- package/dist/registry/create-keybindings.json +13 -0
- package/dist/registry/create-lock-scroll.json +13 -0
- package/dist/registry/create-long-press.json +13 -0
- package/dist/registry/create-media-query.json +13 -0
- package/dist/registry/create-mouse-position.json +13 -0
- package/dist/registry/create-network-status.json +13 -0
- package/dist/registry/create-orientation.json +13 -0
- package/dist/registry/create-pagination.json +13 -0
- package/dist/registry/create-permission.json +13 -0
- package/dist/registry/create-previous.json +13 -0
- package/dist/registry/create-resize-observer.json +13 -0
- package/dist/registry/create-scroll-into-view.json +13 -0
- package/dist/registry/create-scroll-position.json +13 -0
- package/dist/registry/create-storage.json +13 -0
- package/dist/registry/create-tauri-window.json +13 -0
- package/dist/registry/create-timer.json +13 -0
- package/dist/registry/create-tiptap-editor.json +34 -0
- package/dist/registry/create-undo-redo.json +13 -0
- package/dist/registry/create-web-notification.json +13 -0
- package/dist/registry/create-websocket.json +13 -0
- package/dist/registry/create-window-size.json +13 -0
- package/dist/registry/dialog.json +21 -0
- package/dist/registry/dropdown-menu.json +22 -0
- package/dist/registry/dropzone.json +21 -0
- package/dist/registry/empty.json +17 -0
- package/dist/registry/field.json +20 -0
- package/dist/registry/file-tree.json +21 -0
- package/dist/registry/footer.json +18 -0
- package/dist/registry/forgot-password-01.json +28 -0
- package/dist/registry/form-message.json +17 -0
- package/dist/registry/form.json +17 -0
- package/dist/registry/hero-01.json +22 -0
- package/dist/registry/hover-card.json +18 -0
- package/dist/registry/icon-button.json +20 -0
- package/dist/registry/index.json +1489 -0
- package/dist/registry/input-group.json +21 -0
- package/dist/registry/input.json +17 -0
- package/dist/registry/kbd.json +18 -0
- package/dist/registry/label.json +18 -0
- package/dist/registry/list.json +20 -0
- package/dist/registry/login-01.json +28 -0
- package/dist/registry/logo.json +17 -0
- package/dist/registry/marker.json +17 -0
- package/dist/registry/marquee.json +17 -0
- package/dist/registry/message.json +17 -0
- package/dist/registry/navbar.json +19 -0
- package/dist/registry/navigation-menu.json +22 -0
- package/dist/registry/number-input.json +24 -0
- package/dist/registry/otp-verification-01.json +26 -0
- package/dist/registry/package-manager-tabs.json +24 -0
- package/dist/registry/pager.json +21 -0
- package/dist/registry/pagination.json +22 -0
- package/dist/registry/pin-input.json +17 -0
- package/dist/registry/popover.json +22 -0
- package/dist/registry/progress.json +18 -0
- package/dist/registry/radio-group.json +18 -0
- package/dist/registry/rating.json +19 -0
- package/dist/registry/register-01.json +31 -0
- package/dist/registry/resizable.json +21 -0
- package/dist/registry/review-card.json +23 -0
- package/dist/registry/rich-text-editor.json +95 -0
- package/dist/registry/scroll-area.json +21 -0
- package/dist/registry/section-heading.json +21 -0
- package/dist/registry/select.json +22 -0
- package/dist/registry/separator.json +17 -0
- package/dist/registry/sheet.json +22 -0
- package/dist/registry/sidebar.json +24 -0
- package/dist/registry/skeleton.json +17 -0
- package/dist/registry/slider.json +18 -0
- package/dist/registry/spinner.json +18 -0
- package/dist/registry/stat.json +19 -0
- package/dist/registry/status.json +18 -0
- package/dist/registry/steps.json +20 -0
- package/dist/registry/switch.json +20 -0
- package/dist/registry/table-of-contents.json +23 -0
- package/dist/registry/table.json +17 -0
- package/dist/registry/tabs.json +20 -0
- package/dist/registry/textarea.json +17 -0
- package/dist/registry/theme-manager.json +39 -0
- package/dist/registry/timeline.json +18 -0
- package/dist/registry/titlebar-tabs.json +24 -0
- package/dist/registry/titlebar.json +26 -0
- package/dist/registry/toast.json +20 -0
- package/dist/registry/toggle-group.json +21 -0
- package/dist/registry/toggle.json +18 -0
- package/dist/registry/tooltip.json +18 -0
- package/dist/registry/updater-modal.json +26 -0
- package/dist/server/index.d.ts +18 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +526 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/plugin.d.ts +10 -0
- package/dist/server/plugin.d.ts.map +1 -0
- package/dist/server/plugin.js +271 -0
- package/dist/server/plugin.js.map +1 -0
- package/dist/themes/default/content/breadcrumbs.d.ts +4 -0
- package/dist/themes/default/content/breadcrumbs.d.ts.map +1 -0
- package/dist/themes/default/content/breadcrumbs.jsx +31 -0
- package/dist/themes/default/content/breadcrumbs.jsx.map +1 -0
- package/dist/themes/default/content/pager.d.ts +5 -0
- package/dist/themes/default/content/pager.d.ts.map +1 -0
- package/dist/themes/default/content/pager.jsx +9 -0
- package/dist/themes/default/content/pager.jsx.map +1 -0
- package/dist/themes/default/content/table-of-contents.d.ts +4 -0
- package/dist/themes/default/content/table-of-contents.d.ts.map +1 -0
- package/dist/themes/default/content/table-of-contents.jsx +19 -0
- package/dist/themes/default/content/table-of-contents.jsx.map +1 -0
- package/dist/themes/default/index.d.ts +11 -0
- package/dist/themes/default/index.d.ts.map +1 -0
- package/dist/themes/default/index.js +30 -0
- package/dist/themes/default/index.js.map +1 -0
- package/dist/themes/default/layout.d.ts +4 -0
- package/dist/themes/default/layout.d.ts.map +1 -0
- package/dist/themes/default/layout.jsx +75 -0
- package/dist/themes/default/layout.jsx.map +1 -0
- package/dist/themes/default/navbar.d.ts +4 -0
- package/dist/themes/default/navbar.d.ts.map +1 -0
- package/dist/themes/default/navbar.jsx +74 -0
- package/dist/themes/default/navbar.jsx.map +1 -0
- package/dist/themes/default/navigation/mobile-table-of-contents.d.ts +4 -0
- package/dist/themes/default/navigation/mobile-table-of-contents.d.ts.map +1 -0
- package/dist/themes/default/navigation/mobile-table-of-contents.jsx +22 -0
- package/dist/themes/default/navigation/mobile-table-of-contents.jsx.map +1 -0
- package/dist/themes/default/navigation/sidebar-tree.d.ts +8 -0
- package/dist/themes/default/navigation/sidebar-tree.d.ts.map +1 -0
- package/dist/themes/default/navigation/sidebar-tree.jsx +100 -0
- package/dist/themes/default/navigation/sidebar-tree.jsx.map +1 -0
- package/dist/themes/default/overlays/search-dialog.d.ts +4 -0
- package/dist/themes/default/overlays/search-dialog.d.ts.map +1 -0
- package/dist/themes/default/overlays/search-dialog.jsx +34 -0
- package/dist/themes/default/overlays/search-dialog.jsx.map +1 -0
- package/dist/themes/default/sidebar.d.ts +4 -0
- package/dist/themes/default/sidebar.d.ts.map +1 -0
- package/dist/themes/default/sidebar.jsx +60 -0
- package/dist/themes/default/sidebar.jsx.map +1 -0
- package/dist/themes/index.d.ts +4 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/index.js +5 -0
- package/dist/themes/index.js.map +1 -0
- package/dist/themes/types.d.ts +83 -0
- package/dist/themes/types.d.ts.map +1 -0
- package/dist/themes/types.js +2 -0
- package/dist/themes/types.js.map +1 -0
- package/dist/types.d.ts +97 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/vendor/core-src/index.css +11 -0
- package/dist/vendor/core-src/index.ts +48 -0
- package/dist/vendor/core-src/lib/cn.ts +9 -0
- package/dist/vendor/core-src/registry/blocks/forgot-password-01.tsx +141 -0
- package/dist/vendor/core-src/registry/blocks/hero-01.tsx +28 -0
- package/dist/vendor/core-src/registry/blocks/login-01.tsx +231 -0
- package/dist/vendor/core-src/registry/blocks/otp-verification-01.tsx +170 -0
- package/dist/vendor/core-src/registry/blocks/register-01.tsx +318 -0
- package/dist/vendor/core-src/registry/components/ui/accordion.tsx +128 -0
- package/dist/vendor/core-src/registry/components/ui/alert.tsx +155 -0
- package/dist/vendor/core-src/registry/components/ui/api-table.tsx +117 -0
- package/dist/vendor/core-src/registry/components/ui/aspect-ratio.tsx +31 -0
- package/dist/vendor/core-src/registry/components/ui/avatar.tsx +114 -0
- package/dist/vendor/core-src/registry/components/ui/badge.tsx +56 -0
- package/dist/vendor/core-src/registry/components/ui/banner.tsx +187 -0
- package/dist/vendor/core-src/registry/components/ui/breadcrumb.tsx +136 -0
- package/dist/vendor/core-src/registry/components/ui/bubble.tsx +142 -0
- package/dist/vendor/core-src/registry/components/ui/button-group.tsx +42 -0
- package/dist/vendor/core-src/registry/components/ui/button.tsx +82 -0
- package/dist/vendor/core-src/registry/components/ui/callout.tsx +137 -0
- package/dist/vendor/core-src/registry/components/ui/card.tsx +113 -0
- package/dist/vendor/core-src/registry/components/ui/checkbox.tsx +74 -0
- package/dist/vendor/core-src/registry/components/ui/code-block.tsx +326 -0
- package/dist/vendor/core-src/registry/components/ui/code-group.tsx +105 -0
- package/dist/vendor/core-src/registry/components/ui/collapsible.tsx +73 -0
- package/dist/vendor/core-src/registry/components/ui/combobox.tsx +299 -0
- package/dist/vendor/core-src/registry/components/ui/command.tsx +378 -0
- package/dist/vendor/core-src/registry/components/ui/component-viewer.tsx +363 -0
- package/dist/vendor/core-src/registry/components/ui/container.tsx +45 -0
- package/dist/vendor/core-src/registry/components/ui/context-menu.tsx +237 -0
- package/dist/vendor/core-src/registry/components/ui/dialog.tsx +200 -0
- package/dist/vendor/core-src/registry/components/ui/dropdown-menu.tsx +298 -0
- package/dist/vendor/core-src/registry/components/ui/dropzone.tsx +189 -0
- package/dist/vendor/core-src/registry/components/ui/empty.tsx +83 -0
- package/dist/vendor/core-src/registry/components/ui/field.tsx +71 -0
- package/dist/vendor/core-src/registry/components/ui/file-tree.tsx +181 -0
- package/dist/vendor/core-src/registry/components/ui/footer.tsx +247 -0
- package/dist/vendor/core-src/registry/components/ui/form-message.tsx +36 -0
- package/dist/vendor/core-src/registry/components/ui/form.tsx +21 -0
- package/dist/vendor/core-src/registry/components/ui/hover-card.tsx +105 -0
- package/dist/vendor/core-src/registry/components/ui/icon-button.tsx +34 -0
- package/dist/vendor/core-src/registry/components/ui/input-group.tsx +80 -0
- package/dist/vendor/core-src/registry/components/ui/input.tsx +28 -0
- package/dist/vendor/core-src/registry/components/ui/kbd.tsx +73 -0
- package/dist/vendor/core-src/registry/components/ui/label.tsx +30 -0
- package/dist/vendor/core-src/registry/components/ui/list.tsx +222 -0
- package/dist/vendor/core-src/registry/components/ui/logo.tsx +68 -0
- package/dist/vendor/core-src/registry/components/ui/marker.tsx +102 -0
- package/dist/vendor/core-src/registry/components/ui/marquee.tsx +118 -0
- package/dist/vendor/core-src/registry/components/ui/message.tsx +168 -0
- package/dist/vendor/core-src/registry/components/ui/navbar.tsx +375 -0
- package/dist/vendor/core-src/registry/components/ui/navigation-menu.tsx +358 -0
- package/dist/vendor/core-src/registry/components/ui/number-input.tsx +150 -0
- package/dist/vendor/core-src/registry/components/ui/package-manager-tabs.tsx +226 -0
- package/dist/vendor/core-src/registry/components/ui/pager.tsx +102 -0
- package/dist/vendor/core-src/registry/components/ui/pagination.tsx +258 -0
- package/dist/vendor/core-src/registry/components/ui/pin-input.tsx +198 -0
- package/dist/vendor/core-src/registry/components/ui/popover.tsx +90 -0
- package/dist/vendor/core-src/registry/components/ui/progress.tsx +66 -0
- package/dist/vendor/core-src/registry/components/ui/radio-group.tsx +95 -0
- package/dist/vendor/core-src/registry/components/ui/rating.tsx +185 -0
- package/dist/vendor/core-src/registry/components/ui/resizable.tsx +195 -0
- package/dist/vendor/core-src/registry/components/ui/review-card.tsx +195 -0
- package/dist/vendor/core-src/registry/components/ui/rich-text-editor/bubble-menu.tsx +236 -0
- package/dist/vendor/core-src/registry/components/ui/rich-text-editor/editor.tsx +308 -0
- package/dist/vendor/core-src/registry/components/ui/rich-text-editor/extensions.ts +116 -0
- package/dist/vendor/core-src/registry/components/ui/rich-text-editor/footer.tsx +36 -0
- package/dist/vendor/core-src/registry/components/ui/rich-text-editor/image-dialog.tsx +75 -0
- package/dist/vendor/core-src/registry/components/ui/rich-text-editor/index.ts +11 -0
- package/dist/vendor/core-src/registry/components/ui/rich-text-editor/link-dialog.tsx +48 -0
- package/dist/vendor/core-src/registry/components/ui/rich-text-editor/markdown.ts +170 -0
- package/dist/vendor/core-src/registry/components/ui/rich-text-editor/slash-command.tsx +301 -0
- package/dist/vendor/core-src/registry/components/ui/rich-text-editor/table-controls.tsx +68 -0
- package/dist/vendor/core-src/registry/components/ui/rich-text-editor/toolbar.tsx +465 -0
- package/dist/vendor/core-src/registry/components/ui/rich-text-editor/use-editor.ts +231 -0
- package/dist/vendor/core-src/registry/components/ui/scroll-area.tsx +228 -0
- package/dist/vendor/core-src/registry/components/ui/section-heading.tsx +108 -0
- package/dist/vendor/core-src/registry/components/ui/select.tsx +156 -0
- package/dist/vendor/core-src/registry/components/ui/separator.tsx +37 -0
- package/dist/vendor/core-src/registry/components/ui/sheet.tsx +220 -0
- package/dist/vendor/core-src/registry/components/ui/sidebar.tsx +692 -0
- package/dist/vendor/core-src/registry/components/ui/skeleton.tsx +24 -0
- package/dist/vendor/core-src/registry/components/ui/slider.tsx +153 -0
- package/dist/vendor/core-src/registry/components/ui/spinner.tsx +41 -0
- package/dist/vendor/core-src/registry/components/ui/stat.tsx +245 -0
- package/dist/vendor/core-src/registry/components/ui/status.tsx +121 -0
- package/dist/vendor/core-src/registry/components/ui/steps.tsx +198 -0
- package/dist/vendor/core-src/registry/components/ui/switch.tsx +68 -0
- package/dist/vendor/core-src/registry/components/ui/table-of-contents.tsx +131 -0
- package/dist/vendor/core-src/registry/components/ui/table.tsx +160 -0
- package/dist/vendor/core-src/registry/components/ui/tabs.tsx +204 -0
- package/dist/vendor/core-src/registry/components/ui/textarea.tsx +82 -0
- package/dist/vendor/core-src/registry/components/ui/theme-toggle.tsx +238 -0
- package/dist/vendor/core-src/registry/components/ui/timeline.tsx +350 -0
- package/dist/vendor/core-src/registry/components/ui/titlebar-tabs.tsx +773 -0
- package/dist/vendor/core-src/registry/components/ui/titlebar.tsx +468 -0
- package/dist/vendor/core-src/registry/components/ui/toast.tsx +124 -0
- package/dist/vendor/core-src/registry/components/ui/toggle-group.tsx +203 -0
- package/dist/vendor/core-src/registry/components/ui/toggle.tsx +101 -0
- package/dist/vendor/core-src/registry/components/ui/tooltip.tsx +41 -0
- package/dist/vendor/core-src/registry/components/ui/updater-modal.tsx +254 -0
- package/dist/vendor/core-src/registry/index.ts +50 -0
- package/dist/vendor/core-src/registry/metadata.ts +742 -0
- package/dist/vendor/core-src/registry/providers/theme-provider.tsx +216 -0
- package/dist/vendor/core-src/registry/providers/theme-script.tsx +78 -0
- package/dist/vendor/core-src/registry/providers/theme-transitions.ts +139 -0
- package/dist/vendor/hooks-src/create-active-element.ts +51 -0
- package/dist/vendor/hooks-src/create-app-updater.ts +272 -0
- package/dist/vendor/hooks-src/create-audio-video.ts +444 -0
- package/dist/vendor/hooks-src/create-battery.ts +78 -0
- package/dist/vendor/hooks-src/create-chat-scroll.ts +113 -0
- package/dist/vendor/hooks-src/create-click-outside.ts +82 -0
- package/dist/vendor/hooks-src/create-clipboard.ts +69 -0
- package/dist/vendor/hooks-src/create-color-mode.ts +115 -0
- package/dist/vendor/hooks-src/create-controllable-signal.ts +56 -0
- package/dist/vendor/hooks-src/create-debounce.ts +90 -0
- package/dist/vendor/hooks-src/create-disclosure.ts +82 -0
- package/dist/vendor/hooks-src/create-document-tabs.ts +267 -0
- package/dist/vendor/hooks-src/create-document-title.ts +33 -0
- package/dist/vendor/hooks-src/create-drop-zone.ts +317 -0
- package/dist/vendor/hooks-src/create-event-source.ts +126 -0
- package/dist/vendor/hooks-src/create-favicon.ts +52 -0
- package/dist/vendor/hooks-src/create-fetch.ts +93 -0
- package/dist/vendor/hooks-src/create-focus-trap.ts +94 -0
- package/dist/vendor/hooks-src/create-form.ts +200 -0
- package/dist/vendor/hooks-src/create-fullscreen.ts +105 -0
- package/dist/vendor/hooks-src/create-geolocation.ts +140 -0
- package/dist/vendor/hooks-src/create-global-shortcut.ts +140 -0
- package/dist/vendor/hooks-src/create-hover.ts +88 -0
- package/dist/vendor/hooks-src/create-idle.ts +109 -0
- package/dist/vendor/hooks-src/create-infinite-scroll.ts +90 -0
- package/dist/vendor/hooks-src/create-input-mask.ts +109 -0
- package/dist/vendor/hooks-src/create-intersection-observer.ts +82 -0
- package/dist/vendor/hooks-src/create-keybindings.ts +148 -0
- package/dist/vendor/hooks-src/create-lock-scroll.ts +97 -0
- package/dist/vendor/hooks-src/create-long-press.ts +85 -0
- package/dist/vendor/hooks-src/create-media-query.ts +94 -0
- package/dist/vendor/hooks-src/create-mouse-position.ts +87 -0
- package/dist/vendor/hooks-src/create-network-status.ts +100 -0
- package/dist/vendor/hooks-src/create-orientation.ts +129 -0
- package/dist/vendor/hooks-src/create-pagination.ts +208 -0
- package/dist/vendor/hooks-src/create-permission.ts +91 -0
- package/dist/vendor/hooks-src/create-previous.ts +21 -0
- package/dist/vendor/hooks-src/create-resize-observer.ts +89 -0
- package/dist/vendor/hooks-src/create-scroll-into-view.ts +57 -0
- package/dist/vendor/hooks-src/create-scroll-position.ts +129 -0
- package/dist/vendor/hooks-src/create-storage.ts +106 -0
- package/dist/vendor/hooks-src/create-tauri-window.ts +628 -0
- package/dist/vendor/hooks-src/create-timer.ts +150 -0
- package/dist/vendor/hooks-src/create-tiptap-editor.ts +326 -0
- package/dist/vendor/hooks-src/create-undo-redo.ts +100 -0
- package/dist/vendor/hooks-src/create-web-notification.ts +111 -0
- package/dist/vendor/hooks-src/create-websocket.ts +179 -0
- package/dist/vendor/hooks-src/create-window-size.ts +41 -0
- package/dist/vendor/hooks-src/index.ts +48 -0
- package/package.json +87 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidebar-state.js","sourceRoot":"","sources":["../../src/navigation/sidebar-state.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,mBAAmB,CAAC,IAAiB,EAAE,UAAmB;IACxE,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,UAAU,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,IAAiB,EAAE,UAAmB;IAC9E,OAAO,mBAAmB,CAAC,IAAI,EAAE,UAAU,CAAC;WACvC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,yBAAyB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAiB;IAChD,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IACnE,OAAO,SAAS,IAAI,CAAC,IAAI,SAAS,IAAI,EAAE,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAiB;IACtD,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;AACrF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidebar-tree.d.ts","sourceRoot":"","sources":["../../src/navigation/sidebar-tree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,eAAe,EAAE,CAO3E"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function flattenSidebarItems(items) {
|
|
2
|
+
const flattened = [];
|
|
3
|
+
for (const item of items) {
|
|
4
|
+
if (item.href)
|
|
5
|
+
flattened.push({ title: item.title, href: item.href });
|
|
6
|
+
if (item.items)
|
|
7
|
+
flattened.push(...flattenSidebarItems(item.items));
|
|
8
|
+
}
|
|
9
|
+
return flattened;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=sidebar-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidebar-tree.js","sourceRoot":"","sources":["../../src/navigation/sidebar-tree.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,mBAAmB,CAAC,KAAoB;IACtD,MAAM,SAAS,GAAsB,EAAE,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI;YAAE,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACtE,IAAI,IAAI,CAAC,KAAK;YAAE,SAAS,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "accordion",
|
|
3
|
+
"title": "Accordion",
|
|
4
|
+
"description": "A vertically stacked set of interactive headings built on Kobalte primitives.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge",
|
|
9
|
+
"@kobalte/core"
|
|
10
|
+
],
|
|
11
|
+
"files": [
|
|
12
|
+
{
|
|
13
|
+
"path": "ui/accordion.tsx",
|
|
14
|
+
"content": "import { splitProps, type JSX, type ValidComponent } from \"solid-js\";\nimport * as AccordionPrimitive from \"@kobalte/core/accordion\";\nimport type { PolymorphicProps } from \"@kobalte/core/polymorphic\";\nimport { cn } from \"@/lib/cn\";\n\nexport type AccordionRootProps<T extends ValidComponent = \"div\"> = Omit<\n AccordionPrimitive.AccordionRootProps<T>,\n \"value\" | \"defaultValue\"\n> & {\n /** Accordion mode: \"single\" allows one open item, \"multiple\" allows many */\n type?: \"single\" | \"multiple\";\n /** Controlled value (single string or array of strings) */\n value?: string | string[];\n /** Default initial value (single string or array of strings) */\n defaultValue?: string | string[];\n class?: string;\n};\n\n/**\n * Root Accordion component built on top of Kobalte headless primitives.\n */\nexport const Accordion = <T extends ValidComponent = \"div\">(\n props: PolymorphicProps<T, AccordionRootProps<T>>\n) => {\n const [local, rest] = splitProps(props as AccordionRootProps, [\n \"class\",\n \"type\",\n \"multiple\",\n ]);\n\n // Support both `type=\"multiple\"` and `multiple={true}`\n const isMultiple = () => local.multiple ?? local.type === \"multiple\";\n\n return (\n <AccordionPrimitive.Root\n multiple={isMultiple()}\n class={cn(\"w-full divide-y divide-border\", local.class)}\n {...(rest as any)}\n />\n );\n};\n\nexport type AccordionItemProps<T extends ValidComponent = \"div\"> =\n AccordionPrimitive.AccordionItemProps<T> & {\n class?: string;\n value: string;\n };\n\n/**\n * Individual Accordion section item wrapper.\n */\nexport const AccordionItem = <T extends ValidComponent = \"div\">(\n props: PolymorphicProps<T, AccordionItemProps<T>>\n) => {\n const [local, rest] = splitProps(props as AccordionItemProps, [\"class\"]);\n\n return (\n <AccordionPrimitive.Item\n class={cn(\"border-b border-border\", local.class)}\n {...rest}\n />\n );\n};\n\nexport type AccordionTriggerProps<T extends ValidComponent = \"button\"> =\n AccordionPrimitive.AccordionTriggerProps<T> & {\n class?: string;\n children?: JSX.Element;\n };\n\n/**\n * Header trigger button toggling the expansion of an AccordionItem.\n */\nexport const AccordionTrigger = <T extends ValidComponent = \"button\">(\n props: PolymorphicProps<T, AccordionTriggerProps<T>>\n) => {\n const [local, rest] = splitProps(props as AccordionTriggerProps, [\"class\", \"children\"]);\n\n return (\n <AccordionPrimitive.Header class=\"flex\">\n <AccordionPrimitive.Trigger\n class={cn(\n \"flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-expanded]>svg]:rotate-180 cursor-pointer text-foreground\",\n local.class\n )}\n {...rest}\n >\n {local.children}\n <svg\n class=\"h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n};\n\nexport type AccordionContentProps<T extends ValidComponent = \"div\"> =\n AccordionPrimitive.AccordionContentProps<T> & {\n class?: string;\n children?: JSX.Element;\n };\n\n/**\n * Collapsible content panel revealed when the associated AccordionItem is open.\n */\nexport const AccordionContent = <T extends ValidComponent = \"div\">(\n props: PolymorphicProps<T, AccordionContentProps<T>>\n) => {\n const [local, rest] = splitProps(props as AccordionContentProps, [\"class\", \"children\"]);\n\n return (\n <AccordionPrimitive.Content\n class={cn(\n \"overflow-hidden text-sm text-muted-foreground transition-all\",\n local.class\n )}\n {...rest}\n >\n <div class=\"pb-4 pt-0\">{local.children}</div>\n </AccordionPrimitive.Content>\n );\n};",
|
|
15
|
+
"type": "registry:ui"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "alert",
|
|
3
|
+
"title": "Alert",
|
|
4
|
+
"description": "Displays a callout banner for user feedback with variants, dismiss button, and timer.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge",
|
|
9
|
+
"class-variance-authority"
|
|
10
|
+
],
|
|
11
|
+
"files": [
|
|
12
|
+
{
|
|
13
|
+
"path": "ui/alert.tsx",
|
|
14
|
+
"content": "import {\n createSignal,\n splitProps,\n onMount,\n onCleanup,\n Show,\n type Component,\n type JSX,\n} from \"solid-js\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/cn\";\n\n/**\n * CVA variants for Alert status styles and color themes.\n */\nexport const alertVariants = cva(\n \"relative w-full rounded-lg border p-4 transition-all duration-200 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground\",\n {\n variants: {\n variant: {\n default:\n \"bg-background text-foreground border-border\",\n info:\n \"bg-blue-50 text-blue-900 border-blue-200 dark:bg-blue-950/50 dark:text-blue-200 dark:border-blue-900/50\",\n success:\n \"bg-emerald-50 text-emerald-900 border-emerald-200 dark:bg-emerald-950/50 dark:text-emerald-200 dark:border-emerald-900/50\",\n warning:\n \"bg-amber-50 text-amber-900 border-amber-200 dark:bg-amber-950/50 dark:text-amber-200 dark:border-amber-950/50\",\n destructive:\n \"bg-destructive/15 text-destructive border-destructive/30\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n);\n\nexport interface AlertProps\n extends JSX.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof alertVariants> {\n /** Display an interactive close (X) button */\n closable?: boolean;\n /** Auto-dismiss timer duration in milliseconds */\n duration?: number;\n /** Callback fired when the alert is dismissed */\n onClose?: () => void;\n class?: string;\n}\n\n/**\n * Nikala UI Alert notification banner with auto-dismiss timer and theme variants.\n */\nexport const Alert: Component<AlertProps> = (props) => {\n const [local, rest] = splitProps(props, [\n \"variant\",\n \"closable\",\n \"duration\",\n \"onClose\",\n \"class\",\n \"children\",\n ]);\n\n const [isVisible, setIsVisible] = createSignal(true);\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const handleClose = () => {\n setIsVisible(false);\n if (typeof local.onClose === \"function\") {\n local.onClose();\n }\n };\n\n onMount(() => {\n if (local.duration && local.duration > 0) {\n timer = setTimeout(() => {\n handleClose();\n }, local.duration);\n }\n });\n\n onCleanup(() => {\n if (timer) clearTimeout(timer);\n });\n\n return (\n <Show when={isVisible()}>\n <div\n role=\"alert\"\n class={cn(\n alertVariants({ variant: local.variant }),\n \"animate-in fade-in-0 duration-200\",\n local.class\n )}\n {...rest}\n >\n {local.children}\n <Show when={local.closable || typeof local.onClose === \"function\"}>\n <button\n type=\"button\"\n aria-label=\"Close alert\"\n onClick={handleClose}\n class=\"absolute right-3 top-3 rounded-md p-1 text-zinc-500 hover:bg-zinc-100 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-50 transition-colors cursor-pointer\"\n >\n <svg\n class=\"h-4 w-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </Show>\n </div>\n </Show>\n );\n};\n\nexport interface AlertTitleProps extends JSX.HTMLAttributes<HTMLHeadingElement> {\n class?: string;\n}\n\n/**\n * Header title element for the Alert banner.\n */\nexport const AlertTitle: Component<AlertTitleProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n\n return (\n <h5\n class={cn(\"mb-1 font-medium leading-none tracking-tight text-foreground\", local.class)}\n {...rest}\n />\n );\n};\n\nexport interface AlertDescriptionProps extends JSX.HTMLAttributes<HTMLDivElement> {\n class?: string;\n}\n\n/**\n * Body text content for the Alert banner.\n */\nexport const AlertDescription: Component<AlertDescriptionProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n\n return (\n <div\n class={cn(\"text-sm [&_p]:leading-relaxed text-muted-foreground\", local.class)}\n {...rest}\n />\n );\n};",
|
|
15
|
+
"type": "registry:ui"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "api-table",
|
|
3
|
+
"title": "API Table",
|
|
4
|
+
"description": "A structured, clean API reference table component for documenting props, options, and events.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge"
|
|
9
|
+
],
|
|
10
|
+
"registryDependencies": [
|
|
11
|
+
"table",
|
|
12
|
+
"section-heading"
|
|
13
|
+
],
|
|
14
|
+
"files": [
|
|
15
|
+
{
|
|
16
|
+
"path": "ui/api-table.tsx",
|
|
17
|
+
"content": "import {\n splitProps,\n For,\n Show,\n type JSX,\n type Component,\n} from \"solid-js\";\nimport { SectionHeading } from \"@/components/ui/section-heading\";\nimport {\n Table,\n TableHeader,\n TableBody,\n TableRow,\n TableHead,\n TableCell,\n} from \"@/components/ui/table\";\nimport { cn } from \"@/lib/cn\";\n\nexport interface ApiTableItem {\n /** Property, attribute, or method name */\n prop: string;\n /** TypeScript type definition string */\n type: string;\n /** Default value if optional */\n default?: string;\n /** Detailed description of purpose and usage */\n description: string;\n /** Whether the property is strictly required */\n required?: boolean;\n}\n\nexport interface ApiTableProps extends JSX.HTMLAttributes<HTMLDivElement> {\n /** Title header for this API section (e.g. component or interface name) */\n title?: string;\n /** Subtitle or explanatory note */\n description?: string;\n /** Badge label next to the title (defaults to \"Props\") */\n badge?: string;\n /** List of API properties to render in the table */\n items: ApiTableItem[];\n class?: string;\n}\n\n/**\n * Clean, structured API reference table component composed from Table and Badge primitives.\n */\nexport const ApiTable: Component<ApiTableProps> = (props) => {\n const [local, rest] = splitProps(props, [\n \"title\",\n \"description\",\n \"badge\",\n \"items\",\n \"class\",\n ]);\n\n return (\n <div class={cn(\"my-6 space-y-3\", local.class)} {...rest}>\n {/* Header */}\n <Show when={local.title}>\n <SectionHeading\n variant=\"compact\"\n title={local.title!}\n badge={local.badge || \"Props\"}\n description={local.description}\n />\n </Show>\n\n {/* Responsive Table Container Composed from Nikala Table Primitives */}\n <div class=\"rounded-lg border border-border bg-card/50 shadow-2xs overflow-hidden\">\n <Table class=\"text-xs\">\n <TableHeader class=\"bg-muted/40 font-mono text-[11px] uppercase tracking-wider text-muted-foreground select-none\">\n <TableRow class=\"hover:bg-transparent\">\n <TableHead class=\"h-9 px-4 font-semibold\">Prop</TableHead>\n <TableHead class=\"h-9 px-4 font-semibold\">Type</TableHead>\n <TableHead class=\"h-9 px-4 font-semibold\">Default</TableHead>\n <TableHead class=\"h-9 px-4 font-semibold\">Description</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody class=\"font-mono text-xs\">\n <For each={local.items}>\n {(item) => (\n <TableRow class=\"transition-colors hover:bg-muted/20\">\n <TableCell class=\"px-4 py-3 font-semibold text-primary\">\n <span class=\"inline-flex items-center gap-1\">\n {item.prop}\n <Show when={item.required}>\n <span class=\"text-rose-500 font-bold\" title=\"Required\">*</span>\n </Show>\n </span>\n </TableCell>\n <TableCell class=\"px-4 py-3 text-muted-foreground\">\n <code class=\"rounded-md bg-muted px-1.5 py-0.5 font-mono text-[11px] text-foreground\">\n {item.type}\n </code>\n </TableCell>\n <TableCell class=\"px-4 py-3 text-muted-foreground\">\n <Show\n when={item.default}\n fallback={<span class=\"text-muted-foreground/40 font-mono\">-</span>}\n >\n <code class=\"rounded-md bg-muted/60 px-1 py-0.5 font-mono text-[11px]\">\n {item.default}\n </code>\n </Show>\n </TableCell>\n <TableCell class=\"px-4 py-3 font-sans font-normal leading-relaxed text-muted-foreground\">\n {item.description}\n </TableCell>\n </TableRow>\n )}\n </For>\n </TableBody>\n </Table>\n </div>\n </div>\n );\n};\n",
|
|
18
|
+
"type": "registry:ui"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aspect-ratio",
|
|
3
|
+
"title": "Aspect Ratio",
|
|
4
|
+
"description": "Displays content within a specific aspect ratio using CSS aspect-ratio while preventing layout shifts.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge"
|
|
9
|
+
],
|
|
10
|
+
"files": [
|
|
11
|
+
{
|
|
12
|
+
"path": "ui/aspect-ratio.tsx",
|
|
13
|
+
"content": "import { splitProps, type Component, type JSX } from \"solid-js\";\nimport { cn } from \"@/lib/cn\";\n\nexport interface AspectRatioProps extends JSX.HTMLAttributes<HTMLDivElement> {\n ratio?: number;\n class?: string;\n children?: JSX.Element;\n}\n\n/**\n * Nikala UI AspectRatio Component.\n * Displays content within a specific aspect ratio (e.g. 16/9, 4/3, 1/1) using CSS aspect-ratio.\n */\nexport const AspectRatio: Component<AspectRatioProps> = (props) => {\n const [local, rest] = splitProps(props, [\"ratio\", \"class\", \"children\", \"style\"]);\n\n const computedRatio = () => (local.ratio !== undefined ? local.ratio : 16 / 9);\n\n return (\n <div\n class={cn(\"relative w-full overflow-hidden\", local.class)}\n style={{\n \"aspect-ratio\": `${computedRatio()}`,\n ...(typeof local.style === \"object\" ? local.style : {}),\n }}\n {...rest}\n >\n {local.children}\n </div>\n );\n};\n",
|
|
14
|
+
"type": "registry:ui"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "avatar",
|
|
3
|
+
"title": "Avatar",
|
|
4
|
+
"description": "An image element with fallback representation for representing users.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge"
|
|
9
|
+
],
|
|
10
|
+
"files": [
|
|
11
|
+
{
|
|
12
|
+
"path": "ui/avatar.tsx",
|
|
13
|
+
"content": "import {\n createSignal,\n createEffect,\n Show,\n splitProps,\n type Component,\n type JSX,\n} from \"solid-js\";\nimport { cn } from \"@/lib/cn\";\n\nexport interface AvatarProps extends JSX.HTMLAttributes<HTMLDivElement> {\n class?: string;\n}\n\n/**\n * Root Avatar container component.\n */\nexport const Avatar: Component<AvatarProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n\n return (\n <div\n class={cn(\n \"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-lg border border-border bg-muted\",\n local.class\n )}\n {...rest}\n />\n );\n};\n\nexport interface AvatarImageProps\n extends JSX.ImgHTMLAttributes<HTMLImageElement> {\n class?: string;\n}\n\n/**\n * Image element for the Avatar component with background status loader.\n */\nexport const AvatarImage: Component<AvatarImageProps> = (props) => {\n const [local, rest] = splitProps(props, [\n \"class\",\n \"src\",\n \"alt\",\n \"onLoad\",\n \"onError\",\n ]);\n const [status, setStatus] = createSignal<\"loading\" | \"loaded\" | \"error\">(\n \"loading\"\n );\n\n /* Pre-test image loading in background JS to prevent native broken icon flashes */\n createEffect(() => {\n const src = local.src;\n if (!src) {\n setStatus(\"error\");\n return;\n }\n\n const img = new Image();\n img.src = src;\n img.onload = () => setStatus(\"loaded\");\n img.onerror = () => setStatus(\"error\");\n });\n\n const handleLoad: JSX.EventHandlerUnion<HTMLImageElement, Event> = (e) => {\n setStatus(\"loaded\");\n if (typeof local.onLoad === \"function\") {\n (local.onLoad as (e: Event) => void)(e);\n }\n };\n\n const handleError: JSX.EventHandlerUnion<HTMLImageElement, Event> = (e) => {\n setStatus(\"error\");\n if (typeof local.onError === \"function\") {\n (local.onError as (e: Event) => void)(e);\n }\n };\n\n return (\n <Show when={status() === \"loaded\"}>\n <img\n src={local.src}\n alt={local.alt}\n class={cn(\"aspect-square h-full w-full object-cover\", local.class)}\n onLoad={handleLoad}\n onError={handleError}\n {...rest}\n />\n </Show>\n );\n};\n\nexport interface AvatarFallbackProps\n extends JSX.HTMLAttributes<HTMLDivElement> {\n class?: string;\n}\n\n/**\n * Fallback container for rendering initials or icons when avatar image is missing/broken.\n */\nexport const AvatarFallback: Component<AvatarFallbackProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n\n return (\n <div\n class={cn(\n \"flex h-full w-full items-center justify-center bg-muted text-sm font-medium text-muted-foreground select-none\",\n local.class\n )}\n {...rest}\n />\n );\n};",
|
|
14
|
+
"type": "registry:ui"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "badge",
|
|
3
|
+
"title": "Badge",
|
|
4
|
+
"description": "A small badge component for status indicators and tags.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge",
|
|
9
|
+
"class-variance-authority"
|
|
10
|
+
],
|
|
11
|
+
"files": [
|
|
12
|
+
{
|
|
13
|
+
"path": "ui/badge.tsx",
|
|
14
|
+
"content": "import { splitProps, type Component, type JSX } from \"solid-js\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/cn\";\n\n/**\n * Class variance authority configuration for badge styling variants.\n */\nexport const badgeVariants = cva(\n \"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\",\n {\n variants: {\n variant: {\n default:\n \"border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80\",\n secondary:\n \"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n destructive:\n \"border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80\",\n outline:\n \"text-foreground border-border\",\n success:\n \"border-transparent bg-green-600 text-zinc-50 shadow-sm hover:bg-green-600/90 dark:bg-green-900 dark:text-zinc-50 dark:hover:bg-green-900/90\",\n warning:\n \"border-transparent bg-yellow-600 text-zinc-50 shadow-sm hover:bg-yellow-600/90 dark:bg-yellow-900 dark:text-zinc-50 dark:hover:bg-yellow-900/90\",\n info:\n \"border-transparent bg-blue-600 text-zinc-50 shadow-sm hover:bg-blue-600/90 dark:bg-blue-900 dark:text-zinc-50 dark:hover:bg-blue-900/90\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n);\n\n/**\n * Props interface for the Badge component extending standard HTML div attributes.\n */\nexport interface BadgeProps\n extends JSX.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof badgeVariants> {\n class?: string;\n}\n\n/**\n * Nikala UI Badge component built for SolidJS with Tailwind CSS v4 styling.\n */\nexport const Badge: Component<BadgeProps> = (props) => {\n // Use splitProps to preserve SolidJS reactivity\n const [local, rest] = splitProps(props, [\"variant\", \"class\", \"children\"]);\n\n return (\n <div class={cn(badgeVariants({ variant: local.variant }), local.class)} {...rest}>\n {local.children}\n </div>\n );\n};",
|
|
15
|
+
"type": "registry:ui"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "banner",
|
|
3
|
+
"title": "Banner",
|
|
4
|
+
"description": "An announcement banner with sticky positioning, dismissal persistence, auto-hide timer, Lucide icons, and variant styles.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge",
|
|
9
|
+
"class-variance-authority",
|
|
10
|
+
"lucide-solid"
|
|
11
|
+
],
|
|
12
|
+
"files": [
|
|
13
|
+
{
|
|
14
|
+
"path": "ui/banner.tsx",
|
|
15
|
+
"content": "// src/components/ui/banner.tsx\nimport {\n createSignal,\n onMount,\n onCleanup,\n Show,\n splitProps,\n type Component,\n type JSX,\n} from \"solid-js\";\nimport { Dynamic } from \"solid-js/web\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { Info, AlertTriangle, CheckCircle, AlertCircle, X } from \"lucide-solid\";\nimport { cn } from \"@/lib/cn\";\n\nexport const bannerVariants = cva(\n \"relative flex w-full items-center justify-between gap-3 px-4 py-2.5 text-sm transition-all duration-300 ease-in-out\",\n {\n variants: {\n variant: {\n default:\n \"bg-zinc-900 text-zinc-50 dark:bg-zinc-100 dark:text-zinc-900\",\n warning:\n \"bg-amber-500/15 text-amber-900 border-b border-amber-500/20 dark:text-amber-200\",\n info:\n \"bg-sky-500/15 text-sky-900 border-b border-sky-500/20 dark:text-sky-200\",\n success:\n \"bg-emerald-500/15 text-emerald-900 border-b border-emerald-500/20 dark:text-emerald-200\",\n destructive:\n \"bg-rose-500/15 text-rose-900 border-b border-rose-500/20 dark:text-rose-200\",\n },\n sticky: {\n true: \"sticky top-0 z-50 backdrop-blur-sm\",\n false: \"relative\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n sticky: false,\n },\n }\n);\n\nexport interface BannerProps\n extends JSX.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof bannerVariants> {\n dismissible?: boolean;\n autoHideDelay?: number;\n storageKey?: string;\n showIcon?: boolean;\n icon?: Component<{ class?: string }>;\n link?: string;\n linkText?: string;\n linkTarget?: string;\n onDismiss?: () => void;\n class?: string;\n}\n\n/**\n * Nikala UI Banner Component.\n */\nexport const Banner: Component<BannerProps> = (props) => {\n const [local, rest] = splitProps(props, [\n \"variant\",\n \"sticky\",\n \"dismissible\",\n \"autoHideDelay\",\n \"storageKey\",\n \"showIcon\",\n \"icon\",\n \"link\",\n \"linkText\",\n \"linkTarget\",\n \"onDismiss\",\n \"class\",\n \"children\",\n ]);\n\n const [visible, setVisible] = createSignal(true);\n let timerId: ReturnType<typeof setTimeout> | undefined;\n\n onMount(() => {\n if (local.storageKey) {\n try {\n const isDismissed = localStorage.getItem(local.storageKey);\n if (isDismissed === \"true\") {\n setVisible(false);\n return;\n }\n } catch (e) { }\n }\n\n if (local.autoHideDelay && local.autoHideDelay > 0) {\n timerId = setTimeout(() => {\n handleDismiss();\n }, local.autoHideDelay);\n }\n });\n\n onCleanup(() => {\n if (timerId) clearTimeout(timerId);\n });\n\n const handleDismiss = () => {\n setVisible(false);\n\n if (local.storageKey) {\n try {\n localStorage.setItem(local.storageKey, \"true\");\n } catch (e) {}\n }\n\n if (typeof local.onDismiss === \"function\") {\n local.onDismiss();\n }\n };\n\n /* Default icon selector based on banner variant */\n const getDefaultIcon = () => {\n switch (local.variant) {\n case \"warning\":\n return AlertTriangle;\n case \"success\":\n return CheckCircle;\n case \"destructive\":\n return AlertCircle;\n default:\n return Info;\n }\n };\n\n const activeIcon = () => local.icon || getDefaultIcon();\n const shouldShowIcon = () => local.showIcon !== false;\n const shouldBeDismissible = () => local.dismissible !== false;\n\n return (\n <Show when={visible()}>\n <div\n class={cn(\n bannerVariants({ variant: local.variant, sticky: local.sticky }),\n local.class\n )}\n {...rest}\n >\n <div class=\"flex flex-1 items-center justify-center gap-2 text-center sm:text-left\">\n {/* Dynamic Lucide Icon */}\n <Show when={shouldShowIcon()}>\n <span class=\"inline-flex shrink-0 items-center justify-center\">\n <Dynamic component={activeIcon()} class=\"h-4 w-4 opacity-80\" />\n </span>\n </Show>\n\n {/* Text Content */}\n <div class=\"flex-1 text-xs font-medium sm:text-sm\">\n {local.children}\n </div>\n\n {/* Action Link */}\n <Show when={local.link}>\n <div class=\"shrink-0\">\n <a\n href={local.link}\n target={local.linkTarget || \"_blank\"}\n rel=\"noreferrer\"\n class=\"underline font-semibold hover:opacity-80 transition-opacity\"\n >\n {local.linkText || \"Learn more\"}\n </a>\n </div>\n </Show>\n </div>\n\n {/* Close Button */}\n <Show when={shouldBeDismissible()}>\n <button\n type=\"button\"\n onClick={handleDismiss}\n class=\"shrink-0 rounded-md p-1 opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring\"\n aria-label=\"Dismiss banner\"\n >\n <X class=\"h-4 w-4\" />\n </button>\n </Show>\n </div>\n </Show>\n );\n};",
|
|
16
|
+
"type": "registry:ui"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "breadcrumb",
|
|
3
|
+
"title": "Breadcrumb",
|
|
4
|
+
"description": "Displays the path to the current resource using a hierarchy of links.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge"
|
|
9
|
+
],
|
|
10
|
+
"files": [
|
|
11
|
+
{
|
|
12
|
+
"path": "ui/breadcrumb.tsx",
|
|
13
|
+
"content": "import { splitProps, type Component, type JSX } from \"solid-js\";\nimport { cn } from \"@/lib/cn\";\n\nexport interface BreadcrumbProps extends JSX.HTMLAttributes<HTMLElement> {\n class?: string;\n}\n\n/**\n * Root navigation container for the Nikala UI Breadcrumb hierarchy.\n */\nexport const Breadcrumb: Component<BreadcrumbProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n return <nav aria-label=\"breadcrumb\" class={cn(\"relative w-full\", local.class)} {...rest} />;\n};\n\nexport interface BreadcrumbListProps extends JSX.HTMLAttributes<HTMLOListElement> {\n class?: string;\n}\n\n/**\n * Ordered list container housing all breadcrumb path items.\n */\nexport const BreadcrumbList: Component<BreadcrumbListProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n return (\n <ol\n class={cn(\n \"flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground break-words sm:gap-2.5\",\n local.class\n )}\n {...rest}\n />\n );\n};\n\nexport interface BreadcrumbItemProps extends JSX.HTMLAttributes<HTMLLIElement> {\n class?: string;\n}\n\n/**\n * Individual list item element wrapper in the breadcrumb hierarchy.\n */\nexport const BreadcrumbItem: Component<BreadcrumbItemProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n return <li class={cn(\"inline-flex items-center gap-1.5\", local.class)} {...rest} />;\n};\n\nexport interface BreadcrumbLinkProps extends JSX.AnchorHTMLAttributes<HTMLAnchorElement> {\n class?: string;\n}\n\n/**\n * Clickable breadcrumb trail link element.\n */\nexport const BreadcrumbLink: Component<BreadcrumbLinkProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n return (\n <a\n class={cn(\n \"transition-colors hover:text-foreground underline-offset-4 hover:underline\",\n local.class\n )}\n {...rest}\n />\n );\n};\n\nexport interface BreadcrumbPageProps extends JSX.HTMLAttributes<HTMLSpanElement> {\n class?: string;\n}\n\n/**\n * Non-clickable active page indicator in breadcrumb hierarchy.\n */\nexport const BreadcrumbPage: Component<BreadcrumbPageProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n return (\n <span\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n class={cn(\"font-normal text-foreground\", local.class)}\n {...rest}\n />\n );\n};\n\nexport interface BreadcrumbSeparatorProps extends JSX.HTMLAttributes<HTMLLIElement> {\n class?: string;\n}\n\n/**\n * Visual separator icon rendered between breadcrumb path links.\n */\nexport const BreadcrumbSeparator: Component<BreadcrumbSeparatorProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\", \"children\"]);\n return (\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n class={cn(\"[&>svg]:size-3.5 text-muted-foreground\", local.class)}\n {...rest}\n >\n {local.children || (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5l7 7-7 7\" />\n </svg>\n )}\n </li>\n );\n};\n\nexport interface BreadcrumbEllipsisProps extends JSX.HTMLAttributes<HTMLSpanElement> {\n class?: string;\n}\n\n/**\n * Ellipsis element representing truncated intermediate breadcrumb items.\n */\nexport const BreadcrumbEllipsis: Component<BreadcrumbEllipsisProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n return (\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n class={cn(\"flex h-9 w-9 items-center justify-center text-muted-foreground\", local.class)}\n {...rest}\n >\n <svg class=\"h-4 w-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"19\" cy=\"12\" r=\"1\" />\n <circle cx=\"5\" cy=\"12\" r=\"1\" />\n </svg>\n </span>\n );\n};",
|
|
14
|
+
"type": "registry:ui"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bubble",
|
|
3
|
+
"title": "Bubble",
|
|
4
|
+
"description": "Chat message bubble container supporting variants, grouped consecutive bubbles, and emoji reactions.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge",
|
|
9
|
+
"class-variance-authority"
|
|
10
|
+
],
|
|
11
|
+
"files": [
|
|
12
|
+
{
|
|
13
|
+
"path": "ui/bubble.tsx",
|
|
14
|
+
"content": "import {\n splitProps,\n type Component,\n type JSX,\n type ParentComponent,\n useContext,\n} from \"solid-js\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/cn\";\n\n/* --- 1. Bubble Variants --- */\nexport const bubbleVariants = cva(\n \"relative max-w-full rounded-lg transition-colors break-words text-left select-text\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground shadow-2xs\",\n muted: \"bg-muted text-foreground border border-border/50 shadow-2xs\",\n outline: \"border border-border bg-background text-foreground shadow-2xs\",\n ghost: \"bg-transparent text-foreground\",\n },\n size: {\n sm: \"px-3 py-1.5 text-xs\",\n default: \"px-4 py-2.5 text-sm\",\n lg: \"px-5 py-3 text-base\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n);\n\n/* --- 2. BubbleGroup --- */\nexport interface BubbleGroupProps extends JSX.HTMLAttributes<HTMLDivElement> {\n class?: string;\n}\n\nexport const BubbleGroup: ParentComponent<BubbleGroupProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\", \"children\"]);\n\n return (\n <div\n class={cn(\"flex flex-col gap-1 w-full\", local.class)}\n {...rest}\n >\n {local.children}\n </div>\n );\n};\n\n/* --- 3. Bubble --- */\nexport interface BubbleProps\n extends JSX.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof bubbleVariants> {\n class?: string;\n}\n\nexport const Bubble: ParentComponent<BubbleProps> = (props) => {\n const [local, rest] = splitProps(props, [\"variant\", \"size\", \"class\", \"children\"]);\n\n return (\n <div\n class={cn(\n bubbleVariants({\n variant: local.variant,\n size: local.size,\n }),\n local.class\n )}\n {...rest}\n >\n {local.children}\n </div>\n );\n};\n\n/* --- 4. BubbleContent --- */\nexport interface BubbleContentProps extends JSX.HTMLAttributes<HTMLDivElement> {\n class?: string;\n}\n\nexport const BubbleContent: ParentComponent<BubbleContentProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\", \"children\"]);\n\n return (\n <div\n class={cn(\"leading-relaxed\", local.class)}\n {...rest}\n >\n {local.children}\n </div>\n );\n};\n\n/* --- 5. BubbleReactions --- */\nexport interface BubbleReactionsProps extends JSX.HTMLAttributes<HTMLDivElement> {\n class?: string;\n}\n\nexport const BubbleReactions: ParentComponent<BubbleReactionsProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\", \"children\"]);\n\n return (\n <div\n class={cn(\"flex items-center gap-1.5 pt-2 mt-2 border-t border-border/30 z-10 flex-wrap\", local.class)}\n {...rest}\n >\n {local.children}\n </div>\n );\n};\n\n/* --- 6. BubbleReaction --- */\nexport interface BubbleReactionProps extends JSX.ButtonHTMLAttributes<HTMLButtonElement> {\n active?: boolean;\n count?: number;\n class?: string;\n}\n\nexport const BubbleReaction: ParentComponent<BubbleReactionProps> = (props) => {\n const [local, rest] = splitProps(props, [\"active\", \"count\", \"class\", \"children\"]);\n\n return (\n <button\n type=\"button\"\n data-active={local.active ? \"true\" : \"false\"}\n class={cn(\n \"inline-flex items-center gap-1.5 rounded-md border border-border/70 bg-background/80 px-2 py-1 text-xs text-foreground shadow-2xs transition-all hover:bg-accent hover:border-primary/40 cursor-pointer select-none\",\n local.active && \"border-primary/40 bg-primary/10 text-primary font-medium\",\n local.class\n )}\n {...rest}\n >\n <span class=\"text-xs leading-none\">{local.children}</span>\n {local.count !== undefined && (\n <span class=\"text-[11px] font-mono leading-none text-muted-foreground\">{local.count}</span>\n )}\n </button>\n );\n};\n",
|
|
15
|
+
"type": "registry:ui"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "button-group",
|
|
3
|
+
"title": "Button Group",
|
|
4
|
+
"description": "Groups related buttons into a connected horizontal or vertical control.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge"
|
|
9
|
+
],
|
|
10
|
+
"registryDependencies": [
|
|
11
|
+
"button"
|
|
12
|
+
],
|
|
13
|
+
"files": [
|
|
14
|
+
{
|
|
15
|
+
"path": "ui/button-group.tsx",
|
|
16
|
+
"content": "import { splitProps, type Component, type JSX } from \"solid-js\";\nimport { cn } from \"@/lib/cn\";\n\nexport interface ButtonGroupProps extends JSX.HTMLAttributes<HTMLDivElement> {\n /** Controls whether grouped buttons are arranged in a row or column. */\n orientation?: \"horizontal\" | \"vertical\";\n class?: string;\n}\n\n/**\n * Groups adjacent buttons into a connected control with shared borders and radii.\n *\n * ButtonGroup is intentionally presentational. Use Button for individual actions\n * and compose the group with the same reactive state as the surrounding feature.\n */\nexport const ButtonGroup: Component<ButtonGroupProps> = (props) => {\n const [local, rest] = splitProps(props, [\n \"orientation\",\n \"class\",\n \"children\",\n ]);\n\n const orientation = () => local.orientation ?? \"horizontal\";\n\n return (\n <div\n role=\"group\"\n data-orientation={orientation()}\n class={cn(\n \"isolate inline-flex\",\n orientation() === \"horizontal\"\n ? \"flex-row [&>button:not(:first-child)]:-ml-px [&>button:not(:first-child)]:rounded-l-none [&>button:not(:last-child)]:rounded-r-none\"\n : \"flex-col [&>button:not(:first-child)]:-mt-px [&>button:not(:first-child)]:rounded-t-none [&>button:not(:last-child)]:rounded-b-none\",\n \"[&>button:focus-visible]:z-10\",\n local.class\n )}\n {...rest}\n >\n {local.children}\n </div>\n );\n};\n",
|
|
17
|
+
"type": "registry:ui"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "button",
|
|
3
|
+
"title": "Button",
|
|
4
|
+
"description": "An interactive button component with variant and size options.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge",
|
|
9
|
+
"class-variance-authority"
|
|
10
|
+
],
|
|
11
|
+
"registryDependencies": [
|
|
12
|
+
"spinner"
|
|
13
|
+
],
|
|
14
|
+
"files": [
|
|
15
|
+
{
|
|
16
|
+
"path": "ui/button.tsx",
|
|
17
|
+
"content": "import { Show, splitProps, type Component, type JSX } from \"solid-js\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/cn\";\nimport { Spinner } from \"@/components/ui/spinner\";\n\n/**\n * Class variance authority configuration for button styling variants and sizes.\n */\nexport const buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 cursor-pointer\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow hover:bg-primary/90 border border-primary/50\",\n destructive:\n \"bg-red-600 text-zinc-50 shadow-sm hover:bg-red-600/90 dark:bg-red-900 dark:text-zinc-50 dark:hover:bg-red-900/90\",\n outline:\n \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80 border border-border\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n success: \"*:bg-green-600 text-zinc-50 shadow-sm hover:bg-green-600/90 dark:bg-green-900 dark:text-zinc-50 dark:hover:bg-green-900/90\",\n warning: \"*:bg-yellow-600 text-zinc-50 shadow-sm hover:bg-yellow-600/90 dark:bg-yellow-900 dark:text-zinc-50 dark:hover:bg-yellow-900/90\",\n info: \"*:bg-blue-600 text-zinc-50 shadow-sm hover:bg-blue-600/90 dark:bg-blue-900 dark:text-zinc-50 dark:hover:bg-blue-900/90\",\n },\n size: {\n xs: \"h-6 rounded-md px-2 text-xs\",\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"h-9 w-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n);\n\n/**\n * Props interface for the Button component extending standard HTML button attributes.\n */\nexport interface ButtonProps\n extends JSX.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n /** Shows a loading spinner and prevents repeated clicks while active. */\n loading?: boolean;\n class?: string;\n}\n\n/**\n * Nikala UI Button component built for SolidJS with Tailwind CSS v4 styling.\n */\nexport const Button: Component<ButtonProps> = (props) => {\n // Use splitProps to preserve SolidJS reactivity for destructured props\n const [local, rest] = splitProps(props, [\n \"variant\",\n \"size\",\n \"class\",\n \"children\",\n \"loading\",\n \"disabled\",\n ]);\n\n return (\n <button\n class={cn(buttonVariants({ variant: local.variant, size: local.size }), local.class)}\n disabled={local.disabled || local.loading}\n aria-busy={local.loading ? \"true\" : undefined}\n {...rest}\n >\n <Show when={local.loading}>\n <Spinner size=\"sm\" class=\"text-current\" />\n </Show>\n {local.children}\n </button>\n );\n};\n",
|
|
18
|
+
"type": "registry:ui"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "callout",
|
|
3
|
+
"title": "Callout",
|
|
4
|
+
"description": "A semantic callout and alert block with status variants, icons, and titles for documentation and notices.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge",
|
|
9
|
+
"class-variance-authority",
|
|
10
|
+
"lucide-solid"
|
|
11
|
+
],
|
|
12
|
+
"files": [
|
|
13
|
+
{
|
|
14
|
+
"path": "ui/callout.tsx",
|
|
15
|
+
"content": "import {\n splitProps,\n Show,\n type Component,\n type JSX,\n type ParentComponent,\n} from \"solid-js\";\nimport { Dynamic } from \"solid-js/web\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport {\n Info,\n Lightbulb,\n AlertTriangle,\n AlertCircle,\n CheckCircle2,\n Bookmark,\n} from \"lucide-solid\";\nimport { cn } from \"@/lib/cn\";\n\nexport const calloutVariants = cva(\n \"relative w-full rounded-lg border p-4 text-sm leading-relaxed transition-colors\",\n {\n variants: {\n variant: {\n note: \"border-border/80 bg-muted/50 text-foreground [&>svg]:text-foreground\",\n info: \"border-sky-500/30 bg-sky-500/10 text-sky-950 dark:text-sky-100 [&>svg]:text-sky-600 dark:[&>svg]:text-sky-400\",\n tip: \"border-emerald-500/30 bg-emerald-500/10 text-emerald-950 dark:text-emerald-100 [&>svg]:text-emerald-600 dark:[&>svg]:text-emerald-400\",\n warning: \"border-amber-500/30 bg-amber-500/10 text-amber-950 dark:text-amber-100 [&>svg]:text-amber-600 dark:[&>svg]:text-amber-400\",\n danger: \"border-destructive/30 bg-destructive/10 text-destructive dark:text-red-200 [&>svg]:text-destructive\",\n success: \"border-emerald-500/30 bg-emerald-500/10 text-emerald-950 dark:text-emerald-100 [&>svg]:text-emerald-600 dark:[&>svg]:text-emerald-400\",\n },\n },\n defaultVariants: {\n variant: \"note\",\n },\n }\n);\n\nconst defaultIcons = {\n note: Bookmark,\n info: Info,\n tip: Lightbulb,\n warning: AlertTriangle,\n danger: AlertCircle,\n success: CheckCircle2,\n};\n\nexport interface CalloutProps\n extends JSX.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof calloutVariants> {\n title?: string;\n type?: VariantProps<typeof calloutVariants>[\"variant\"];\n icon?: Component<{ class?: string }> | false;\n class?: string;\n}\n\nexport const Callout: ParentComponent<CalloutProps> = (props) => {\n const [local, rest] = splitProps(props, [\n \"variant\",\n \"type\",\n \"title\",\n \"icon\",\n \"class\",\n \"children\",\n ]);\n\n const variant = () => local.variant || local.type || \"note\";\n\n const IconComponent = () => {\n if (local.icon === false) return null;\n if (local.icon) return local.icon;\n return defaultIcons[variant()] || Info;\n };\n\n return (\n <div\n role=\"region\"\n aria-label={local.title || `${variant()} callout`}\n class={cn(\n calloutVariants({ variant: variant() }),\n \"flex gap-3.5 items-start\",\n local.class\n )}\n {...rest}\n >\n <Show when={IconComponent()}>\n {(Icon) => (\n <span class=\"inline-flex shrink-0 items-center justify-center mt-0.5 select-none\">\n <Dynamic component={Icon()} class=\"size-4.5 shrink-0\" />\n </span>\n )}\n </Show>\n <div class=\"flex-1 space-y-1 min-w-0\">\n <Show when={local.title}>\n <h5 class=\"font-semibold text-sm leading-none tracking-tight\">\n {local.title}\n </h5>\n </Show>\n <div class=\"text-sm opacity-90 leading-relaxed break-words\">\n {local.children}\n </div>\n </div>\n </div>\n );\n};\n\nexport interface CalloutTitleProps extends JSX.HTMLAttributes<HTMLHeadingElement> {\n class?: string;\n}\n\nexport const CalloutTitle: ParentComponent<CalloutTitleProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\", \"children\"]);\n return (\n <h5\n class={cn(\"font-semibold text-sm leading-none tracking-tight mb-1\", local.class)}\n {...rest}\n >\n {local.children}\n </h5>\n );\n};\n\nexport interface CalloutDescriptionProps extends JSX.HTMLAttributes<HTMLParagraphElement> {\n class?: string;\n}\n\nexport const CalloutDescription: ParentComponent<CalloutDescriptionProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\", \"children\"]);\n return (\n <div\n class={cn(\"text-sm opacity-90 leading-relaxed\", local.class)}\n {...rest}\n >\n {local.children}\n </div>\n );\n};\n",
|
|
16
|
+
"type": "registry:ui"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "card",
|
|
3
|
+
"title": "Card",
|
|
4
|
+
"description": "A versatile container component with header, content, and footer sections.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge"
|
|
9
|
+
],
|
|
10
|
+
"files": [
|
|
11
|
+
{
|
|
12
|
+
"path": "ui/card.tsx",
|
|
13
|
+
"content": "import { splitProps, type Component, type JSX } from \"solid-js\";\nimport { cn } from \"@/lib/cn\";\n\nexport interface CardProps extends JSX.HTMLAttributes<HTMLDivElement> {\n class?: string;\n}\n\n/**\n * Root Card container component.\n */\nexport const Card: Component<CardProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n\n return (\n <div\n class={cn(\n \"rounded-lg border border-border bg-card text-card-foreground shadow-sm\",\n local.class\n )}\n {...rest}\n />\n );\n};\n\nexport interface CardHeaderProps extends JSX.HTMLAttributes<HTMLDivElement> {\n class?: string;\n}\n\n/**\n * Header wrapper for the Card component.\n */\nexport const CardHeader: Component<CardHeaderProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n\n return (\n <div\n class={cn(\"flex flex-col space-y-1.5 p-6\", local.class)}\n {...rest}\n />\n );\n};\n\nexport interface CardTitleProps extends JSX.HTMLAttributes<HTMLHeadingElement> {\n class?: string;\n}\n\n/**\n * Main title heading for the Card header.\n */\nexport const CardTitle: Component<CardTitleProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n\n return (\n <h3\n class={cn(\"font-semibold leading-none tracking-tight text-lg\", local.class)}\n {...rest}\n />\n );\n};\n\nexport interface CardDescriptionProps extends JSX.HTMLAttributes<HTMLParagraphElement> {\n class?: string;\n}\n\n/**\n * Subtitle description text for the Card header.\n */\nexport const CardDescription: Component<CardDescriptionProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n\n return (\n <p\n class={cn(\"text-sm text-muted-foreground\", local.class)}\n {...rest}\n />\n );\n};\n\nexport interface CardContentProps extends JSX.HTMLAttributes<HTMLDivElement> {\n class?: string;\n}\n\n/**\n * Main body content area for the Card.\n */\nexport const CardContent: Component<CardContentProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n\n return (\n <div\n class={cn(\"p-6 pt-0\", local.class)}\n {...rest}\n />\n );\n};\n\nexport interface CardFooterProps extends JSX.HTMLAttributes<HTMLDivElement> {\n class?: string;\n}\n\n/**\n * Footer action area for the Card.\n */\nexport const CardFooter: Component<CardFooterProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\"]);\n\n return (\n <div\n class={cn(\"flex items-center p-6 pt-0\", local.class)}\n {...rest}\n />\n );\n};",
|
|
14
|
+
"type": "registry:ui"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "checkbox",
|
|
3
|
+
"title": "Checkbox",
|
|
4
|
+
"description": "A control that allows the user to toggle between checked and unchecked options.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge"
|
|
9
|
+
],
|
|
10
|
+
"registryDependencies": [
|
|
11
|
+
"create-controllable-signal"
|
|
12
|
+
],
|
|
13
|
+
"files": [
|
|
14
|
+
{
|
|
15
|
+
"path": "ui/checkbox.tsx",
|
|
16
|
+
"content": "import { splitProps, Show, type Component, type JSX } from \"solid-js\";\nimport { createControllableSignal } from \"@/hooks/create-controllable-signal\";\nimport { cn } from \"@/lib/cn\";\n\nexport interface CheckboxProps\n extends Omit<JSX.ButtonHTMLAttributes<HTMLButtonElement>, \"onChange\"> {\n /** Controlled checked state */\n checked?: boolean;\n /** Uncontrolled default checked state */\n defaultChecked?: boolean;\n /** Event handler triggered when checked state changes */\n onChange?: (checked: boolean) => void;\n class?: string;\n}\n\n/**\n * Nikala UI Checkbox component built for SolidJS with Tailwind CSS v4 styling.\n */\nexport const Checkbox: Component<CheckboxProps> = (props) => {\n const [local, rest] = splitProps(props, [\n \"checked\",\n \"defaultChecked\",\n \"onChange\",\n \"disabled\",\n \"class\",\n \"onClick\",\n ]);\n\n const [isChecked, setIsChecked] = createControllableSignal({\n value: () => local.checked,\n defaultValue: local.defaultChecked ?? false,\n onChange: (val) => local.onChange?.(val),\n });\n\n const toggle = (\n e: MouseEvent & { currentTarget: HTMLButtonElement; target: Element }\n ) => {\n if (local.disabled) return;\n setIsChecked(!isChecked());\n\n if (typeof local.onClick === \"function\") {\n local.onClick(e);\n }\n };\n\n return (\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={isChecked()}\n data-state={isChecked() ? \"checked\" : \"unchecked\"}\n disabled={local.disabled}\n onClick={toggle}\n class={cn(\n \"peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground flex items-center justify-center transition-colors\",\n local.class\n )}\n {...rest}\n >\n <Show when={isChecked()}>\n <svg\n class=\"h-3.5 w-3.5 fill-none stroke-current stroke-[3]\"\n viewBox=\"0 0 24 24\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n </Show>\n </button>\n );\n};",
|
|
17
|
+
"type": "registry:ui"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "code-block",
|
|
3
|
+
"title": "Code Block",
|
|
4
|
+
"description": "A code block container with filename header, language indicator, and interactive copy to clipboard button.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge",
|
|
9
|
+
"lucide-solid",
|
|
10
|
+
"shiki"
|
|
11
|
+
],
|
|
12
|
+
"registryDependencies": [
|
|
13
|
+
"button",
|
|
14
|
+
"badge",
|
|
15
|
+
"tooltip",
|
|
16
|
+
"tabs",
|
|
17
|
+
"create-clipboard"
|
|
18
|
+
],
|
|
19
|
+
"files": [
|
|
20
|
+
{
|
|
21
|
+
"path": "ui/code-block.tsx",
|
|
22
|
+
"content": "import {\n createSignal,\n createEffect,\n createMemo,\n splitProps,\n For,\n Show,\n type JSX,\n type ParentComponent,\n} from \"solid-js\";\nimport { Check, Copy } from \"lucide-solid\";\nimport { Button } from \"@/components/ui/button\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Tabs, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\nimport { Tooltip, TooltipTrigger, TooltipContent } from \"@/components/ui/tooltip\";\nimport { createClipboard } from \"@/hooks/create-clipboard\";\nimport { cn } from \"@/lib/cn\";\n\nexport type CodeBlockPackageManager = \"bunx\" | \"npx\" | \"pnpm\" | \"yarn\";\n\nexport interface CodeBlockProps extends JSX.HTMLAttributes<HTMLDivElement> {\n /** The raw source code text to display and copy */\n code?: string;\n /** File name to display in the header bar (e.g. \"App.tsx\", \"main.rs\") */\n filename?: string;\n /** Programming language badge (e.g. \"tsx\", \"rust\", \"bash\") */\n language?: string;\n /** Alias for language */\n lang?: string;\n /** Whether the code snippet is an executable CLI command */\n isCli?: boolean;\n /** Shows the interactive package manager runner tabs (bunx, npx, pnpm, yarn) */\n showPmSwitcher?: boolean;\n /** List of package manager runners to show */\n managers?: CodeBlockPackageManager[];\n /** Whether the copy button is enabled. Defaults to true. */\n copyable?: boolean;\n class?: string;\n}\n\nlet shikiHighlighterPromise: Promise<any> | null = null;\n\nasync function getShikiHighlighter() {\n if (typeof window === \"undefined\") return null;\n if (!shikiHighlighterPromise) {\n try {\n const { createHighlighter } = await import(\"shiki\");\n shikiHighlighterPromise = createHighlighter({\n themes: [\"github-dark\", \"github-light\"],\n langs: [\n \"typescript\",\n \"javascript\",\n \"tsx\",\n \"jsx\",\n \"bash\",\n \"json\",\n \"css\",\n \"html\",\n \"rust\",\n ],\n });\n } catch (e) {\n console.warn(\"Failed to load Shiki highlighter\", e);\n return null;\n }\n }\n return shikiHighlighterPromise;\n}\n\nfunction highlightCliCommand(code: string): string {\n const trimmed = code.trim();\n const parts = trimmed.split(/\\s+/);\n if (parts.length === 0) return code;\n\n const isRunner = [\"bunx\", \"npx\", \"pnpm\", \"yarn\", \"bun\", \"npm\", \"cargo\", \"deno\"].includes(parts[0]);\n if (!isRunner) return `<span class=\"text-foreground\">${escapeHtml(trimmed)}</span>`;\n\n return parts\n .map((part, index) => {\n if (index === 0) {\n return `<span class=\"text-amber-500 dark:text-amber-400 font-bold\">${escapeHtml(part)}</span>`;\n }\n if (part.startsWith(\"-\")) {\n return `<span class=\"text-purple-400 dark:text-purple-300\">${escapeHtml(part)}</span>`;\n }\n if (part.startsWith(\"@\")) {\n return `<span class=\"text-emerald-400 dark:text-emerald-300 font-medium\">${escapeHtml(part)}</span>`;\n }\n if (index === 1 && [\"add\", \"install\", \"init\", \"create\", \"run\"].includes(part)) {\n return `<span class=\"text-sky-500 dark:text-sky-400 font-medium\">${escapeHtml(part)}</span>`;\n }\n return `<span class=\"text-foreground/90\">${escapeHtml(part)}</span>`;\n })\n .join(\" \");\n}\n\nfunction transformCommandForPm(cmd: string, pm: CodeBlockPackageManager): string {\n const trimmed = cmd.trim();\n const runners = [\"bunx\", \"npx\", \"pnpm dlx\", \"pnpm\", \"yarn dlx\", \"yarn\", \"bun\", \"npm\"];\n\n let base = trimmed;\n for (const r of runners) {\n if (trimmed.startsWith(r)) {\n base = trimmed.slice(r.length).trim();\n break;\n }\n }\n\n switch (pm) {\n case \"bunx\":\n return `bunx ${base}`;\n case \"npx\":\n return `npx ${base}`;\n case \"pnpm\":\n return `pnpm dlx ${base}`;\n case \"yarn\":\n return `yarn dlx ${base}`;\n default:\n return `${pm} ${base}`;\n }\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nexport const CodeBlock: ParentComponent<CodeBlockProps> = (props) => {\n const [local, rest] = splitProps(props, [\n \"id\",\n \"code\",\n \"filename\",\n \"language\",\n \"lang\",\n \"isCli\",\n \"showPmSwitcher\",\n \"managers\",\n \"copyable\",\n \"class\",\n \"children\",\n ]);\n\n const clipboard = createClipboard();\n const [activePm, setActivePm] = createSignal<CodeBlockPackageManager>(\"bunx\");\n const [highlightedHtml, setHighlightedHtml] = createSignal(\"\");\n\n const effectiveLang = () => (local.lang || local.language || \"tsx\").toLowerCase();\n const copyable = () => local.copyable ?? true;\n const defaultManagers: CodeBlockPackageManager[] = [\"bunx\", \"npx\", \"pnpm\", \"yarn\"];\n const managersList = () => local.managers || defaultManagers;\n\n const isBashCli = () => {\n const l = effectiveLang();\n return l === \"bash\" || l === \"sh\" || l === \"shell\" || Boolean(local.isCli);\n };\n\n const cleanCode = createMemo(() => {\n const raw = (local.code || \"\").trim();\n if (local.isCli || local.showPmSwitcher) {\n return transformCommandForPm(raw, activePm());\n }\n return raw;\n });\n\n createEffect(() => {\n const codeStr = cleanCode();\n const lang = effectiveLang();\n\n if (isBashCli()) {\n setHighlightedHtml(highlightCliCommand(codeStr));\n return;\n }\n\n if (!codeStr) {\n setHighlightedHtml(\"\");\n return;\n }\n\n // Attempt Shiki highlighting\n getShikiHighlighter().then((highlighter) => {\n if (highlighter) {\n try {\n const html = highlighter.codeToHtml(codeStr, {\n lang: lang === \"js\" ? \"javascript\" : lang === \"ts\" ? \"typescript\" : lang,\n themes: {\n light: \"github-light\",\n dark: \"github-dark\",\n },\n });\n setHighlightedHtml(html);\n return;\n } catch (err) {\n console.warn(`Shiki failed for language: ${lang}`, err);\n }\n }\n // Fallback\n setHighlightedHtml(`<pre class=\"text-foreground/90\"><code>${escapeHtml(codeStr)}</code></pre>`);\n });\n });\n\n const handleCopy = async () => {\n let textToCopy = cleanCode();\n if (!textToCopy && typeof window !== \"undefined\") {\n const target = document.querySelector(`[data-code-block-id=\"${local.id}\"]`);\n if (target) textToCopy = target.textContent || \"\";\n }\n\n if (!textToCopy) return;\n await clipboard.copy(textToCopy);\n };\n\n const shouldShowSwitcher = () => Boolean(local.showPmSwitcher || local.isCli);\n const hasHeader = () => Boolean(shouldShowSwitcher() || local.filename || effectiveLang());\n\n return (\n <div\n class={cn(\n \"group relative my-4 w-full overflow-hidden rounded-lg border border-border bg-muted/40 font-mono text-sm shadow-2xs\",\n local.class\n )}\n {...rest}\n >\n {/* Code Header Bar */}\n <Show when={hasHeader()}>\n <div class=\"flex h-9 items-center justify-between border-b border-border/70 bg-muted/70 px-3.5 text-xs text-muted-foreground select-none\">\n <div class=\"flex items-center gap-2\">\n <Show when={shouldShowSwitcher()}>\n <Tabs\n value={activePm()}\n onChange={(val) => setActivePm(val as CodeBlockPackageManager)}\n class=\"w-auto flex-none\"\n >\n <TabsList class=\"w-auto inline-flex h-auto bg-background/60 p-0.5 border border-border/50 gap-0.5 rounded-md font-mono\">\n <For each={managersList()}>\n {(pm) => (\n <TabsTrigger\n value={pm}\n class=\"rounded-xs px-2 py-0.5 text-[11px] font-mono transition-colors cursor-pointer data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:font-semibold data-[state=active]:shadow-2xs\"\n >\n {pm}\n </TabsTrigger>\n )}\n </For>\n </TabsList>\n </Tabs>\n </Show>\n\n <Show when={local.filename}>\n <span class=\"font-medium text-foreground tracking-tight\">{local.filename}</span>\n </Show>\n\n <Show when={effectiveLang() && !shouldShowSwitcher() && !local.filename}>\n <Badge variant=\"outline\" class=\"uppercase text-[10px] px-1.5 py-0 h-4 font-mono font-semibold\">\n {effectiveLang()}\n </Badge>\n </Show>\n </div>\n\n <Show when={copyable() && (local.code || cleanCode())}>\n <Tooltip>\n <TooltipTrigger\n as={Button}\n variant=\"ghost\"\n size=\"icon\"\n onClick={handleCopy}\n aria-label={clipboard.copied() ? \"Copied code\" : \"Copy code\"}\n class=\"size-6 p-0 rounded-xs text-muted-foreground hover:bg-background hover:text-foreground cursor-pointer\"\n >\n <Show when={clipboard.copied()} fallback={<Copy class=\"size-3.5\" />}>\n <Check class=\"size-3.5 text-emerald-500 dark:text-emerald-400\" />\n </Show>\n </TooltipTrigger>\n <TooltipContent class=\"text-[10px] py-1 px-2\">\n {clipboard.copied() ? \"Copied!\" : \"Copy code\"}\n </TooltipContent>\n </Tooltip>\n </Show>\n </div>\n </Show>\n\n {/* Floating Copy Button (if no header bar is present) */}\n <Show when={!hasHeader() && copyable() && (local.code || cleanCode())}>\n <div class=\"absolute right-2.5 top-2.5 z-10 opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100\">\n <Tooltip>\n <TooltipTrigger\n as={Button}\n variant=\"outline\"\n size=\"icon\"\n onClick={handleCopy}\n aria-label={clipboard.copied() ? \"Copied code\" : \"Copy code\"}\n class=\"size-7 rounded-md border-border/80 bg-background/90 text-muted-foreground backdrop-blur-xs hover:bg-muted hover:text-foreground cursor-pointer shadow-2xs\"\n >\n <Show when={clipboard.copied()} fallback={<Copy class=\"size-3.5\" />}>\n <Check class=\"size-3.5 text-emerald-500 dark:text-emerald-400\" />\n </Show>\n </TooltipTrigger>\n <TooltipContent class=\"text-[10px] py-1 px-2\">\n {clipboard.copied() ? \"Copied!\" : \"Copy code\"}\n </TooltipContent>\n </Tooltip>\n </div>\n </Show>\n\n {/* Code Container */}\n <div class=\"overflow-x-auto p-4 text-[13px] leading-relaxed [scrollbar-width:thin]\">\n <Show\n when={local.children}\n fallback={\n <div\n class=\"font-mono text-sm leading-relaxed overflow-x-auto [&>pre]:!bg-transparent [&>pre]:!p-0 [&>pre]:!m-0 [&>pre]:!border-none\"\n innerHTML={highlightedHtml() || `<pre class=\"text-foreground/90\"><code>${escapeHtml(cleanCode())}</code></pre>`}\n />\n }\n >\n <pre class=\"shiki nikala-code-block m-0 overflow-x-auto bg-transparent p-0 font-mono text-xs\">\n {local.children}\n </pre>\n </Show>\n </div>\n </div>\n );\n};\n",
|
|
23
|
+
"type": "registry:ui"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "code-group",
|
|
3
|
+
"title": "Code Group",
|
|
4
|
+
"description": "A compound tabbed code container for organizing multiple files, languages, and snippets built on Tabs.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge"
|
|
9
|
+
],
|
|
10
|
+
"registryDependencies": [
|
|
11
|
+
"tabs"
|
|
12
|
+
],
|
|
13
|
+
"files": [
|
|
14
|
+
{
|
|
15
|
+
"path": "ui/code-group.tsx",
|
|
16
|
+
"content": "import {\n splitProps,\n type JSX,\n type ParentComponent,\n} from \"solid-js\";\nimport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n} from \"@/components/ui/tabs\";\nimport { cn } from \"@/lib/cn\";\n\nexport interface CodeGroupProps\n extends Omit<JSX.HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n /** Controlled active tab value */\n value?: string;\n /** Default active tab value */\n defaultValue?: string;\n /** Callback fired when active tab changes */\n onChange?: (value: string) => void;\n class?: string;\n}\n\n/**\n * Tabbed code container composed directly from Nikala UI Tabs primitives.\n */\nexport const CodeGroup: ParentComponent<CodeGroupProps> = (props) => {\n const [local, rest] = splitProps(props, [\n \"value\",\n \"defaultValue\",\n \"onChange\",\n \"class\",\n \"children\",\n ]);\n\n return (\n <Tabs\n value={local.value}\n defaultValue={local.defaultValue}\n onChange={local.onChange}\n class={cn(\n \"my-4 w-full gap-0 overflow-hidden rounded-lg border border-border bg-muted/40 font-mono text-sm shadow-2xs\",\n local.class\n )}\n {...rest}\n >\n {local.children}\n </Tabs>\n );\n};\n\nexport interface CodeGroupListProps extends JSX.HTMLAttributes<HTMLDivElement> {\n class?: string;\n}\n\nexport const CodeGroupList: ParentComponent<CodeGroupListProps> = (props) => {\n const [local, rest] = splitProps(props, [\"class\", \"children\"]);\n return (\n <div class={cn(\"flex h-9 items-center justify-between border-b border-border/70 bg-muted/70 px-3 select-none\", local.class)}>\n <TabsList class=\"h-auto bg-background/60 p-0.5 border border-border/50 gap-0.5 rounded-md\" {...rest}>\n {local.children}\n </TabsList>\n </div>\n );\n};\n\nexport interface CodeGroupTriggerProps extends JSX.ButtonHTMLAttributes<HTMLButtonElement> {\n value: string;\n class?: string;\n}\n\nexport const CodeGroupTrigger: ParentComponent<CodeGroupTriggerProps> = (props) => {\n const [local, rest] = splitProps(props, [\"value\", \"class\", \"children\"]);\n return (\n <TabsTrigger\n value={local.value}\n class={cn(\n \"rounded-xs px-2 py-0.5 text-[11px] font-mono transition-colors cursor-pointer data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:font-semibold data-[state=active]:shadow-2xs\",\n local.class\n )}\n {...rest}\n >\n {local.children}\n </TabsTrigger>\n );\n};\n\nexport interface CodeGroupContentProps extends JSX.HTMLAttributes<HTMLDivElement> {\n value: string;\n class?: string;\n}\n\nexport const CodeGroupContent: ParentComponent<CodeGroupContentProps> = (props) => {\n const [local, rest] = splitProps(props, [\"value\", \"class\", \"children\"]);\n return (\n <TabsContent\n value={local.value}\n class={cn(\"p-4 text-[13px] leading-relaxed overflow-x-auto m-0 focus-visible:outline-none\", local.class)}\n {...rest}\n >\n {local.children}\n </TabsContent>\n );\n};\n",
|
|
17
|
+
"type": "registry:ui"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "collapsible",
|
|
3
|
+
"title": "Collapsible",
|
|
4
|
+
"description": "An interactive component that expands and collapses content panels with smooth height animations, built on Kobalte primitives.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge",
|
|
9
|
+
"@kobalte/core"
|
|
10
|
+
],
|
|
11
|
+
"files": [
|
|
12
|
+
{
|
|
13
|
+
"path": "ui/collapsible.tsx",
|
|
14
|
+
"content": "import { splitProps, type JSX, type ValidComponent } from \"solid-js\";\nimport * as CollapsiblePrimitive from \"@kobalte/core/collapsible\";\nimport type { PolymorphicProps } from \"@kobalte/core/polymorphic\";\nimport { cn } from \"@/lib/cn\";\n\nexport type CollapsibleRootProps<T extends ValidComponent = \"div\"> =\n CollapsiblePrimitive.CollapsibleRootProps<T> & {\n class?: string;\n };\n\n/**\n * Root Collapsible component built on Kobalte primitives.\n */\nexport const Collapsible = <T extends ValidComponent = \"div\">(\n props: PolymorphicProps<T, CollapsibleRootProps<T>>\n) => {\n const [local, rest] = splitProps(props as CollapsibleRootProps, [\"class\"]);\n return (\n <CollapsiblePrimitive.Root\n class={cn(\"w-full\", local.class)}\n {...(rest as any)}\n />\n );\n};\n\nexport type CollapsibleTriggerProps<T extends ValidComponent = \"button\"> =\n CollapsiblePrimitive.CollapsibleTriggerProps<T> & {\n class?: string;\n children?: JSX.Element;\n };\n\n/**\n * Trigger element that toggles the Collapsible open/closed state.\n */\nexport const CollapsibleTrigger = <T extends ValidComponent = \"button\">(\n props: PolymorphicProps<T, CollapsibleTriggerProps<T>>\n) => {\n const [local, rest] = splitProps(props as CollapsibleTriggerProps, [\"class\", \"children\"]);\n return (\n <CollapsiblePrimitive.Trigger\n class={cn(\"flex w-full items-center justify-between cursor-pointer\", local.class)}\n {...rest}\n >\n {local.children}\n </CollapsiblePrimitive.Trigger>\n );\n};\n\nexport type CollapsibleContentProps<T extends ValidComponent = \"div\"> =\n CollapsiblePrimitive.CollapsibleContentProps<T> & {\n class?: string;\n children?: JSX.Element;\n };\n\n/**\n * Collapsible content panel revealed when opened.\n */\nexport const CollapsibleContent = <T extends ValidComponent = \"div\">(\n props: PolymorphicProps<T, CollapsibleContentProps<T>>\n) => {\n const [local, rest] = splitProps(props as CollapsibleContentProps, [\"class\", \"children\"]);\n return (\n <CollapsiblePrimitive.Content\n class={cn(\n \"overflow-hidden transition-all data-expanded:animate-collapsible-down data-closed:animate-collapsible-up\",\n local.class\n )}\n {...rest}\n >\n {local.children}\n </CollapsiblePrimitive.Content>\n );\n};\n",
|
|
15
|
+
"type": "registry:ui"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "combobox",
|
|
3
|
+
"title": "Combobox",
|
|
4
|
+
"description": "Searchable autocomplete dropdown with single/multi-selection tags, avatars, group headers, and customizable clear controls.",
|
|
5
|
+
"type": "registry:ui",
|
|
6
|
+
"dependencies": [
|
|
7
|
+
"clsx",
|
|
8
|
+
"tailwind-merge",
|
|
9
|
+
"@kobalte/core"
|
|
10
|
+
],
|
|
11
|
+
"registryDependencies": [
|
|
12
|
+
"scroll-area"
|
|
13
|
+
],
|
|
14
|
+
"files": [
|
|
15
|
+
{
|
|
16
|
+
"path": "ui/combobox.tsx",
|
|
17
|
+
"content": "import { splitProps, type JSX, type ValidComponent } from \"solid-js\";\nimport { Check, ChevronDown, X } from \"lucide-solid\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport * as ComboboxPrimitive from \"@kobalte/core/combobox\";\nimport { cn } from \"@/lib/cn\";\n\nexport type ComboboxRootProps<Option = any, OptGroup = any, T extends ValidComponent = \"div\"> =\n ComboboxPrimitive.ComboboxRootProps<Option, OptGroup, T> & {\n class?: string;\n children?: JSX.Element;\n triggerMode?: \"input\" | \"focus\" | \"both\" | \"manual\";\n };\n\n/**\n * Root Combobox component providing search, single/multi-selection, and group support.\n * `triggerMode=\"focus\"` or `triggerMode=\"both\"` enables opening dropdown on input click/focus.\n */\nexport const Combobox = <Option = any, OptGroup = any, T extends ValidComponent = \"div\">(\n props: ComboboxRootProps<Option, OptGroup, T>\n) => {\n const [local, rest] = splitProps(props as ComboboxRootProps, [\"class\", \"children\", \"triggerMode\"]);\n\n return (\n <ComboboxPrimitive.Root\n triggerMode={local.triggerMode ?? \"input\"}\n class={cn(\"relative w-full\", local.class)}\n {...(rest as any)}\n >\n {local.children}\n </ComboboxPrimitive.Root>\n );\n};\n\nexport type ComboboxControlProps<Option = any, T extends ValidComponent = \"div\"> =\n ComboboxPrimitive.ComboboxControlProps<Option, T> & {\n class?: string;\n children?: JSX.Element;\n clearable?: boolean;\n onClear?: () => void;\n };\n\n/**\n * Input container for Combobox supporting search input, selected tags, and clear button.\n */\nexport const ComboboxControl = <Option = any, T extends ValidComponent = \"div\">(\n props: ComboboxControlProps<Option, T>\n) => {\n const [local, rest] = splitProps(props as ComboboxControlProps, [\n \"class\",\n \"children\",\n \"clearable\",\n \"onClear\",\n ]);\n\n return (\n <ComboboxPrimitive.Control\n class={cn(\n \"flex min-h-9 w-full flex-wrap items-center justify-between rounded-md border border-input bg-muted px-3 py-1 text-sm shadow-sm transition-colors focus-within:ring-1 focus-within:ring-primary focus-within:border-primary disabled:cursor-not-allowed disabled:opacity-50 gap-1.5 text-foreground\",\n local.class\n )}\n {...(rest as any)}\n >\n <div class=\"flex flex-wrap items-center gap-1.5 flex-1 min-w-0\">\n {local.children}\n </div>\n\n <div class=\"flex items-center gap-1 shrink-0 self-center\">\n {local.clearable && (\n <button\n type=\"button\"\n tabIndex={-1}\n onClick={(e) => {\n e.stopPropagation();\n if (local.onClear) local.onClear();\n }}\n class=\"rounded-sm p-0.5 opacity-60 hover:opacity-100 hover:bg-accent text-foreground transition-opacity focus:outline-none cursor-pointer\"\n aria-label=\"Clear selection\"\n >\n <svg class=\"h-3.5 w-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n )}\n <ComboboxTrigger />\n </div>\n </ComboboxPrimitive.Control>\n );\n};\n\nexport type ComboboxInputProps<T extends ValidComponent = \"input\"> =\n ComboboxPrimitive.ComboboxInputProps<T> & {\n class?: string;\n openOnFocus?: boolean;\n };\n\n/**\n * Search input field embedded within ComboboxControl.\n * Supports `openOnFocus` to automatically trigger the dropdown when focused or clicked.\n */\nexport const ComboboxInput = <T extends ValidComponent = \"input\">(\n props: ComboboxInputProps<T>\n) => {\n const [local, rest] = splitProps(props as ComboboxInputProps, [\"class\", \"openOnFocus\", \"onFocus\", \"onClick\"]);\n\n return (\n <ComboboxPrimitive.Input\n class={cn(\n \"flex-1 bg-transparent py-1 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed text-foreground min-w-16\",\n local.class\n )}\n onFocus={(e: FocusEvent) => {\n if (typeof local.onFocus === \"function\") local.onFocus(e as any);\n }}\n onClick={(e: MouseEvent) => {\n if (typeof local.onClick === \"function\") local.onClick(e as any);\n }}\n {...(rest as any)}\n />\n );\n};\n\nexport type ComboboxTriggerProps<T extends ValidComponent = \"button\"> =\n ComboboxPrimitive.ComboboxTriggerProps<T> & {\n class?: string;\n };\n\n/**\n * Dropdown chevron trigger icon.\n */\nexport const ComboboxTrigger = <T extends ValidComponent = \"button\">(\n props: ComboboxTriggerProps<T>\n) => {\n const [local, rest] = splitProps(props as ComboboxTriggerProps, [\"class\"]);\n\n return (\n <ComboboxPrimitive.Trigger\n class={cn(\n \"flex h-4 w-4 items-center justify-center opacity-50 hover:opacity-100 transition-opacity focus:outline-none cursor-pointer\",\n local.class\n )}\n {...(rest as any)}\n >\n <ComboboxPrimitive.Icon\n as=\"svg\"\n class=\"h-4 w-4 stroke-current stroke-2 fill-none\"\n viewBox=\"0 0 24 24\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </ComboboxPrimitive.Icon>\n </ComboboxPrimitive.Trigger>\n );\n};\n\nexport type ComboboxTokenProps<Option = any> = {\n class?: string;\n children?: JSX.Element;\n item?: Option;\n onRemove?: () => void;\n};\n\n/**\n * Selected item tag token pill rendered in multi-select mode.\n */\nexport const ComboboxToken = <Option = any>(props: ComboboxTokenProps<Option>) => {\n const [local, rest] = splitProps(props, [\"class\", \"children\", \"onRemove\"]);\n\n return (\n <span\n class={cn(\n \"inline-flex items-center gap-1.5 rounded-md bg-accent px-2 py-0.5 text-xs font-medium text-accent-foreground border border-border shadow-2xs animate-in fade-in-50\",\n local.class\n )}\n {...rest}\n >\n <span class=\"truncate\">{local.children}</span>\n <button\n type=\"button\"\n tabIndex={-1}\n onClick={(e) => {\n e.stopPropagation();\n if (local.onRemove) local.onRemove();\n }}\n class=\"rounded-xs p-0.5 hover:bg-muted-foreground/20 text-muted-foreground hover:text-foreground transition-colors focus:outline-none cursor-pointer\"\n aria-label=\"Remove tag\"\n >\n <svg class=\"h-3 w-3\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </span>\n );\n};\n\nexport type ComboboxContentProps<T extends ValidComponent = \"div\"> =\n ComboboxPrimitive.ComboboxContentProps<T> & {\n class?: string;\n };\n\n/**\n * Portaled popover content listbox container.\n */\nexport const ComboboxContent = <T extends ValidComponent = \"div\">(\n props: ComboboxContentProps<T>\n) => {\n const [local, rest] = splitProps(props as ComboboxContentProps, [\"class\"]);\n\n return (\n <ComboboxPrimitive.Portal>\n <ComboboxPrimitive.Content\n class={cn(\n \"relative z-50 min-w-8rem overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md animate-in fade-in-80 data-expanded:animate-in data-closed:animate-out data-[closed]:fade-out-0 data-[expanded]:fade-in-0 data-closed:zoom-out-95 data-expanded:zoom-in-95 max-h-60\",\n local.class\n )}\n {...(rest as any)}\n >\n <ScrollArea class=\"max-h-60 w-full\">\n <ComboboxPrimitive.Listbox class=\"p-1 outline-none\" />\n </ScrollArea>\n </ComboboxPrimitive.Content>\n </ComboboxPrimitive.Portal>\n );\n};\n\nexport type ComboboxItemProps<T extends ValidComponent = \"li\"> =\n ComboboxPrimitive.ComboboxItemProps<T> & {\n class?: string;\n children?: JSX.Element;\n };\n\n/**\n * Individual option item inside listbox supporting custom avatars, icons, and titles.\n */\nexport const ComboboxItem = <T extends ValidComponent = \"li\">(\n props: ComboboxItemProps<T>\n) => {\n const [local, rest] = splitProps(props as ComboboxItemProps, [\"class\", \"children\"]);\n\n return (\n <ComboboxPrimitive.Item\n class={cn(\n \"relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-disabled:pointer-events-none data-disabled:opacity-50 data-highlighted:bg-accent data-highlighted:text-accent-foreground text-popover-foreground transition-colors\",\n local.class\n )}\n {...rest}\n >\n <ComboboxPrimitive.ItemIndicator class=\"absolute left-2 flex h-4 w-4 items-center justify-center text-primary\">\n <svg class=\"h-4 w-4 fill-none stroke-current stroke-2\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M5 13l4 4L19 7\" />\n </svg>\n </ComboboxPrimitive.ItemIndicator>\n <ComboboxPrimitive.ItemLabel class=\"flex items-center gap-2 w-full truncate\">\n {local.children}\n </ComboboxPrimitive.ItemLabel>\n </ComboboxPrimitive.Item>\n );\n};\n\nexport type ComboboxGroupProps<T extends ValidComponent = \"li\"> =\n ComboboxPrimitive.ComboboxSectionProps<T> & {\n class?: string;\n children?: JSX.Element;\n label?: JSX.Element;\n };\n\n/**\n * Group container for organizing related options.\n */\nexport const ComboboxGroup = <T extends ValidComponent = \"li\">(\n props: ComboboxGroupProps<T>\n) => {\n const [local, rest] = splitProps(props as ComboboxGroupProps, [\"class\", \"children\", \"label\"]);\n\n return (\n <ComboboxPrimitive.Section class={cn(\"px-1 py-1\", local.class)} {...(rest as any)}>\n {local.label && (\n <span class=\"px-2 py-1.5 text-xs font-semibold text-muted-foreground uppercase tracking-wider block\">\n {local.label}\n </span>\n )}\n {local.children}\n </ComboboxPrimitive.Section>\n );\n};\n\n/**\n * Empty state notice when no matching search items exist.\n */\nexport const ComboboxEmpty = (props: { class?: string; children?: JSX.Element }) => {\n return (\n <div class={cn(\"py-6 text-center text-sm text-muted-foreground\", props.class)}>\n {props.children || \"No matching items found.\"}\n </div>\n );\n};\n\n/**\n * Hidden native select element for form integrations.\n */\nexport const ComboboxHiddenSelect = ComboboxPrimitive.HiddenSelect;\n",
|
|
18
|
+
"type": "registry:ui"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|