@lickle/docs 0.0.0-dev.1
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 +3 -0
- package/dist/esm/_lib/fs/index.js +20 -0
- package/dist/esm/_lib/fs/index.js.map +1 -0
- package/dist/esm/_lib/fs/watch.js +30 -0
- package/dist/esm/_lib/fs/watch.js.map +1 -0
- package/dist/esm/_lib/index.js +9 -0
- package/dist/esm/_lib/index.js.map +1 -0
- package/dist/esm/_lib/jiti/index.js +16 -0
- package/dist/esm/_lib/jiti/index.js.map +1 -0
- package/dist/esm/_lib/path/index.js +42 -0
- package/dist/esm/_lib/path/index.js.map +1 -0
- package/dist/esm/_lib/pkg/index.js +128 -0
- package/dist/esm/_lib/pkg/index.js.map +1 -0
- package/dist/esm/_lib/repo/index.js +100 -0
- package/dist/esm/_lib/repo/index.js.map +1 -0
- package/dist/esm/_lib/slug/index.js +23 -0
- package/dist/esm/_lib/slug/index.js.map +1 -0
- package/dist/esm/_lib/t.js +2 -0
- package/dist/esm/_lib/t.js.map +1 -0
- package/dist/esm/_lib/tsconfig/index.js +12 -0
- package/dist/esm/_lib/tsconfig/index.js.map +1 -0
- package/dist/esm/_lib/util/index.js +54 -0
- package/dist/esm/_lib/util/index.js.map +1 -0
- package/dist/esm/cli/cmd/dev.js +74 -0
- package/dist/esm/cli/cmd/dev.js.map +1 -0
- package/dist/esm/cli/cmd/index.js +4 -0
- package/dist/esm/cli/cmd/index.js.map +1 -0
- package/dist/esm/cli/cmd/init.js +74 -0
- package/dist/esm/cli/cmd/init.js.map +1 -0
- package/dist/esm/cli/cmd/json.js +28 -0
- package/dist/esm/cli/cmd/json.js.map +1 -0
- package/dist/esm/cli/env.js +5 -0
- package/dist/esm/cli/env.js.map +1 -0
- package/dist/esm/cli/index.js +13 -0
- package/dist/esm/cli/index.js.map +1 -0
- package/dist/esm/cli/vite/client/index.jsx +20 -0
- package/dist/esm/cli/vite/client/index.jsx.map +1 -0
- package/dist/esm/cli/vite/index.js +100 -0
- package/dist/esm/cli/vite/index.js.map +1 -0
- package/dist/esm/cli.js +5 -0
- package/dist/esm/cli.js.map +1 -0
- package/dist/esm/config/defaults.js +32 -0
- package/dist/esm/config/defaults.js.map +1 -0
- package/dist/esm/config/file.js +48 -0
- package/dist/esm/config/file.js.map +1 -0
- package/dist/esm/config/index.js +7 -0
- package/dist/esm/config/index.js.map +1 -0
- package/dist/esm/config/load.js +79 -0
- package/dist/esm/config/load.js.map +1 -0
- package/dist/esm/config/types.js +2 -0
- package/dist/esm/config/types.js.map +1 -0
- package/dist/esm/core/index.js +3 -0
- package/dist/esm/core/index.js.map +1 -0
- package/dist/esm/core/project/debug.js +26 -0
- package/dist/esm/core/project/debug.js.map +1 -0
- package/dist/esm/core/project/index.js +39 -0
- package/dist/esm/core/project/index.js.map +1 -0
- package/dist/esm/core/project/naming.js +39 -0
- package/dist/esm/core/project/naming.js.map +1 -0
- package/dist/esm/core/project/routing.js +173 -0
- package/dist/esm/core/project/routing.js.map +1 -0
- package/dist/esm/core/project/types.js +4 -0
- package/dist/esm/core/project/types.js.map +1 -0
- package/dist/esm/core/reflect/index.js +10 -0
- package/dist/esm/core/reflect/index.js.map +1 -0
- package/dist/esm/core/reflect/indexed.js +195 -0
- package/dist/esm/core/reflect/indexed.js.map +1 -0
- package/dist/esm/core/reflect/resolve.js +157 -0
- package/dist/esm/core/reflect/resolve.js.map +1 -0
- package/dist/esm/core/reflect/scan.js +787 -0
- package/dist/esm/core/reflect/scan.js.map +1 -0
- package/dist/esm/core/reflect/state.js +29 -0
- package/dist/esm/core/reflect/state.js.map +1 -0
- package/dist/esm/core/reflect/types.js +16 -0
- package/dist/esm/core/reflect/types.js.map +1 -0
- package/dist/esm/core/reflect/walk.js +106 -0
- package/dist/esm/core/reflect/walk.js.map +1 -0
- package/dist/esm/solidjs/index.js +2 -0
- package/dist/esm/solidjs/index.js.map +1 -0
- package/dist/esm/solidjs/jsx-runtime.js +2 -0
- package/dist/esm/solidjs/jsx-runtime.js.map +1 -0
- package/dist/esm/ui/App.jsx +71 -0
- package/dist/esm/ui/App.jsx.map +1 -0
- package/dist/esm/ui/components/Breadcrumb.jsx +45 -0
- package/dist/esm/ui/components/Breadcrumb.jsx.map +1 -0
- package/dist/esm/ui/components/Code/index.jsx +89 -0
- package/dist/esm/ui/components/Code/index.jsx.map +1 -0
- package/dist/esm/ui/components/Comment.jsx +176 -0
- package/dist/esm/ui/components/Comment.jsx.map +1 -0
- package/dist/esm/ui/components/Declaration.jsx +147 -0
- package/dist/esm/ui/components/Declaration.jsx.map +1 -0
- package/dist/esm/ui/components/Header.jsx +66 -0
- package/dist/esm/ui/components/Header.jsx.map +1 -0
- package/dist/esm/ui/components/Layout.jsx +44 -0
- package/dist/esm/ui/components/Layout.jsx.map +1 -0
- package/dist/esm/ui/components/Link.jsx +34 -0
- package/dist/esm/ui/components/Link.jsx.map +1 -0
- package/dist/esm/ui/components/LivePreview/Example.jsx +76 -0
- package/dist/esm/ui/components/LivePreview/Example.jsx.map +1 -0
- package/dist/esm/ui/components/LivePreview/Sandbox.jsx +25 -0
- package/dist/esm/ui/components/LivePreview/Sandbox.jsx.map +1 -0
- package/dist/esm/ui/components/LivePreview/index.js +4 -0
- package/dist/esm/ui/components/LivePreview/index.js.map +1 -0
- package/dist/esm/ui/components/LivePreview/transform.js +16 -0
- package/dist/esm/ui/components/LivePreview/transform.js.map +1 -0
- package/dist/esm/ui/components/Markdown.jsx +14 -0
- package/dist/esm/ui/components/Markdown.jsx.map +1 -0
- package/dist/esm/ui/components/Page.jsx +121 -0
- package/dist/esm/ui/components/Page.jsx.map +1 -0
- package/dist/esm/ui/components/References.jsx +32 -0
- package/dist/esm/ui/components/References.jsx.map +1 -0
- package/dist/esm/ui/components/SearchPalette.jsx +178 -0
- package/dist/esm/ui/components/SearchPalette.jsx.map +1 -0
- package/dist/esm/ui/components/Sidebar.jsx +63 -0
- package/dist/esm/ui/components/Sidebar.jsx.map +1 -0
- package/dist/esm/ui/components/Syntax.jsx +10 -0
- package/dist/esm/ui/components/Syntax.jsx.map +1 -0
- package/dist/esm/ui/components/ThemeToggle.jsx +25 -0
- package/dist/esm/ui/components/ThemeToggle.jsx.map +1 -0
- package/dist/esm/ui/components/Type.jsx +444 -0
- package/dist/esm/ui/components/Type.jsx.map +1 -0
- package/dist/esm/ui/components/index.js +16 -0
- package/dist/esm/ui/components/index.js.map +1 -0
- package/dist/esm/ui/context/components.jsx +30 -0
- package/dist/esm/ui/context/components.jsx.map +1 -0
- package/dist/esm/ui/context/global.js +15 -0
- package/dist/esm/ui/context/global.js.map +1 -0
- package/dist/esm/ui/context/index.js +5 -0
- package/dist/esm/ui/context/index.js.map +1 -0
- package/dist/esm/ui/context/markup/index.jsx +25 -0
- package/dist/esm/ui/context/markup/index.jsx.map +1 -0
- package/dist/esm/ui/context/markup/markdown.js +34 -0
- package/dist/esm/ui/context/markup/markdown.js.map +1 -0
- package/dist/esm/ui/context/markup/shiki.js +58 -0
- package/dist/esm/ui/context/markup/shiki.js.map +1 -0
- package/dist/esm/ui/context/markup/util.js +22 -0
- package/dist/esm/ui/context/markup/util.js.map +1 -0
- package/dist/esm/ui/context/project/index.jsx +27 -0
- package/dist/esm/ui/context/project/index.jsx.map +1 -0
- package/dist/esm/ui/context/project/indexed.js +47 -0
- package/dist/esm/ui/context/project/indexed.js.map +1 -0
- package/dist/esm/ui/context/project/types.js +2 -0
- package/dist/esm/ui/context/project/types.js.map +1 -0
- package/dist/esm/ui/context/theme.jsx +36 -0
- package/dist/esm/ui/context/theme.jsx.map +1 -0
- package/dist/esm/ui/hooks/index.js +94 -0
- package/dist/esm/ui/hooks/index.js.map +1 -0
- package/dist/esm/ui/index.js +5 -0
- package/dist/esm/ui/index.js.map +1 -0
- package/dist/esm/ui/renderer.jsx +21 -0
- package/dist/esm/ui/renderer.jsx.map +1 -0
- package/dist/esm/ui/util/comment.js +14 -0
- package/dist/esm/ui/util/comment.js.map +1 -0
- package/dist/esm/ui/util/kind.js +85 -0
- package/dist/esm/ui/util/kind.js.map +1 -0
- package/dist/esm/ui/util/markdown.js +66 -0
- package/dist/esm/ui/util/markdown.js.map +1 -0
- package/dist/esm/ui/util/search.js +75 -0
- package/dist/esm/ui/util/search.js.map +1 -0
- package/dist/ts/_lib/fs/index.d.ts +6 -0
- package/dist/ts/_lib/fs/index.d.ts.map +1 -0
- package/dist/ts/_lib/fs/watch.d.ts +14 -0
- package/dist/ts/_lib/fs/watch.d.ts.map +1 -0
- package/dist/ts/_lib/index.d.ts +10 -0
- package/dist/ts/_lib/index.d.ts.map +1 -0
- package/dist/ts/_lib/jiti/index.d.ts +2 -0
- package/dist/ts/_lib/jiti/index.d.ts.map +1 -0
- package/dist/ts/_lib/path/index.d.ts +12 -0
- package/dist/ts/_lib/path/index.d.ts.map +1 -0
- package/dist/ts/_lib/pkg/index.d.ts +28 -0
- package/dist/ts/_lib/pkg/index.d.ts.map +1 -0
- package/dist/ts/_lib/repo/index.d.ts +30 -0
- package/dist/ts/_lib/repo/index.d.ts.map +1 -0
- package/dist/ts/_lib/slug/index.d.ts +4 -0
- package/dist/ts/_lib/slug/index.d.ts.map +1 -0
- package/dist/ts/_lib/t.d.ts +11 -0
- package/dist/ts/_lib/t.d.ts.map +1 -0
- package/dist/ts/_lib/tsconfig/index.d.ts +8 -0
- package/dist/ts/_lib/tsconfig/index.d.ts.map +1 -0
- package/dist/ts/_lib/util/index.d.ts +9 -0
- package/dist/ts/_lib/util/index.d.ts.map +1 -0
- package/dist/ts/cli/cmd/dev.d.ts +27 -0
- package/dist/ts/cli/cmd/dev.d.ts.map +1 -0
- package/dist/ts/cli/cmd/index.d.ts +4 -0
- package/dist/ts/cli/cmd/index.d.ts.map +1 -0
- package/dist/ts/cli/cmd/init.d.ts +14 -0
- package/dist/ts/cli/cmd/init.d.ts.map +1 -0
- package/dist/ts/cli/cmd/json.d.ts +12 -0
- package/dist/ts/cli/cmd/json.d.ts.map +1 -0
- package/dist/ts/cli/env.d.ts +2 -0
- package/dist/ts/cli/env.d.ts.map +1 -0
- package/dist/ts/cli/index.d.ts +78 -0
- package/dist/ts/cli/index.d.ts.map +1 -0
- package/dist/ts/cli/vite/client/index.d.ts +10 -0
- package/dist/ts/cli/vite/client/index.d.ts.map +1 -0
- package/dist/ts/cli/vite/index.d.ts +12 -0
- package/dist/ts/cli/vite/index.d.ts.map +1 -0
- package/dist/ts/cli.d.ts +3 -0
- package/dist/ts/cli.d.ts.map +1 -0
- package/dist/ts/config/defaults.d.ts +10 -0
- package/dist/ts/config/defaults.d.ts.map +1 -0
- package/dist/ts/config/file.d.ts +3 -0
- package/dist/ts/config/file.d.ts.map +1 -0
- package/dist/ts/config/index.d.ts +6 -0
- package/dist/ts/config/index.d.ts.map +1 -0
- package/dist/ts/config/load.d.ts +36 -0
- package/dist/ts/config/load.d.ts.map +1 -0
- package/dist/ts/config/types.d.ts +56 -0
- package/dist/ts/config/types.d.ts.map +1 -0
- package/dist/ts/core/index.d.ts +3 -0
- package/dist/ts/core/index.d.ts.map +1 -0
- package/dist/ts/core/project/debug.d.ts +3 -0
- package/dist/ts/core/project/debug.d.ts.map +1 -0
- package/dist/ts/core/project/index.d.ts +17 -0
- package/dist/ts/core/project/index.d.ts.map +1 -0
- package/dist/ts/core/project/naming.d.ts +23 -0
- package/dist/ts/core/project/naming.d.ts.map +1 -0
- package/dist/ts/core/project/routing.d.ts +61 -0
- package/dist/ts/core/project/routing.d.ts.map +1 -0
- package/dist/ts/core/project/types.d.ts +56 -0
- package/dist/ts/core/project/types.d.ts.map +1 -0
- package/dist/ts/core/reflect/index.d.ts +22 -0
- package/dist/ts/core/reflect/index.d.ts.map +1 -0
- package/dist/ts/core/reflect/indexed.d.ts +83 -0
- package/dist/ts/core/reflect/indexed.d.ts.map +1 -0
- package/dist/ts/core/reflect/resolve.d.ts +3 -0
- package/dist/ts/core/reflect/resolve.d.ts.map +1 -0
- package/dist/ts/core/reflect/scan.d.ts +218 -0
- package/dist/ts/core/reflect/scan.d.ts.map +1 -0
- package/dist/ts/core/reflect/state.d.ts +44 -0
- package/dist/ts/core/reflect/state.d.ts.map +1 -0
- package/dist/ts/core/reflect/types.d.ts +289 -0
- package/dist/ts/core/reflect/types.d.ts.map +1 -0
- package/dist/ts/core/reflect/walk.d.ts +28 -0
- package/dist/ts/core/reflect/walk.d.ts.map +1 -0
- package/dist/ts/solidjs/index.d.ts +2 -0
- package/dist/ts/solidjs/index.d.ts.map +1 -0
- package/dist/ts/solidjs/jsx-runtime.d.ts +2 -0
- package/dist/ts/solidjs/jsx-runtime.d.ts.map +1 -0
- package/dist/ts/ui/App.d.ts +17 -0
- package/dist/ts/ui/App.d.ts.map +1 -0
- package/dist/ts/ui/components/Breadcrumb.d.ts +4 -0
- package/dist/ts/ui/components/Breadcrumb.d.ts.map +1 -0
- package/dist/ts/ui/components/Code/index.d.ts +17 -0
- package/dist/ts/ui/components/Code/index.d.ts.map +1 -0
- package/dist/ts/ui/components/Comment.d.ts +49 -0
- package/dist/ts/ui/components/Comment.d.ts.map +1 -0
- package/dist/ts/ui/components/Declaration.d.ts +122 -0
- package/dist/ts/ui/components/Declaration.d.ts.map +1 -0
- package/dist/ts/ui/components/Header.d.ts +5 -0
- package/dist/ts/ui/components/Header.d.ts.map +1 -0
- package/dist/ts/ui/components/Layout.d.ts +5 -0
- package/dist/ts/ui/components/Layout.d.ts.map +1 -0
- package/dist/ts/ui/components/Link.d.ts +15 -0
- package/dist/ts/ui/components/Link.d.ts.map +1 -0
- package/dist/ts/ui/components/LivePreview/Example.d.ts +16 -0
- package/dist/ts/ui/components/LivePreview/Example.d.ts.map +1 -0
- package/dist/ts/ui/components/LivePreview/Sandbox.d.ts +20 -0
- package/dist/ts/ui/components/LivePreview/Sandbox.d.ts.map +1 -0
- package/dist/ts/ui/components/LivePreview/index.d.ts +4 -0
- package/dist/ts/ui/components/LivePreview/index.d.ts.map +1 -0
- package/dist/ts/ui/components/LivePreview/transform.d.ts +19 -0
- package/dist/ts/ui/components/LivePreview/transform.d.ts.map +1 -0
- package/dist/ts/ui/components/Markdown.d.ts +11 -0
- package/dist/ts/ui/components/Markdown.d.ts.map +1 -0
- package/dist/ts/ui/components/Page.d.ts +21 -0
- package/dist/ts/ui/components/Page.d.ts.map +1 -0
- package/dist/ts/ui/components/References.d.ts +2 -0
- package/dist/ts/ui/components/References.d.ts.map +1 -0
- package/dist/ts/ui/components/SearchPalette.d.ts +5 -0
- package/dist/ts/ui/components/SearchPalette.d.ts.map +1 -0
- package/dist/ts/ui/components/Sidebar.d.ts +5 -0
- package/dist/ts/ui/components/Sidebar.d.ts.map +1 -0
- package/dist/ts/ui/components/Syntax.d.ts +15 -0
- package/dist/ts/ui/components/Syntax.d.ts.map +1 -0
- package/dist/ts/ui/components/ThemeToggle.d.ts +2 -0
- package/dist/ts/ui/components/ThemeToggle.d.ts.map +1 -0
- package/dist/ts/ui/components/Type.d.ts +82 -0
- package/dist/ts/ui/components/Type.d.ts.map +1 -0
- package/dist/ts/ui/components/index.d.ts +15 -0
- package/dist/ts/ui/components/index.d.ts.map +1 -0
- package/dist/ts/ui/context/components.d.ts +124 -0
- package/dist/ts/ui/context/components.d.ts.map +1 -0
- package/dist/ts/ui/context/global.d.ts +210 -0
- package/dist/ts/ui/context/global.d.ts.map +1 -0
- package/dist/ts/ui/context/index.d.ts +5 -0
- package/dist/ts/ui/context/index.d.ts.map +1 -0
- package/dist/ts/ui/context/markup/index.d.ts +20 -0
- package/dist/ts/ui/context/markup/index.d.ts.map +1 -0
- package/dist/ts/ui/context/markup/markdown.d.ts +4 -0
- package/dist/ts/ui/context/markup/markdown.d.ts.map +1 -0
- package/dist/ts/ui/context/markup/shiki.d.ts +17 -0
- package/dist/ts/ui/context/markup/shiki.d.ts.map +1 -0
- package/dist/ts/ui/context/markup/util.d.ts +11 -0
- package/dist/ts/ui/context/markup/util.d.ts.map +1 -0
- package/dist/ts/ui/context/project/index.d.ts +25 -0
- package/dist/ts/ui/context/project/index.d.ts.map +1 -0
- package/dist/ts/ui/context/project/indexed.d.ts +4 -0
- package/dist/ts/ui/context/project/indexed.d.ts.map +1 -0
- package/dist/ts/ui/context/project/types.d.ts +13 -0
- package/dist/ts/ui/context/project/types.d.ts.map +1 -0
- package/dist/ts/ui/context/theme.d.ts +12 -0
- package/dist/ts/ui/context/theme.d.ts.map +1 -0
- package/dist/ts/ui/hooks/index.d.ts +29 -0
- package/dist/ts/ui/hooks/index.d.ts.map +1 -0
- package/dist/ts/ui/index.d.ts +5 -0
- package/dist/ts/ui/index.d.ts.map +1 -0
- package/dist/ts/ui/renderer.d.ts +200 -0
- package/dist/ts/ui/renderer.d.ts.map +1 -0
- package/dist/ts/ui/util/comment.d.ts +4 -0
- package/dist/ts/ui/util/comment.d.ts.map +1 -0
- package/dist/ts/ui/util/kind.d.ts +15 -0
- package/dist/ts/ui/util/kind.d.ts.map +1 -0
- package/dist/ts/ui/util/markdown.d.ts +8 -0
- package/dist/ts/ui/util/markdown.d.ts.map +1 -0
- package/dist/ts/ui/util/search.d.ts +20 -0
- package/dist/ts/ui/util/search.d.ts.map +1 -0
- package/package.json +89 -0
- package/src/_lib/fs/index.ts +23 -0
- package/src/_lib/fs/watch.ts +40 -0
- package/src/_lib/index.ts +9 -0
- package/src/_lib/jiti/index.ts +18 -0
- package/src/_lib/path/index.ts +44 -0
- package/src/_lib/pkg/index.ts +165 -0
- package/src/_lib/repo/index.ts +138 -0
- package/src/_lib/slug/index.ts +26 -0
- package/src/_lib/t.ts +17 -0
- package/src/_lib/tsconfig/index.ts +20 -0
- package/src/_lib/util/index.ts +53 -0
- package/src/cli/cmd/dev.ts +86 -0
- package/src/cli/cmd/index.ts +3 -0
- package/src/cli/cmd/init.ts +80 -0
- package/src/cli/cmd/json.ts +28 -0
- package/src/cli/env.ts +6 -0
- package/src/cli/index.ts +14 -0
- package/src/cli/vite/client/index.html +27 -0
- package/src/cli/vite/client/index.tsx +30 -0
- package/src/cli/vite/client/public/apple-touch-icon.png +0 -0
- package/src/cli/vite/client/public/favicon-96x96.png +0 -0
- package/src/cli/vite/client/public/favicon.ico +0 -0
- package/src/cli/vite/client/public/favicon.svg +1 -0
- package/src/cli/vite/client/public/site.webmanifest +21 -0
- package/src/cli/vite/client/public/web-app-manifest-192x192.png +0 -0
- package/src/cli/vite/client/public/web-app-manifest-512x512.png +0 -0
- package/src/cli/vite/index.ts +115 -0
- package/src/cli.ts +6 -0
- package/src/config/defaults.ts +36 -0
- package/src/config/file.ts +53 -0
- package/src/config/index.ts +11 -0
- package/src/config/load.ts +95 -0
- package/src/config/types.ts +59 -0
- package/src/core/index.ts +2 -0
- package/src/core/project/debug.ts +30 -0
- package/src/core/project/index.ts +58 -0
- package/src/core/project/naming.ts +49 -0
- package/src/core/project/routing.ts +234 -0
- package/src/core/project/types.ts +47 -0
- package/src/core/reflect/index.ts +18 -0
- package/src/core/reflect/indexed.ts +242 -0
- package/src/core/reflect/resolve.ts +159 -0
- package/src/core/reflect/scan.ts +816 -0
- package/src/core/reflect/state.ts +75 -0
- package/src/core/reflect/types.ts +164 -0
- package/src/core/reflect/walk.ts +121 -0
- package/src/solidjs/index.ts +1 -0
- package/src/solidjs/jsx-runtime.ts +1 -0
- package/src/ui/App.tsx +115 -0
- package/src/ui/components/Breadcrumb.tsx +53 -0
- package/src/ui/components/Code/index.tsx +112 -0
- package/src/ui/components/Comment.tsx +221 -0
- package/src/ui/components/Declaration.tsx +210 -0
- package/src/ui/components/Header.tsx +99 -0
- package/src/ui/components/Layout.tsx +62 -0
- package/src/ui/components/Link.tsx +43 -0
- package/src/ui/components/LivePreview/Example.tsx +104 -0
- package/src/ui/components/LivePreview/Sandbox.tsx +36 -0
- package/src/ui/components/LivePreview/index.ts +3 -0
- package/src/ui/components/LivePreview/transform.ts +28 -0
- package/src/ui/components/Markdown.tsx +16 -0
- package/src/ui/components/Page.tsx +162 -0
- package/src/ui/components/References.tsx +34 -0
- package/src/ui/components/SearchPalette.tsx +266 -0
- package/src/ui/components/Sidebar.tsx +107 -0
- package/src/ui/components/Syntax.tsx +10 -0
- package/src/ui/components/ThemeToggle.tsx +50 -0
- package/src/ui/components/Type.tsx +583 -0
- package/src/ui/components/index.ts +15 -0
- package/src/ui/context/components.tsx +103 -0
- package/src/ui/context/global.ts +33 -0
- package/src/ui/context/index.ts +4 -0
- package/src/ui/context/markup/index.tsx +39 -0
- package/src/ui/context/markup/markdown.ts +37 -0
- package/src/ui/context/markup/shiki.ts +72 -0
- package/src/ui/context/markup/util.ts +20 -0
- package/src/ui/context/project/index.tsx +47 -0
- package/src/ui/context/project/indexed.ts +52 -0
- package/src/ui/context/project/types.ts +14 -0
- package/src/ui/context/theme.tsx +45 -0
- package/src/ui/hooks/index.ts +116 -0
- package/src/ui/index.ts +4 -0
- package/src/ui/renderer.tsx +31 -0
- package/src/ui/util/comment.ts +12 -0
- package/src/ui/util/kind.ts +120 -0
- package/src/ui/util/markdown.ts +74 -0
- package/src/ui/util/search.ts +84 -0
- package/theme.css +301 -0
- package/tsconfig.client.json +12 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { createEffect, createSignal, onCleanup, Show } from 'solid-js'
|
|
2
|
+
|
|
3
|
+
import type { Types } from '../../context/index.ts'
|
|
4
|
+
|
|
5
|
+
import { Sandbox, type SandboxIsolate } from './Sandbox.tsx'
|
|
6
|
+
|
|
7
|
+
import { firstCodeBlock, langOf } from '../../context/index.ts'
|
|
8
|
+
import { CodeEditor } from '../Code/index.tsx'
|
|
9
|
+
import { TagSection } from '../Comment.tsx'
|
|
10
|
+
|
|
11
|
+
type ExampleTag = Types.CommentTagMap['@example']
|
|
12
|
+
|
|
13
|
+
/** Executes already-compiled JS into the host; return a disposer to tear down. */
|
|
14
|
+
export type ExampleRun = (src: string, host: HTMLElement) => void | (() => void)
|
|
15
|
+
|
|
16
|
+
export type LiveExampleProps = {
|
|
17
|
+
tag: ExampleTag
|
|
18
|
+
run: ExampleRun
|
|
19
|
+
language?: string
|
|
20
|
+
isolate?: SandboxIsolate
|
|
21
|
+
readonly?: boolean
|
|
22
|
+
onError?: (err: unknown) => void
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const LiveExample = (props: LiveExampleProps) => {
|
|
26
|
+
const preview = useWithPreview(props)
|
|
27
|
+
return (
|
|
28
|
+
<TagSection tag={props.tag} description={props.tag.caption}>
|
|
29
|
+
<div class="rounded-lg border border-line">
|
|
30
|
+
<div class="p-4 bg-code-bg">
|
|
31
|
+
<CodeEditor
|
|
32
|
+
lang={props.language ?? langOf(preview.lang)}
|
|
33
|
+
readonly={props.readonly}
|
|
34
|
+
value={preview.value}
|
|
35
|
+
onChange={preview.onChange}
|
|
36
|
+
/>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="relative min-h-12">
|
|
39
|
+
<Sandbox class="border-t border-line p-4" isolate={props.isolate} ref={preview.onBind} />
|
|
40
|
+
<Show when={preview.error()}>
|
|
41
|
+
{(msg) => (
|
|
42
|
+
<div class="absolute inset-0 w-full h-full flex items-center justify-start p-4 text-xs text-red-500 border-t border-red-500/30 ">
|
|
43
|
+
<div class="flex gap-2">
|
|
44
|
+
<span aria-hidden="true" class="select-none leading-5">
|
|
45
|
+
⚠
|
|
46
|
+
</span>
|
|
47
|
+
<pre class="overflow-x-auto whitespace-pre-wrap wrap-break-word font-mono leading-5">{msg()}</pre>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
)}
|
|
51
|
+
</Show>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</TagSection>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const useWithPreview = (props: LiveExampleProps) => {
|
|
59
|
+
const block = firstCodeBlock(props.tag.code)
|
|
60
|
+
|
|
61
|
+
const [host, setHost] = createSignal<HTMLElement | null>(null)
|
|
62
|
+
const [code, setCode] = createSignal(block.code)
|
|
63
|
+
const [error, setError] = createSignal<string>()
|
|
64
|
+
|
|
65
|
+
let dispose: void | (() => void)
|
|
66
|
+
const teardown = () => {
|
|
67
|
+
try {
|
|
68
|
+
if (typeof dispose === 'function') dispose()
|
|
69
|
+
host()?.replaceChildren()
|
|
70
|
+
} catch (err) {
|
|
71
|
+
console.error('[LiveExample] teardown failed', err)
|
|
72
|
+
}
|
|
73
|
+
dispose = undefined
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
createEffect(() => {
|
|
77
|
+
const src = code()
|
|
78
|
+
const target = host()
|
|
79
|
+
if (!target) return
|
|
80
|
+
teardown()
|
|
81
|
+
try {
|
|
82
|
+
dispose = props.run(src, target)
|
|
83
|
+
setError(undefined)
|
|
84
|
+
} catch (err) {
|
|
85
|
+
target.replaceChildren()
|
|
86
|
+
setError(messageOf(err))
|
|
87
|
+
if (props.onError) props.onError(err)
|
|
88
|
+
else console.error('[LiveExample] failed to run', err)
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
onCleanup(teardown)
|
|
92
|
+
|
|
93
|
+
const onChange = (code: string) => setCode(code)
|
|
94
|
+
|
|
95
|
+
const value = () => code()
|
|
96
|
+
const onBind = (h: HTMLElement | null) => setHost(h)
|
|
97
|
+
|
|
98
|
+
return { onBind, onChange, value, error, lang: block.lang }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const messageOf = (err: unknown): string => {
|
|
102
|
+
if (err instanceof Error) return err.message || err.name
|
|
103
|
+
return String(err)
|
|
104
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { onMount, onCleanup } from 'solid-js'
|
|
2
|
+
|
|
3
|
+
/** Isolation level for the render container. Only `inline` ships today. */
|
|
4
|
+
export type SandboxIsolate = 'inline'
|
|
5
|
+
|
|
6
|
+
/** The element examples render into, plus its teardown. */
|
|
7
|
+
export type Container = { target: HTMLElement; dispose: () => void; reset: () => void }
|
|
8
|
+
|
|
9
|
+
/** Builds a {@link Container} inside `root`. Add new strategies to {@link strategies}. */
|
|
10
|
+
export type ContainerStrategy = (root: HTMLElement) => Container
|
|
11
|
+
|
|
12
|
+
/** Plain child `div` — no isolation. */
|
|
13
|
+
const inline: ContainerStrategy = (root) => {
|
|
14
|
+
const target = document.createElement('div')
|
|
15
|
+
root.appendChild(target)
|
|
16
|
+
return { target, dispose: () => target.remove(), reset: () => target.replaceChildren() }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Shadow DOM / iframe strategies can be added here later (iframe will need an
|
|
20
|
+
// async/ready variant since its document isn't available synchronously).
|
|
21
|
+
const strategies: Record<SandboxIsolate, ContainerStrategy> = { inline }
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A contained render location. Resolves a target element via the chosen
|
|
25
|
+
* isolation strategy and hands it back through `ref` once mounted.
|
|
26
|
+
*/
|
|
27
|
+
export const Sandbox = (props: { isolate?: SandboxIsolate; class?: string; ref?: (target: HTMLElement) => void }) => {
|
|
28
|
+
let root!: HTMLDivElement
|
|
29
|
+
onMount(() => {
|
|
30
|
+
const strategy = strategies[props.isolate ?? 'inline'] ?? inline
|
|
31
|
+
const { target, dispose } = strategy(root)
|
|
32
|
+
props.ref?.(target)
|
|
33
|
+
onCleanup(dispose)
|
|
34
|
+
})
|
|
35
|
+
return <div ref={root} class={props.class} />
|
|
36
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { transform as sucraseTransform, type Transform } from 'sucrase'
|
|
2
|
+
|
|
3
|
+
/** Options forwarded to `sucrase.transform`, plus import handling. */
|
|
4
|
+
export type CompileOptions = {
|
|
5
|
+
/** Sucrase transforms to apply. Default `['typescript', 'jsx']`. */
|
|
6
|
+
transforms?: Transform[]
|
|
7
|
+
/** JSX factory, e.g. `'h'`. Left to sucrase's default when unset. */
|
|
8
|
+
jsxPragma?: string
|
|
9
|
+
/** JSX fragment factory, e.g. `'Fragment'`. */
|
|
10
|
+
jsxFragmentPragma?: string
|
|
11
|
+
/** Production JSX output (no `__source`/`__self`). Default `true`. */
|
|
12
|
+
production?: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Transform a TS/JSX snippet into runnable JS. Framework-agnostic: point
|
|
17
|
+
* `jsxPragma` / `jsxFragmentPragma` at whatever runtime you inject when
|
|
18
|
+
* executing the result.
|
|
19
|
+
*/
|
|
20
|
+
export const transform = (src: string, options: CompileOptions = {}): string => {
|
|
21
|
+
const code = sucraseTransform(src, {
|
|
22
|
+
transforms: options.transforms ?? ['typescript', 'jsx'],
|
|
23
|
+
jsxPragma: options.jsxPragma,
|
|
24
|
+
jsxFragmentPragma: options.jsxFragmentPragma,
|
|
25
|
+
production: options.production ?? true,
|
|
26
|
+
}).code
|
|
27
|
+
return code
|
|
28
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createMemo, Show } from 'solid-js'
|
|
2
|
+
import cn from '@lickle/cn'
|
|
3
|
+
|
|
4
|
+
import { useMarkup } from '../context/index.ts'
|
|
5
|
+
|
|
6
|
+
export const Markdown = (props: { source: string; class?: string }) => {
|
|
7
|
+
const markup = useMarkup()
|
|
8
|
+
const html = createMemo(() => markup.marked()?.parse(props.source, { async: false }))
|
|
9
|
+
return <Show when={html()}>{(h) => <div class={cn('markdown', props.class)} innerHTML={h()} />}</Show>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
Markdown.Inline = (props: { source?: string; class?: string }) => {
|
|
13
|
+
const markup = useMarkup()
|
|
14
|
+
const html = createMemo(() => markup.marked()?.parse(props.source ?? '', { async: false }))
|
|
15
|
+
return <Show when={html()}>{(h) => <div class={cn('markdown-tight', props.class)} innerHTML={h()} />}</Show>
|
|
16
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { For, Show, createMemo } from 'solid-js'
|
|
2
|
+
import { A } from '@solidjs/router'
|
|
3
|
+
|
|
4
|
+
import { createSlot, useProject, type Types } from '../context/index.ts'
|
|
5
|
+
import { type ReferenceRow, useReferences } from '../hooks/index.ts'
|
|
6
|
+
import { labelOf, pluralLabel, groupOrder } from '../util/kind.ts'
|
|
7
|
+
import { commentSummaryText } from '../util/comment.ts'
|
|
8
|
+
|
|
9
|
+
import { Declaration } from './Declaration.tsx'
|
|
10
|
+
import { Breadcrumb } from './Breadcrumb.tsx'
|
|
11
|
+
import { Markdown } from './Markdown.tsx'
|
|
12
|
+
import { Type } from './Type.tsx'
|
|
13
|
+
|
|
14
|
+
type PageProps = { decl: Types.Declaration; route: Types.RouteNode<'declaration' | 'module'> }
|
|
15
|
+
|
|
16
|
+
export const Page = createSlot('page', (props) => (
|
|
17
|
+
<article>
|
|
18
|
+
<PageHeader {...props} />
|
|
19
|
+
<Declaration decl={props.decl} />
|
|
20
|
+
<Children route={props.route} />
|
|
21
|
+
<References id={props.decl.id} />
|
|
22
|
+
</article>
|
|
23
|
+
))
|
|
24
|
+
|
|
25
|
+
/** Renders a markdown page — its `content` parsed inline. */
|
|
26
|
+
export const MarkdownPage = createSlot('page.markdown', (props) => (
|
|
27
|
+
<article>
|
|
28
|
+
<Markdown source={props.route.page.content} />
|
|
29
|
+
</article>
|
|
30
|
+
))
|
|
31
|
+
|
|
32
|
+
export const PageHeader = createSlot('page.header', (props: PageProps) => (
|
|
33
|
+
<header class="mb-5">
|
|
34
|
+
<Breadcrumb id={props.decl.id} />
|
|
35
|
+
<div class="flex items-baseline gap-3 flex-wrap">
|
|
36
|
+
<h1 class="text-2xl font-semibold tracking-tight font-mono">{props.route.label}</h1>
|
|
37
|
+
<Type.KindLabel kind={props.decl.kind} />
|
|
38
|
+
<Show when={props.decl.comment?.tags?.some((t: { tag: string }) => t.tag === '@deprecated')}>
|
|
39
|
+
<span class="text-xs uppercase tracking-wider text-mute">· deprecated</span>
|
|
40
|
+
</Show>
|
|
41
|
+
</div>
|
|
42
|
+
<Source sources={props.decl.sources} />
|
|
43
|
+
</header>
|
|
44
|
+
))
|
|
45
|
+
|
|
46
|
+
/** Stock source-location renderer. Replaceable via `slots.source`. */
|
|
47
|
+
export const Source = createSlot('page.source', (props: { sources?: Types.Source[] }) => {
|
|
48
|
+
const project = useProject()
|
|
49
|
+
return (
|
|
50
|
+
<Show when={props.sources?.[0]}>
|
|
51
|
+
{(s) => {
|
|
52
|
+
const link = project().sourceLink(s())
|
|
53
|
+
const text = `${s().file}:${s().line}`
|
|
54
|
+
if (link) {
|
|
55
|
+
return (
|
|
56
|
+
<a href={link} class="text-xs text-mute mt-2 font-mono">
|
|
57
|
+
{text}
|
|
58
|
+
</a>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
return <div class="text-xs text-mute mt-2 font-mono">{text}</div>
|
|
62
|
+
}}
|
|
63
|
+
</Show>
|
|
64
|
+
)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
type ChildRoute = Types.RouteNode<'declaration' | 'module'>
|
|
68
|
+
type ChildRow = { route: ChildRoute; decl?: Types.Declaration; kind: string; summary: string }
|
|
69
|
+
|
|
70
|
+
/** Child pages of a module / namespace, grouped by kind and linked from the route tree. */
|
|
71
|
+
const Children = (props: { route: ChildRoute }) => {
|
|
72
|
+
const project = useProject()
|
|
73
|
+
const groups = createMemo(() => groupChildren(project(), props.route.children))
|
|
74
|
+
return (
|
|
75
|
+
<For each={groups()}>
|
|
76
|
+
{(group) => (
|
|
77
|
+
<section class="mt-8">
|
|
78
|
+
<h2 class="text-sm font-semibold mb-3 pb-1.5 border-b border-line capitalize">{group.title}</h2>
|
|
79
|
+
<ul class="space-y-3">
|
|
80
|
+
<For each={group.items}>{(row) => <ChildRowView row={row} />}</For>
|
|
81
|
+
</ul>
|
|
82
|
+
</section>
|
|
83
|
+
)}
|
|
84
|
+
</For>
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const ChildRowView = (props: { row: ChildRow }) => (
|
|
89
|
+
<li>
|
|
90
|
+
<div class="flex items-baseline gap-2.5 min-w-0">
|
|
91
|
+
<Type.KindBadge kind={props.row.kind} class="w-3.5 shrink-0" />
|
|
92
|
+
<A href={`/${props.row.route.slug}`} class="font-mono font-semibold text-sm hover:opacity-70">
|
|
93
|
+
{props.row.route.label}
|
|
94
|
+
</A>
|
|
95
|
+
<Show when={props.row.decl}>{(d) => <Signature decl={d()} />}</Show>
|
|
96
|
+
</div>
|
|
97
|
+
<Show when={props.row.summary}>
|
|
98
|
+
<p class="text-sm text-mute mt-1 pl-6 line-clamp-2">{props.row.summary}</p>
|
|
99
|
+
</Show>
|
|
100
|
+
</li>
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
/** A terse inline type cue next to a member name (function params / variable type). */
|
|
104
|
+
const Signature = (props: { decl: Types.Declaration }) => {
|
|
105
|
+
const d = props.decl
|
|
106
|
+
if (d.kind === 'function' && d.signatures[0])
|
|
107
|
+
return (
|
|
108
|
+
<span class="font-mono text-sm text-mute min-w-0 truncate">
|
|
109
|
+
<Type.SignatureExpr sig={d.signatures[0]} />
|
|
110
|
+
</span>
|
|
111
|
+
)
|
|
112
|
+
if (d.kind === 'variable')
|
|
113
|
+
return (
|
|
114
|
+
<span class="font-mono text-sm text-mute min-w-0 truncate">
|
|
115
|
+
: <Type type={d.type} />
|
|
116
|
+
</span>
|
|
117
|
+
)
|
|
118
|
+
return null
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Bucket child routes by declaration kind, ordered by the canonical group order. */
|
|
122
|
+
const groupChildren = (project: Types.Project, children: ChildRoute[]): { title: string; items: ChildRow[] }[] => {
|
|
123
|
+
const buckets = new Map<string, ChildRow[]>()
|
|
124
|
+
for (const route of children) {
|
|
125
|
+
const decl = project.byId(route.page.id)
|
|
126
|
+
const kind = decl?.kind ?? 'module'
|
|
127
|
+
const title = pluralLabel(kind)
|
|
128
|
+
const arr = buckets.get(title) ?? []
|
|
129
|
+
arr.push({ route, decl, kind, summary: commentSummaryText(decl?.comment) })
|
|
130
|
+
buckets.set(title, arr)
|
|
131
|
+
}
|
|
132
|
+
return [...buckets.entries()]
|
|
133
|
+
.sort(([a], [b]) => groupOrder(a) - groupOrder(b) || a.localeCompare(b))
|
|
134
|
+
.map(([title, items]) => ({ title, items: items.sort((a, b) => a.route.label.localeCompare(b.route.label)) }))
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export const References = createSlot('page.references', (props: { id: number }) => {
|
|
138
|
+
const rows = useReferences(() => props.id)
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<Show when={rows().length}>
|
|
142
|
+
<section class="mt-10 lk-references">
|
|
143
|
+
<h2 class="font-semibold text-xl mb-4 pb-2 border-b border-line">Used in</h2>
|
|
144
|
+
<ul class="grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1.5 items-baseline">
|
|
145
|
+
<For each={rows()}>{(r) => <ReferenceRowView row={r} />}</For>
|
|
146
|
+
</ul>
|
|
147
|
+
</section>
|
|
148
|
+
</Show>
|
|
149
|
+
)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
const ReferenceRowView = (props: { row: ReferenceRow }) => (
|
|
153
|
+
<li class="contents">
|
|
154
|
+
<span class="text-xs uppercase tracking-wider text-mute">{labelOf(props.row.decl.kind)}</span>
|
|
155
|
+
<A href={`/${props.row.slug}`} class="font-mono hover:opacity-70 min-w-0 wrap-break-word">
|
|
156
|
+
<Show when={props.row.module}>
|
|
157
|
+
<span class="text-mute">{props.row.module}.</span>
|
|
158
|
+
</Show>
|
|
159
|
+
<span class="font-medium">{props.row.name}</span>
|
|
160
|
+
</A>
|
|
161
|
+
</li>
|
|
162
|
+
)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// import { For, Show } from 'solid-js'
|
|
2
|
+
// import { A } from '@solidjs/router'
|
|
3
|
+
|
|
4
|
+
// import { useReferences, type ReferenceRow } from '../hooks/index.ts'
|
|
5
|
+
// import { createSlot } from '../theme/slots/slot.tsx'
|
|
6
|
+
// import { labelOf } from '../util/kind.ts'
|
|
7
|
+
|
|
8
|
+
// export const References = createSlot('references', (props: { id: number }) => {
|
|
9
|
+
// const rows = useReferences(() => props.id)
|
|
10
|
+
|
|
11
|
+
// return (
|
|
12
|
+
// <Show when={rows().length}>
|
|
13
|
+
// <section class="mt-10 lk-references">
|
|
14
|
+
// <h2 class="font-semibold text-xl mb-4 pb-2 border-b border-line">Used in</h2>
|
|
15
|
+
// <ul>
|
|
16
|
+
// <For each={rows()}>{(r) => <ReferenceRowView row={r} />}</For>
|
|
17
|
+
// </ul>
|
|
18
|
+
// </section>
|
|
19
|
+
// </Show>
|
|
20
|
+
// )
|
|
21
|
+
// })
|
|
22
|
+
|
|
23
|
+
// const ReferenceRowView = (props: { row: ReferenceRow }) => (
|
|
24
|
+
// <li>
|
|
25
|
+
// <span class="kind">{labelOf(props.row.decl.kind)}</span>
|
|
26
|
+
// <A href={`/r/${props.row.slug}`} class="symbol font-mono hover:opacity-70">
|
|
27
|
+
// <Show when={props.row.module}>
|
|
28
|
+
// <span class="text-mute">{props.row.module}.</span>
|
|
29
|
+
// </Show>
|
|
30
|
+
// <span class="font-medium">{props.row.name}</span>
|
|
31
|
+
// </A>
|
|
32
|
+
// <span class="summary">{props.row.summary}</span>
|
|
33
|
+
// </li>
|
|
34
|
+
// )
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { For, Show, createEffect, createMemo, createResource, createSignal, on, onCleanup } from 'solid-js'
|
|
2
|
+
import { useNavigate } from '@solidjs/router'
|
|
3
|
+
|
|
4
|
+
import { useProject, type Types } from '../context/index.ts'
|
|
5
|
+
import { type SearchHit } from '../util/search.ts'
|
|
6
|
+
import { useSearch } from '../hooks/index.ts'
|
|
7
|
+
import { type Kind } from '../util/kind.ts'
|
|
8
|
+
import { Type } from './Type.tsx'
|
|
9
|
+
|
|
10
|
+
const DEBOUNCE_MS = 80
|
|
11
|
+
const DEFAULT_LIMIT = 12
|
|
12
|
+
|
|
13
|
+
export const SearchPalette = (props: { open: () => boolean; onClose: () => void }) => {
|
|
14
|
+
const navigate = useNavigate()
|
|
15
|
+
const search = useSearch()
|
|
16
|
+
const project = useProject()
|
|
17
|
+
|
|
18
|
+
const [engine] = createResource(props.open, async (isOpen) => (isOpen ? await search() : undefined))
|
|
19
|
+
|
|
20
|
+
const [term, setTerm] = createSignal('')
|
|
21
|
+
const [debounced, setDebounced] = createSignal('')
|
|
22
|
+
const [highlight, setHighlight] = createSignal(0)
|
|
23
|
+
let inputRef!: HTMLInputElement
|
|
24
|
+
|
|
25
|
+
createEffect(() => {
|
|
26
|
+
const t = term()
|
|
27
|
+
const timer = setTimeout(() => setDebounced(t), DEBOUNCE_MS)
|
|
28
|
+
onCleanup(() => clearTimeout(timer))
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
createEffect(
|
|
32
|
+
on(props.open, (isOpen) => {
|
|
33
|
+
if (!isOpen) return
|
|
34
|
+
setTerm('')
|
|
35
|
+
setDebounced('')
|
|
36
|
+
setHighlight(0)
|
|
37
|
+
queueMicrotask(() => inputRef?.focus())
|
|
38
|
+
}),
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
const [hits] = createResource(
|
|
42
|
+
() => [engine(), debounced()] as const,
|
|
43
|
+
async ([e, t]) => (e ? await e.query(t) : []),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
// Before the user types, suggest the first module's entries so the palette
|
|
47
|
+
// opens with something to browse instead of an empty box.
|
|
48
|
+
const firstModule = createMemo(() => project().routes.find((r) => r.sidebar && r.page.kind !== 'markdown'))
|
|
49
|
+
const suggestions = createMemo<SearchHit[]>(() => {
|
|
50
|
+
const mod = firstModule()
|
|
51
|
+
return mod ? childHits(project(), mod).slice(0, DEFAULT_LIMIT) : []
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const hasTerm = () => debounced().trim().length > 0
|
|
55
|
+
const list = createMemo<SearchHit[]>(() => (hasTerm() ? (hits() ?? []) : suggestions()))
|
|
56
|
+
|
|
57
|
+
createEffect(
|
|
58
|
+
on(list, (l) => {
|
|
59
|
+
if (highlight() >= l.length) setHighlight(0)
|
|
60
|
+
}),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
const choose = (hit: SearchHit) => {
|
|
64
|
+
navigate(`/${hit.slug}`)
|
|
65
|
+
props.onClose()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const onKeyDown = (e: KeyboardEvent) => {
|
|
69
|
+
const l = list()
|
|
70
|
+
if (e.key === 'ArrowDown') {
|
|
71
|
+
e.preventDefault()
|
|
72
|
+
if (l.length) setHighlight((i) => (i + 1) % l.length)
|
|
73
|
+
} else if (e.key === 'ArrowUp') {
|
|
74
|
+
e.preventDefault()
|
|
75
|
+
if (l.length) setHighlight((i) => (i - 1 + l.length) % l.length)
|
|
76
|
+
} else if (e.key === 'Enter') {
|
|
77
|
+
e.preventDefault()
|
|
78
|
+
const hit = l[highlight()]
|
|
79
|
+
if (hit) choose(hit)
|
|
80
|
+
} else if (e.key === 'Escape') {
|
|
81
|
+
e.preventDefault()
|
|
82
|
+
props.onClose()
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<Show when={props.open()}>
|
|
88
|
+
<div
|
|
89
|
+
class="fixed inset-0 z-50 bg-black/40 backdrop-blur-sm flex items-start justify-center p-4"
|
|
90
|
+
onClick={() => props.onClose()}
|
|
91
|
+
role="presentation"
|
|
92
|
+
>
|
|
93
|
+
<div
|
|
94
|
+
class="w-full max-w-xl mt-[12vh] bg-bg border border-line rounded-xl shadow-2xl overflow-hidden flex flex-col max-h-[70vh]"
|
|
95
|
+
onClick={(e) => e.stopPropagation()}
|
|
96
|
+
role="dialog"
|
|
97
|
+
aria-label="Search"
|
|
98
|
+
>
|
|
99
|
+
<div class="flex items-center gap-3 px-4 py-3.5 border-b border-line">
|
|
100
|
+
<SearchGlyph class="text-mute shrink-0" />
|
|
101
|
+
<input
|
|
102
|
+
ref={inputRef}
|
|
103
|
+
type="text"
|
|
104
|
+
value={term()}
|
|
105
|
+
onInput={(e) => setTerm(e.currentTarget.value)}
|
|
106
|
+
onKeyDown={onKeyDown}
|
|
107
|
+
placeholder="Search functions, types, classes…"
|
|
108
|
+
class="flex-1 bg-transparent outline-none text-[0.95rem] placeholder:text-mute"
|
|
109
|
+
autocomplete="off"
|
|
110
|
+
spellcheck={false}
|
|
111
|
+
/>
|
|
112
|
+
<Kbd>esc</Kbd>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<Show when={list().length} fallback={<EmptyState loading={engine.loading} term={debounced()} />}>
|
|
116
|
+
<Show when={!hasTerm() && firstModule()}>
|
|
117
|
+
{(mod) => (
|
|
118
|
+
<p class="px-5 pt-3 pb-1 text-[0.7rem] uppercase tracking-wider font-semibold text-mute">
|
|
119
|
+
{mod().label}
|
|
120
|
+
</p>
|
|
121
|
+
)}
|
|
122
|
+
</Show>
|
|
123
|
+
<ul class="flex-1 overflow-y-auto p-2" role="listbox">
|
|
124
|
+
<For each={list()}>
|
|
125
|
+
{(hit, i) => (
|
|
126
|
+
<li
|
|
127
|
+
role="option"
|
|
128
|
+
aria-selected={i() === highlight()}
|
|
129
|
+
class="group flex items-center gap-3 px-3 py-2 rounded-lg cursor-pointer scroll-mt-2"
|
|
130
|
+
classList={{ 'bg-hover': i() === highlight() }}
|
|
131
|
+
onMouseEnter={() => setHighlight(i())}
|
|
132
|
+
onClick={() => choose(hit)}
|
|
133
|
+
>
|
|
134
|
+
<span
|
|
135
|
+
class="flex items-center justify-center w-6 h-6 rounded-md border border-line bg-hover/50 shrink-0"
|
|
136
|
+
classList={{ 'border-accent/40': i() === highlight() }}
|
|
137
|
+
>
|
|
138
|
+
<Type.KindBadge kind={hit.kind} class="w-3.5" />
|
|
139
|
+
</span>
|
|
140
|
+
<span class="font-mono font-semibold text-sm shrink-0">{hit.name}</span>
|
|
141
|
+
<Show when={hit.qualified && hit.qualified !== hit.name}>
|
|
142
|
+
<span class="font-mono text-xs text-mute truncate">{hit.qualified}</span>
|
|
143
|
+
</Show>
|
|
144
|
+
<Show when={hit.file}>
|
|
145
|
+
<span class="font-mono text-[0.7rem] text-mute truncate ml-auto pl-3 opacity-70">{hit.file}</span>
|
|
146
|
+
</Show>
|
|
147
|
+
<svg
|
|
148
|
+
width="14"
|
|
149
|
+
height="14"
|
|
150
|
+
viewBox="0 0 24 24"
|
|
151
|
+
fill="none"
|
|
152
|
+
stroke="currentColor"
|
|
153
|
+
stroke-width="2"
|
|
154
|
+
class="shrink-0 text-mute transition-opacity"
|
|
155
|
+
classList={{ 'opacity-0': i() !== highlight(), 'opacity-100': i() === highlight() }}
|
|
156
|
+
aria-hidden="true"
|
|
157
|
+
>
|
|
158
|
+
<path d="M5 12h14M13 6l6 6-6 6" stroke-linecap="round" stroke-linejoin="round" />
|
|
159
|
+
</svg>
|
|
160
|
+
</li>
|
|
161
|
+
)}
|
|
162
|
+
</For>
|
|
163
|
+
</ul>
|
|
164
|
+
</Show>
|
|
165
|
+
|
|
166
|
+
<div class="flex items-center gap-4 px-4 py-2 border-t border-line text-[0.7rem] text-mute">
|
|
167
|
+
<span class="flex items-center gap-1.5">
|
|
168
|
+
<Kbd>↑</Kbd>
|
|
169
|
+
<Kbd>↓</Kbd>
|
|
170
|
+
<span>navigate</span>
|
|
171
|
+
</span>
|
|
172
|
+
<span class="flex items-center gap-1.5">
|
|
173
|
+
<Kbd>↵</Kbd>
|
|
174
|
+
<span>open</span>
|
|
175
|
+
</span>
|
|
176
|
+
<Show when={list().length}>
|
|
177
|
+
<span class="ml-auto tabular-nums">
|
|
178
|
+
{list().length} result{list().length === 1 ? '' : 's'}
|
|
179
|
+
</span>
|
|
180
|
+
</Show>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
</Show>
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Map a route's direct children into search-hit rows for the default listing. */
|
|
189
|
+
const childHits = (project: Types.Project, route: Types.RouteNode): SearchHit[] => {
|
|
190
|
+
const out: SearchHit[] = []
|
|
191
|
+
for (const child of route.children) {
|
|
192
|
+
if (child.page.kind === 'markdown') continue
|
|
193
|
+
const decl = project.byId(child.page.id)
|
|
194
|
+
out.push({
|
|
195
|
+
name: child.label,
|
|
196
|
+
qualified: child.page.qualified,
|
|
197
|
+
kind: (decl?.kind ?? 'module') as Kind,
|
|
198
|
+
slug: child.slug,
|
|
199
|
+
file: decl?.sources?.[0]?.file ?? '',
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
return out
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const EmptyState = (props: { loading: boolean; term: string }) => (
|
|
206
|
+
<div class="flex-1 flex flex-col items-center justify-center text-center gap-3 px-6 py-16">
|
|
207
|
+
<Show
|
|
208
|
+
when={!props.loading}
|
|
209
|
+
fallback={
|
|
210
|
+
<>
|
|
211
|
+
<Spinner />
|
|
212
|
+
<p class="text-sm text-mute">Building search index…</p>
|
|
213
|
+
</>
|
|
214
|
+
}
|
|
215
|
+
>
|
|
216
|
+
<div class="flex items-center justify-center w-12 h-12 rounded-full bg-hover text-mute">
|
|
217
|
+
<SearchGlyph size={22} />
|
|
218
|
+
</div>
|
|
219
|
+
<Show
|
|
220
|
+
when={props.term}
|
|
221
|
+
fallback={
|
|
222
|
+
<>
|
|
223
|
+
<p class="text-sm font-medium text-fg">Search the API</p>
|
|
224
|
+
<p class="text-xs text-mute max-w-xs leading-relaxed">
|
|
225
|
+
Jump to any function, type, class or interface by name.
|
|
226
|
+
</p>
|
|
227
|
+
</>
|
|
228
|
+
}
|
|
229
|
+
>
|
|
230
|
+
<p class="text-sm font-medium text-fg">
|
|
231
|
+
No matches for <span class="font-mono">“{props.term}”</span>
|
|
232
|
+
</p>
|
|
233
|
+
<p class="text-xs text-mute">Try a shorter or different term.</p>
|
|
234
|
+
</Show>
|
|
235
|
+
</Show>
|
|
236
|
+
</div>
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
const Kbd = (props: { children: any }) => (
|
|
240
|
+
<kbd class="font-mono text-[0.65rem] text-mute bg-hover border border-line rounded px-1.5 py-0.5 leading-none">
|
|
241
|
+
{props.children}
|
|
242
|
+
</kbd>
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
const SearchGlyph = (props: { class?: string; size?: number }) => (
|
|
246
|
+
<svg
|
|
247
|
+
width={props.size ?? 16}
|
|
248
|
+
height={props.size ?? 16}
|
|
249
|
+
viewBox="0 0 24 24"
|
|
250
|
+
fill="none"
|
|
251
|
+
stroke="currentColor"
|
|
252
|
+
stroke-width="1.8"
|
|
253
|
+
class={props.class}
|
|
254
|
+
aria-hidden="true"
|
|
255
|
+
>
|
|
256
|
+
<circle cx="11" cy="11" r="7" />
|
|
257
|
+
<path d="m20 20-3.5-3.5" stroke-linecap="round" />
|
|
258
|
+
</svg>
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
const Spinner = () => (
|
|
262
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" class="animate-spin text-mute" aria-hidden="true">
|
|
263
|
+
<circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="2" class="opacity-25" />
|
|
264
|
+
<path d="M21 12a9 9 0 0 0-9-9" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
|
|
265
|
+
</svg>
|
|
266
|
+
)
|