@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,126 @@
|
|
|
1
|
+
import { createSignal, createEffect, onCleanup, type Accessor } from "solid-js";
|
|
2
|
+
|
|
3
|
+
export type EventSourceStatus = "CONNECTING" | "OPEN" | "CLOSED";
|
|
4
|
+
|
|
5
|
+
export interface CreateEventSourceOptions {
|
|
6
|
+
/** Event names to listen to on the EventSource. Defaults to ['message']. */
|
|
7
|
+
events?: string[];
|
|
8
|
+
/** Include credentials in CORS requests. */
|
|
9
|
+
withCredentials?: boolean;
|
|
10
|
+
/** Whether to open connection immediately. Defaults to true. */
|
|
11
|
+
immediate?: boolean;
|
|
12
|
+
/** Callback fired when connection is opened. */
|
|
13
|
+
onOpen?: (event: Event) => void;
|
|
14
|
+
/** Callback fired when message event is received. */
|
|
15
|
+
onMessage?: (event: MessageEvent) => void;
|
|
16
|
+
/** Callback fired when error occurs. */
|
|
17
|
+
onError?: (event: Event) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface CreateEventSourceReturn<T = unknown> {
|
|
21
|
+
/** Signal accessor containing latest received SSE event data (parsed if JSON). */
|
|
22
|
+
data: Accessor<T | null>;
|
|
23
|
+
/** Signal accessor containing current EventSource status. */
|
|
24
|
+
status: Accessor<EventSourceStatus>;
|
|
25
|
+
/** Signal accessor containing last raw MessageEvent. */
|
|
26
|
+
event: Accessor<MessageEvent | null>;
|
|
27
|
+
/** Open or reconnect EventSource stream. */
|
|
28
|
+
open: () => void;
|
|
29
|
+
/** Close active EventSource stream. */
|
|
30
|
+
close: () => void;
|
|
31
|
+
/** Signal accessor indicating whether EventSource is supported in browser environment. */
|
|
32
|
+
isSupported: Accessor<boolean>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* SolidJS reactive primitive for subscribing to Server-Sent Events (SSE) streams.
|
|
37
|
+
*/
|
|
38
|
+
export function createEventSource<T = unknown>(
|
|
39
|
+
url: string | Accessor<string>,
|
|
40
|
+
options: CreateEventSourceOptions = {}
|
|
41
|
+
): CreateEventSourceReturn<T> {
|
|
42
|
+
const [data, setData] = createSignal<T | null>(null);
|
|
43
|
+
const [event, setEvent] = createSignal<MessageEvent | null>(null);
|
|
44
|
+
const [status, setStatus] = createSignal<EventSourceStatus>("CLOSED");
|
|
45
|
+
|
|
46
|
+
const getUrl = (): string => (typeof url === "function" ? url() : url);
|
|
47
|
+
|
|
48
|
+
const isSupported = (): boolean =>
|
|
49
|
+
typeof window !== "undefined" && "EventSource" in window;
|
|
50
|
+
|
|
51
|
+
let es: EventSource | null = null;
|
|
52
|
+
|
|
53
|
+
const close = (): void => {
|
|
54
|
+
if (es) {
|
|
55
|
+
es.close();
|
|
56
|
+
es = null;
|
|
57
|
+
setStatus("CLOSED");
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const open = (): void => {
|
|
62
|
+
if (!isSupported()) return;
|
|
63
|
+
|
|
64
|
+
close();
|
|
65
|
+
|
|
66
|
+
setStatus("CONNECTING");
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const source = new EventSource(getUrl(), {
|
|
70
|
+
withCredentials: options.withCredentials,
|
|
71
|
+
});
|
|
72
|
+
es = source;
|
|
73
|
+
|
|
74
|
+
source.onopen = (e) => {
|
|
75
|
+
setStatus("OPEN");
|
|
76
|
+
options.onOpen?.(e);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
source.onerror = (e) => {
|
|
80
|
+
if (source.readyState === EventSource.CLOSED) {
|
|
81
|
+
setStatus("CLOSED");
|
|
82
|
+
} else if (source.readyState === EventSource.CONNECTING) {
|
|
83
|
+
setStatus("CONNECTING");
|
|
84
|
+
}
|
|
85
|
+
options.onError?.(e);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const eventList = options.events ?? ["message"];
|
|
89
|
+
eventList.forEach((eventName) => {
|
|
90
|
+
source.addEventListener(eventName, (e) => {
|
|
91
|
+
const msgEvt = e as MessageEvent;
|
|
92
|
+
setEvent(() => msgEvt);
|
|
93
|
+
try {
|
|
94
|
+
const parsed = JSON.parse(msgEvt.data);
|
|
95
|
+
setData(() => parsed);
|
|
96
|
+
} catch {
|
|
97
|
+
setData(() => msgEvt.data as unknown as T);
|
|
98
|
+
}
|
|
99
|
+
options.onMessage?.(msgEvt);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
} catch {
|
|
103
|
+
setStatus("CLOSED");
|
|
104
|
+
es = null;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
createEffect(() => {
|
|
109
|
+
if (options.immediate ?? true) {
|
|
110
|
+
open();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
onCleanup(() => {
|
|
114
|
+
close();
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
data,
|
|
120
|
+
status,
|
|
121
|
+
event,
|
|
122
|
+
open,
|
|
123
|
+
close,
|
|
124
|
+
isSupported,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { createEffect, onCleanup, type Accessor } from "solid-js";
|
|
2
|
+
|
|
3
|
+
export interface CreateFaviconOptions {
|
|
4
|
+
/** Favicon rel attribute value. Defaults to 'icon'. */
|
|
5
|
+
rel?: string;
|
|
6
|
+
/** Favicon image mime-type format (e.g., 'image/x-icon', 'image/svg+xml', 'image/png'). */
|
|
7
|
+
type?: string;
|
|
8
|
+
/** Whether to restore original favicon on component unmount. Defaults to true. */
|
|
9
|
+
restoreOnUnmount?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* SolidJS reactive primitive for dynamically updating browser favicon element.
|
|
14
|
+
*/
|
|
15
|
+
export function createFavicon(
|
|
16
|
+
href: string | Accessor<string>,
|
|
17
|
+
options: CreateFaviconOptions = {}
|
|
18
|
+
): void {
|
|
19
|
+
const getHref = (): string => (typeof href === "function" ? href() : href);
|
|
20
|
+
|
|
21
|
+
createEffect(() => {
|
|
22
|
+
if (typeof document === "undefined") return;
|
|
23
|
+
|
|
24
|
+
const rel = options.rel ?? "icon";
|
|
25
|
+
let linkElement: HTMLLinkElement | null = document.querySelector(
|
|
26
|
+
`link[rel*="${rel}"]`
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const originalHref = linkElement ? linkElement.href : "";
|
|
30
|
+
|
|
31
|
+
if (!linkElement) {
|
|
32
|
+
linkElement = document.createElement("link");
|
|
33
|
+
linkElement.rel = rel;
|
|
34
|
+
if (options.type) linkElement.type = options.type;
|
|
35
|
+
document.head.appendChild(linkElement);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const newHref = getHref();
|
|
39
|
+
if (newHref) {
|
|
40
|
+
linkElement.href = newHref;
|
|
41
|
+
if (options.type) linkElement.type = options.type;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
onCleanup(() => {
|
|
45
|
+
if (typeof document !== "undefined" && (options.restoreOnUnmount ?? true) && linkElement) {
|
|
46
|
+
if (originalHref) {
|
|
47
|
+
linkElement.href = originalHref;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { createSignal, createEffect, type Accessor } from "solid-js";
|
|
2
|
+
|
|
3
|
+
export interface CreateFetchOptions<T> extends RequestInit {
|
|
4
|
+
/** Whether the request should be refetched automatically on window focus. Defaults to false. */
|
|
5
|
+
refetchOnFocus?: boolean;
|
|
6
|
+
/** Custom transform function to process raw JSON / text response into required shape. */
|
|
7
|
+
transform?: (data: unknown) => T;
|
|
8
|
+
/** Whether the initial request should execute immediately. Defaults to true. */
|
|
9
|
+
immediate?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface CreateFetchReturn<T> {
|
|
13
|
+
/** Signal containing fetched data. */
|
|
14
|
+
data: Accessor<T | null>;
|
|
15
|
+
/** Signal indicating whether request is loading. */
|
|
16
|
+
isLoading: Accessor<boolean>;
|
|
17
|
+
/** Signal containing request error if fetch failed. */
|
|
18
|
+
error: Accessor<Error | null>;
|
|
19
|
+
/** Imperative function to refetch data manually. */
|
|
20
|
+
refetch: () => Promise<void>;
|
|
21
|
+
/** Abort ongoing HTTP request. */
|
|
22
|
+
abort: () => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* SolidJS reactive primitive for handling HTTP fetch requests, loading states, errors, and manual refetching.
|
|
27
|
+
*/
|
|
28
|
+
export function createFetch<T = unknown>(
|
|
29
|
+
url: string | Accessor<string>,
|
|
30
|
+
options: CreateFetchOptions<T> = {}
|
|
31
|
+
): CreateFetchReturn<T> {
|
|
32
|
+
const [data, setData] = createSignal<T | null>(null);
|
|
33
|
+
const [isLoading, setIsLoading] = createSignal(options.immediate ?? true);
|
|
34
|
+
const [error, setError] = createSignal<Error | null>(null);
|
|
35
|
+
|
|
36
|
+
let controller: AbortController | null = null;
|
|
37
|
+
|
|
38
|
+
const getUrl = (): string => {
|
|
39
|
+
return typeof url === "function" ? url() : url;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const abort = (): void => {
|
|
43
|
+
if (controller) {
|
|
44
|
+
controller.abort();
|
|
45
|
+
controller = null;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const executeFetch = async (): Promise<void> => {
|
|
50
|
+
if (typeof window === "undefined") return;
|
|
51
|
+
|
|
52
|
+
abort();
|
|
53
|
+
controller = new AbortController();
|
|
54
|
+
|
|
55
|
+
setIsLoading(true);
|
|
56
|
+
setError(null);
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
const response = await fetch(getUrl(), {
|
|
60
|
+
...options,
|
|
61
|
+
signal: controller.signal,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
throw new Error(`HTTP error! status: ${response.status} ${response.statusText}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const raw = await response.json();
|
|
69
|
+
const result = options.transform ? options.transform(raw) : (raw as T);
|
|
70
|
+
|
|
71
|
+
setData(() => result);
|
|
72
|
+
} catch (err) {
|
|
73
|
+
if (err instanceof Error && err.name === "AbortError") return;
|
|
74
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
75
|
+
} finally {
|
|
76
|
+
setIsLoading(false);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
createEffect(() => {
|
|
81
|
+
if (options.immediate ?? true) {
|
|
82
|
+
executeFetch();
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
data,
|
|
88
|
+
isLoading,
|
|
89
|
+
error,
|
|
90
|
+
refetch: executeFetch,
|
|
91
|
+
abort,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { createEffect, onCleanup, type Accessor } from "solid-js";
|
|
2
|
+
|
|
3
|
+
export interface CreateFocusTrapOptions {
|
|
4
|
+
/** Whether focus trap is actively enabled. Defaults to true. */
|
|
5
|
+
enabled?: boolean | Accessor<boolean>;
|
|
6
|
+
/** Whether to return focus to previously focused element on cleanup. Defaults to true. */
|
|
7
|
+
returnFocusOnDeactivate?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const FOCUSABLE_SELECTOR =
|
|
11
|
+
'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex]:not([tabindex="-1"]), [contenteditable]';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* SolidJS reactive primitive for trapping keyboard focus inside target container element.
|
|
15
|
+
*
|
|
16
|
+
* @param target Target element or accessor returning HTML element.
|
|
17
|
+
* @param options Configuration options for focus trap behavior.
|
|
18
|
+
*/
|
|
19
|
+
export function createFocusTrap(
|
|
20
|
+
target: HTMLElement | Accessor<HTMLElement | undefined>,
|
|
21
|
+
options: CreateFocusTrapOptions = {}
|
|
22
|
+
): void {
|
|
23
|
+
const getTarget = (): HTMLElement | undefined => {
|
|
24
|
+
if (typeof target === "function") {
|
|
25
|
+
return (target as Accessor<HTMLElement | undefined>)();
|
|
26
|
+
}
|
|
27
|
+
return target;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const isEnabled = (): boolean => {
|
|
31
|
+
if (typeof options.enabled === "function") {
|
|
32
|
+
return options.enabled();
|
|
33
|
+
}
|
|
34
|
+
return options.enabled ?? true;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
createEffect(() => {
|
|
38
|
+
if (typeof window === "undefined" || !isEnabled()) return;
|
|
39
|
+
|
|
40
|
+
const container = getTarget();
|
|
41
|
+
if (!container) return;
|
|
42
|
+
|
|
43
|
+
const previousActiveElement = document.activeElement as HTMLElement | null;
|
|
44
|
+
|
|
45
|
+
const getFocusableElements = (): HTMLElement[] => {
|
|
46
|
+
return Array.from(container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(
|
|
47
|
+
(el) => el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const focusable = getFocusableElements();
|
|
52
|
+
if (focusable.length > 0) {
|
|
53
|
+
focusable[0].focus();
|
|
54
|
+
} else {
|
|
55
|
+
container.focus();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
59
|
+
if (event.key !== "Tab") return;
|
|
60
|
+
|
|
61
|
+
const elements = getFocusableElements();
|
|
62
|
+
if (elements.length === 0) {
|
|
63
|
+
event.preventDefault();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const firstElement = elements[0];
|
|
68
|
+
const lastElement = elements[elements.length - 1];
|
|
69
|
+
const activeElement = document.activeElement;
|
|
70
|
+
|
|
71
|
+
if (event.shiftKey) {
|
|
72
|
+
if (activeElement === firstElement || !container.contains(activeElement)) {
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
lastElement.focus();
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
if (activeElement === lastElement || !container.contains(activeElement)) {
|
|
78
|
+
event.preventDefault();
|
|
79
|
+
firstElement.focus();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
85
|
+
|
|
86
|
+
onCleanup(() => {
|
|
87
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
88
|
+
|
|
89
|
+
if (options.returnFocusOnDeactivate !== false && previousActiveElement) {
|
|
90
|
+
previousActiveElement.focus?.();
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { createSignal, createMemo, type Accessor } from "solid-js";
|
|
2
|
+
|
|
3
|
+
export type FormErrors<T> = Partial<Record<keyof T, string>>;
|
|
4
|
+
export type FormTouched<T> = Partial<Record<keyof T, boolean>>;
|
|
5
|
+
export type ValidateOn = "change" | "blur" | "submit";
|
|
6
|
+
|
|
7
|
+
export type FormInputEvent = Event & {
|
|
8
|
+
currentTarget:
|
|
9
|
+
| HTMLInputElement
|
|
10
|
+
| HTMLTextAreaElement
|
|
11
|
+
| HTMLSelectElement;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export interface CreateFormOptions<T extends Record<string, any>> {
|
|
15
|
+
/** Initial form field values object */
|
|
16
|
+
initialValues: T;
|
|
17
|
+
/** Custom validation function returning error messages object */
|
|
18
|
+
validate?: (values: T) => FormErrors<T> | Promise<FormErrors<T>>;
|
|
19
|
+
/** Event that triggers validation. Defaults to "change". */
|
|
20
|
+
validateOn?: ValidateOn;
|
|
21
|
+
/** Submit handler callback invoked when validation succeeds */
|
|
22
|
+
onSubmit?: (values: T) => void | Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface CreateFormReturn<T extends Record<string, any>> {
|
|
26
|
+
/** Accessor for current form field values */
|
|
27
|
+
values: Accessor<T>;
|
|
28
|
+
/** Accessor for form field validation error messages */
|
|
29
|
+
errors: Accessor<FormErrors<T>>;
|
|
30
|
+
/** Accessor for form field touched states */
|
|
31
|
+
touched: Accessor<FormTouched<T>>;
|
|
32
|
+
/** Accessor indicating if form is currently submitting */
|
|
33
|
+
isSubmitting: Accessor<boolean>;
|
|
34
|
+
/** Accessor containing an exception thrown by onSubmit, if any */
|
|
35
|
+
submitError: Accessor<unknown>;
|
|
36
|
+
/** Accessor indicating if form has zero validation errors */
|
|
37
|
+
isValid: Accessor<boolean>;
|
|
38
|
+
/** Accessor indicating if form values differ from initial values */
|
|
39
|
+
isDirty: Accessor<boolean>;
|
|
40
|
+
/** Update specific form field value */
|
|
41
|
+
setFieldValue: <K extends keyof T>(field: K, value: T[K]) => void;
|
|
42
|
+
/** Set specific form field validation error */
|
|
43
|
+
setFieldError: <K extends keyof T>(field: K, error: string | undefined) => void;
|
|
44
|
+
/** Set specific form field touched state */
|
|
45
|
+
setFieldTouched: <K extends keyof T>(field: K, isTouched?: boolean) => void;
|
|
46
|
+
/** Input change event listener helper factory function */
|
|
47
|
+
handleChange: <K extends keyof T>(field: K) => (e: FormInputEvent) => void;
|
|
48
|
+
/** Input blur event listener helper factory function */
|
|
49
|
+
handleBlur: <K extends keyof T>(field: K) => () => void;
|
|
50
|
+
/** Form onSubmit event handler */
|
|
51
|
+
handleSubmit: (e?: Event) => Promise<void>;
|
|
52
|
+
/** Reset form values, errors, and touched states to initial values */
|
|
53
|
+
resetForm: () => void;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* SolidJS reactive primitive for managing form field state, validation, errors, and submission.
|
|
58
|
+
*
|
|
59
|
+
* @param options Form configuration options including initialValues and validate function.
|
|
60
|
+
*/
|
|
61
|
+
export function createForm<T extends Record<string, any>>(
|
|
62
|
+
options: CreateFormOptions<T>
|
|
63
|
+
): CreateFormReturn<T> {
|
|
64
|
+
const initialValues = { ...options.initialValues };
|
|
65
|
+
|
|
66
|
+
const [values, setValues] = createSignal<T>({ ...initialValues });
|
|
67
|
+
const [errors, setErrors] = createSignal<FormErrors<T>>({});
|
|
68
|
+
const [touched, setTouched] = createSignal<FormTouched<T>>({});
|
|
69
|
+
const [isSubmitting, setIsSubmitting] = createSignal(false);
|
|
70
|
+
const [submitError, setSubmitError] = createSignal<unknown>();
|
|
71
|
+
const validateOn = options.validateOn ?? "change";
|
|
72
|
+
let validationSequence = 0;
|
|
73
|
+
|
|
74
|
+
const isDirty = createMemo(() => {
|
|
75
|
+
const current = values();
|
|
76
|
+
return Object.keys(initialValues).some((key) => current[key] !== initialValues[key]);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const isValid = createMemo(() => {
|
|
80
|
+
const errs = errors();
|
|
81
|
+
return Object.keys(errs).length === 0;
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const runValidation = async (currentValues: T): Promise<FormErrors<T>> => {
|
|
85
|
+
const sequence = ++validationSequence;
|
|
86
|
+
if (!options.validate) {
|
|
87
|
+
setErrors(() => ({}));
|
|
88
|
+
return {};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const result = await options.validate(currentValues);
|
|
92
|
+
const newErrors = result || {};
|
|
93
|
+
// Ignore stale async validations that finished after a newer request.
|
|
94
|
+
if (sequence === validationSequence) {
|
|
95
|
+
setErrors(() => newErrors);
|
|
96
|
+
}
|
|
97
|
+
return newErrors;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const setFieldValue = <K extends keyof T>(field: K, value: T[K]) => {
|
|
101
|
+
const next = { ...values(), [field]: value };
|
|
102
|
+
setValues(() => next);
|
|
103
|
+
if (validateOn === "change") {
|
|
104
|
+
void runValidation(next);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const setFieldError = <K extends keyof T>(field: K, error: string | undefined) => {
|
|
109
|
+
setErrors((prev) => {
|
|
110
|
+
const next = { ...prev };
|
|
111
|
+
if (error) next[field] = error;
|
|
112
|
+
else delete next[field];
|
|
113
|
+
return next;
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const setFieldTouched = <K extends keyof T>(field: K, isTouched = true) => {
|
|
118
|
+
setTouched((prev) => ({ ...prev, [field]: isTouched }));
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const handleChange = <K extends keyof T>(field: K) => {
|
|
122
|
+
return (e: FormInputEvent) => {
|
|
123
|
+
const target = e.currentTarget;
|
|
124
|
+
let value: unknown = target.value;
|
|
125
|
+
|
|
126
|
+
if (
|
|
127
|
+
"checked" in target &&
|
|
128
|
+
((target as HTMLInputElement).type === "checkbox" ||
|
|
129
|
+
(target as HTMLInputElement).type === "radio")
|
|
130
|
+
) {
|
|
131
|
+
value = (target as HTMLInputElement).checked;
|
|
132
|
+
} else if ("selectedOptions" in target && target.multiple) {
|
|
133
|
+
value = Array.from(target.selectedOptions, (option) => option.value);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
setFieldValue(field, value as T[K]);
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const handleBlur = <K extends keyof T>(field: K) => {
|
|
141
|
+
return () => {
|
|
142
|
+
setFieldTouched(field, true);
|
|
143
|
+
if (validateOn === "blur") {
|
|
144
|
+
void runValidation(values());
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const handleSubmit = async (e?: Event) => {
|
|
150
|
+
e?.preventDefault();
|
|
151
|
+
setIsSubmitting(true);
|
|
152
|
+
setSubmitError(undefined);
|
|
153
|
+
|
|
154
|
+
// Mark all fields as touched on submit
|
|
155
|
+
const allTouched = Object.keys(values()).reduce((acc, key) => {
|
|
156
|
+
acc[key as keyof T] = true;
|
|
157
|
+
return acc;
|
|
158
|
+
}, {} as FormTouched<T>);
|
|
159
|
+
setTouched(() => allTouched);
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
const validationErrors = await runValidation(values());
|
|
163
|
+
if (Object.keys(validationErrors).length === 0 && options.onSubmit) {
|
|
164
|
+
try {
|
|
165
|
+
await options.onSubmit(values());
|
|
166
|
+
} catch (error) {
|
|
167
|
+
setSubmitError(() => error);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
} finally {
|
|
171
|
+
setIsSubmitting(false);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const resetForm = () => {
|
|
176
|
+
setValues(() => ({ ...initialValues }));
|
|
177
|
+
setErrors(() => ({}));
|
|
178
|
+
setTouched(() => ({}));
|
|
179
|
+
setIsSubmitting(false);
|
|
180
|
+
setSubmitError(undefined);
|
|
181
|
+
validationSequence += 1;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
values,
|
|
186
|
+
errors,
|
|
187
|
+
touched,
|
|
188
|
+
isSubmitting,
|
|
189
|
+
submitError,
|
|
190
|
+
isValid,
|
|
191
|
+
isDirty,
|
|
192
|
+
setFieldValue,
|
|
193
|
+
setFieldError,
|
|
194
|
+
setFieldTouched,
|
|
195
|
+
handleChange,
|
|
196
|
+
handleBlur,
|
|
197
|
+
handleSubmit,
|
|
198
|
+
resetForm,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { createSignal, createEffect, onCleanup, type Accessor } from "solid-js";
|
|
2
|
+
|
|
3
|
+
export interface CreateFullscreenOptions {
|
|
4
|
+
/** Target element accessor or reference. Defaults to document.documentElement. */
|
|
5
|
+
target?: HTMLElement | Accessor<HTMLElement | undefined>;
|
|
6
|
+
/** Callback fired when entering fullscreen mode. */
|
|
7
|
+
onEnter?: () => void;
|
|
8
|
+
/** Callback fired when exiting fullscreen mode. */
|
|
9
|
+
onExit?: () => void;
|
|
10
|
+
/** Callback fired when fullscreen request fails. */
|
|
11
|
+
onError?: (err: Event) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface CreateFullscreenReturn {
|
|
15
|
+
/** Signal indicating whether fullscreen mode is currently active. */
|
|
16
|
+
isFullscreen: Accessor<boolean>;
|
|
17
|
+
/** Request full screen mode for target element. */
|
|
18
|
+
enter: () => Promise<void>;
|
|
19
|
+
/** Exit full screen mode. */
|
|
20
|
+
exit: () => Promise<void>;
|
|
21
|
+
/** Toggle full screen mode. */
|
|
22
|
+
toggle: () => Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* SolidJS reactive primitive for requesting and monitoring element fullscreen status.
|
|
27
|
+
*/
|
|
28
|
+
export function createFullscreen(
|
|
29
|
+
options: CreateFullscreenOptions = {}
|
|
30
|
+
): CreateFullscreenReturn {
|
|
31
|
+
const [isFullscreen, setIsFullscreen] = createSignal(false);
|
|
32
|
+
|
|
33
|
+
const getTarget = (): HTMLElement | undefined => {
|
|
34
|
+
if (typeof document === "undefined") return undefined;
|
|
35
|
+
if (typeof options.target === "function") {
|
|
36
|
+
return options.target() ?? document.documentElement;
|
|
37
|
+
}
|
|
38
|
+
return options.target ?? document.documentElement;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const updateStatus = (): void => {
|
|
42
|
+
if (typeof document === "undefined") return;
|
|
43
|
+
const activeEl = document.fullscreenElement;
|
|
44
|
+
const isTargetFullscreen = Boolean(activeEl && activeEl === getTarget());
|
|
45
|
+
setIsFullscreen(isTargetFullscreen);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const enter = async (): Promise<void> => {
|
|
49
|
+
if (typeof window === "undefined") return;
|
|
50
|
+
const el = getTarget();
|
|
51
|
+
if (el?.requestFullscreen) {
|
|
52
|
+
await el.requestFullscreen();
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const exit = async (): Promise<void> => {
|
|
57
|
+
if (typeof document === "undefined") return;
|
|
58
|
+
if (document.fullscreenElement && document.exitFullscreen) {
|
|
59
|
+
await document.exitFullscreen();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const toggle = async (): Promise<void> => {
|
|
64
|
+
if (isFullscreen()) {
|
|
65
|
+
await exit();
|
|
66
|
+
} else {
|
|
67
|
+
await enter();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
createEffect(() => {
|
|
72
|
+
if (typeof document === "undefined") return;
|
|
73
|
+
|
|
74
|
+
const handleFullscreenChange = (): void => {
|
|
75
|
+
const activeEl = document.fullscreenElement;
|
|
76
|
+
const isTarget = Boolean(activeEl && activeEl === getTarget());
|
|
77
|
+
setIsFullscreen(isTarget);
|
|
78
|
+
|
|
79
|
+
if (isTarget) {
|
|
80
|
+
options.onEnter?.();
|
|
81
|
+
} else {
|
|
82
|
+
options.onExit?.();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const handleFullscreenError = (err: Event): void => {
|
|
87
|
+
options.onError?.(err);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
|
91
|
+
document.addEventListener("fullscreenerror", handleFullscreenError);
|
|
92
|
+
|
|
93
|
+
onCleanup(() => {
|
|
94
|
+
document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
|
95
|
+
document.removeEventListener("fullscreenerror", handleFullscreenError);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
isFullscreen,
|
|
101
|
+
enter,
|
|
102
|
+
exit,
|
|
103
|
+
toggle,
|
|
104
|
+
};
|
|
105
|
+
}
|