handoff-app 2.0.0-0 → 2.0.0-10
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/AGENTS.md +7 -0
- package/CLAUDE.md +7 -0
- package/README.md +732 -304
- package/UPGRADE.md +218 -0
- package/config/config.template.js +1 -4
- package/config/config.template.ts +1 -2
- package/config/docs/foundations/colors/guidelines.md +9 -0
- package/config/docs/foundations/effects/guidelines.md +9 -0
- package/config/docs/foundations/effects/resources.md +9 -0
- package/config/docs/foundations/grid.md +10 -0
- package/config/docs/foundations/icons/guidelines.md +9 -0
- package/config/docs/foundations/images/guidelines.md +9 -0
- package/config/docs/foundations/images/resources.md +9 -0
- package/config/docs/foundations/images.md +10 -0
- package/config/docs/foundations/logo/resources.md +9 -0
- package/config/docs/foundations/typography/guidelines.md +9 -0
- package/config/docs/foundations/typography/resources.md +9 -0
- package/config/docs/foundations.md +5 -3
- package/dist/ai/connections.d.ts +64 -0
- package/dist/ai/connections.js +136 -0
- package/dist/ai/define.d.ts +10 -0
- package/dist/ai/define.js +13 -0
- package/dist/ai/types.d.ts +27 -0
- package/dist/ai/types.js +10 -0
- package/dist/app-builder/build.d.ts +12 -0
- package/dist/app-builder/build.js +227 -69
- package/dist/app-builder/client-config.js +16 -12
- package/dist/app-builder/config-diff/strategies/pattern.js +3 -3
- package/dist/app-builder/nav-shell.js +8 -15
- package/dist/app-builder/paths.js +23 -1
- package/dist/app-builder/static-export.js +25 -0
- package/dist/app-builder/vercel-output.js +6 -6
- package/dist/app-builder/watchers/component.js +5 -5
- package/dist/app-builder/watchers/utils.d.ts +2 -3
- package/dist/app-builder/watchers.d.ts +8 -15
- package/dist/app-builder/watchers.js +70 -61
- package/dist/artifacts/index.d.ts +1 -1
- package/dist/artifacts/index.js +4 -1
- package/dist/artifacts/url.d.ts +18 -0
- package/dist/artifacts/url.js +31 -1
- package/dist/cache/build-cache.js +23 -23
- package/dist/catalog/define.d.ts +6 -0
- package/dist/catalog/define.js +72 -0
- package/dist/catalog/implementation.d.ts +27 -0
- package/dist/catalog/implementation.js +133 -0
- package/dist/catalog/index.d.ts +6 -0
- package/dist/catalog/index.js +22 -0
- package/dist/catalog/normalize.d.ts +16 -0
- package/dist/catalog/normalize.js +118 -0
- package/dist/catalog/previews.d.ts +18 -0
- package/dist/catalog/previews.js +107 -0
- package/dist/catalog/renderers.d.ts +43 -0
- package/dist/catalog/renderers.js +62 -0
- package/dist/catalog/types.d.ts +71 -0
- package/dist/cli/auth/browser.d.ts +2 -0
- package/dist/cli/auth/browser.js +33 -0
- package/dist/cli/auth/device.d.ts +16 -0
- package/dist/cli/auth/device.js +158 -0
- package/dist/cli/auth/store.d.ts +38 -0
- package/dist/cli/auth/store.js +199 -0
- package/dist/cli/create.js +48 -3
- package/dist/cli/make.d.ts +0 -5
- package/dist/cli/make.js +24 -69
- package/dist/cli/scaffold.js +39 -181
- package/dist/cli.js +39 -7
- package/dist/commands/build/app.js +1 -5
- package/dist/commands/build/components.js +1 -5
- package/dist/commands/build/index.js +1 -5
- package/dist/commands/checkout/index.d.ts +18 -12
- package/dist/commands/checkout/index.js +19 -59
- package/dist/commands/compat/deprecations.d.ts +46 -0
- package/dist/commands/compat/deprecations.js +62 -0
- package/dist/commands/compat/push-args.d.ts +48 -0
- package/dist/commands/compat/push-args.js +73 -0
- package/dist/commands/db/migrate.js +1 -5
- package/dist/commands/dev/index.js +1 -5
- package/dist/commands/eject/config.js +1 -5
- package/dist/commands/eject/pages.js +1 -5
- package/dist/commands/eject/theme.js +1 -5
- package/dist/commands/fetch/index.js +1 -5
- package/dist/commands/index.js +8 -2
- package/dist/commands/login/index.d.ts +13 -0
- package/dist/commands/login/index.js +61 -0
- package/dist/commands/logout/index.d.ts +12 -0
- package/dist/commands/logout/index.js +89 -0
- package/dist/commands/make/component.js +1 -5
- package/dist/commands/make/page.js +3 -7
- package/dist/commands/publish/index.d.ts +21 -11
- package/dist/commands/publish/index.js +22 -58
- package/dist/commands/pull/index.d.ts +13 -0
- package/dist/commands/pull/index.js +20 -0
- package/dist/commands/push/index.d.ts +23 -0
- package/dist/commands/push/index.js +58 -0
- package/dist/commands/scaffold/index.js +1 -5
- package/dist/commands/start/index.js +1 -5
- package/dist/commands/types.d.ts +12 -0
- package/dist/commands/utils.d.ts +100 -1
- package/dist/commands/utils.js +103 -2
- package/dist/commands/validate/components.js +1 -5
- package/dist/config/catalog-include.d.ts +43 -0
- package/dist/config/catalog-include.js +203 -0
- package/dist/config/defaults.d.ts +4 -2
- package/dist/config/defaults.js +58 -49
- package/dist/config/env.d.ts +9 -0
- package/dist/config/env.js +43 -0
- package/dist/config/errors.d.ts +4 -0
- package/dist/config/errors.js +11 -0
- package/dist/config/from-env.d.ts +24 -0
- package/dist/config/from-env.js +7 -0
- package/dist/config/helpers.d.ts +2 -0
- package/dist/config/helpers.js +3 -1
- package/dist/config/index.d.ts +6 -2
- package/dist/config/index.js +12 -1
- package/dist/config/loader.d.ts +40 -9
- package/dist/config/loader.js +148 -35
- package/dist/config/normalizers/page.d.ts +4 -4
- package/dist/config/normalizers/page.js +2 -2
- package/dist/config/resolve-env.d.ts +6 -0
- package/dist/config/resolve-env.js +115 -0
- package/dist/config/runtime.d.ts +15 -16
- package/dist/config/runtime.js +178 -196
- package/dist/config/validator.d.ts +2 -2
- package/dist/config/validator.js +2 -4
- package/dist/handlebars.d.ts +17 -0
- package/dist/handlebars.js +16 -0
- package/dist/index.d.ts +120 -27
- package/dist/index.js +242 -53
- package/dist/nav/resolver.js +3 -1
- package/dist/nav/workspace.js +2 -2
- package/dist/pattern.d.ts +7 -0
- package/dist/pattern.js +13 -0
- package/dist/pipeline/index.d.ts +1 -1
- package/dist/pipeline/index.js +1 -1
- package/dist/react.d.ts +43 -0
- package/dist/react.js +11 -0
- package/dist/registry/asset-storage/adapters/vercel-blob.js +1 -1
- package/dist/registry/asset-storage/define.d.ts +1 -1
- package/dist/registry/asset-storage/define.js +1 -1
- package/dist/registry/asset-storage/resolve.d.ts +3 -3
- package/dist/registry/asset-storage/resolve.js +5 -2
- package/dist/registry/auth/access-tokens.d.ts +54 -0
- package/dist/registry/auth/access-tokens.js +191 -0
- package/dist/registry/auth/action-tokens.d.ts +66 -0
- package/dist/registry/auth/action-tokens.js +178 -0
- package/dist/registry/auth/ai-keys.d.ts +32 -0
- package/dist/registry/auth/ai-keys.js +69 -0
- package/dist/registry/auth/crypto.d.ts +21 -0
- package/dist/registry/auth/crypto.js +76 -0
- package/dist/registry/auth/database.d.ts +7 -0
- package/dist/registry/auth/database.js +22 -0
- package/dist/registry/auth/device-authorizations.d.ts +51 -0
- package/dist/registry/auth/device-authorizations.js +170 -0
- package/dist/registry/auth/gravatar.d.ts +1 -0
- package/dist/registry/auth/gravatar.js +8 -0
- package/dist/registry/auth/index.d.ts +13 -0
- package/dist/registry/auth/index.js +89 -0
- package/dist/registry/auth/installation.d.ts +42 -0
- package/dist/registry/auth/installation.js +105 -0
- package/dist/registry/auth/password.d.ts +12 -0
- package/dist/registry/auth/password.js +58 -0
- package/dist/registry/auth/rate-limits.d.ts +22 -0
- package/dist/registry/auth/rate-limits.js +75 -0
- package/dist/registry/auth/sync-secret.d.ts +27 -0
- package/dist/registry/auth/sync-secret.js +65 -0
- package/dist/registry/auth/types.d.ts +45 -0
- package/dist/registry/auth/types.js +11 -0
- package/dist/registry/auth/user-record.d.ts +13 -0
- package/dist/registry/auth/user-record.js +16 -0
- package/dist/registry/auth/users.d.ts +31 -0
- package/dist/registry/auth/users.js +135 -0
- package/dist/registry/auth/validation.d.ts +14 -0
- package/dist/registry/auth/validation.js +45 -0
- package/dist/registry/checkout/assets.d.ts +1 -1
- package/dist/registry/checkout/assets.js +25 -8
- package/dist/registry/checkout/index.d.ts +27 -6
- package/dist/registry/checkout/index.js +479 -131
- package/dist/registry/checkout/tokens.d.ts +1 -1
- package/dist/registry/checkout/tokens.js +16 -7
- package/dist/registry/client.d.ts +2 -1
- package/dist/registry/client.js +8 -0
- package/dist/registry/connection.d.ts +34 -11
- package/dist/registry/connection.js +77 -18
- package/dist/registry/content-kinds.d.ts +27 -0
- package/dist/registry/content-kinds.js +33 -0
- package/dist/registry/db/client.d.ts +14 -9
- package/dist/registry/db/client.js +22 -9
- package/dist/registry/db/driver.d.ts +39 -0
- package/dist/registry/db/driver.js +50 -0
- package/dist/registry/db/index.d.ts +2 -2
- package/dist/registry/db/index.js +14 -9
- package/dist/registry/db/migrate.d.ts +1 -1
- package/dist/registry/db/migrate.js +5 -5
- package/dist/registry/db/schema.d.ts +2992 -963
- package/dist/registry/db/schema.js +158 -8
- package/dist/registry/publish/assets.d.ts +2 -2
- package/dist/registry/publish/assets.js +46 -35
- package/dist/registry/publish/errors.js +3 -3
- package/dist/registry/publish/index.d.ts +45 -3
- package/dist/registry/publish/index.js +247 -24
- package/dist/registry/publish/package.js +14 -1
- package/dist/registry/publish/tokens.d.ts +2 -2
- package/dist/registry/publish/tokens.js +30 -24
- package/dist/registry/selection.d.ts +32 -0
- package/dist/registry/selection.js +58 -0
- package/dist/registry/transfer.d.ts +13 -0
- package/dist/store/filesystem.d.ts +3 -3
- package/dist/store/filesystem.js +7 -7
- package/dist/store/registry.d.ts +48 -0
- package/dist/store/registry.js +99 -15
- package/dist/transformers/plugins/csf-render.js +4 -2
- package/dist/transformers/plugins/ssr-render.js +52 -18
- package/dist/transformers/preview/component/api.d.ts +8 -0
- package/dist/transformers/preview/component/api.js +11 -15
- package/dist/transformers/preview/component/artifacts.d.ts +1 -1
- package/dist/transformers/preview/component/artifacts.js +11 -7
- package/dist/transformers/preview/component/builder.js +15 -18
- package/dist/transformers/preview/component/css.d.ts +3 -0
- package/dist/transformers/preview/component/css.js +93 -58
- package/dist/transformers/preview/component/html.js +18 -16
- package/dist/transformers/preview/component/javascript.js +2 -4
- package/dist/transformers/preview/pattern/builder.js +31 -18
- package/dist/transformers/preview/pattern/html.js +3 -1
- package/dist/transformers/preview/types.d.ts +30 -3
- package/dist/transformers/utils/build.d.ts +19 -0
- package/dist/transformers/utils/build.js +83 -1
- package/dist/transformers/utils/module.js +2 -1
- package/dist/types/config.d.ts +156 -45
- package/dist/utils/markdown.d.ts +10 -0
- package/dist/utils/markdown.js +17 -0
- package/dist/utils/menu-shell.js +14 -7
- package/dist/utils/pages.d.ts +22 -0
- package/dist/utils/pages.js +73 -0
- package/dist/utils/path.d.ts +5 -0
- package/dist/utils/path.js +9 -0
- package/docs/api.md +35 -3
- package/docs/cli.md +6 -2
- package/drizzle/0002_add_pages.sql +5 -3
- package/drizzle/0005_add_registry_auth.sql +95 -0
- package/drizzle/0006_add_component_source_format.sql +3 -0
- package/drizzle/0007_add_ai_keys.sql +11 -0
- package/drizzle/meta/0002_snapshot.json +17 -8
- package/drizzle/meta/0003_snapshot.json +17 -8
- package/drizzle/meta/0004_snapshot.json +17 -8
- package/drizzle/meta/0005_snapshot.json +1935 -0
- package/drizzle/meta/0006_snapshot.json +1941 -0
- package/drizzle/meta/0007_snapshot.json +2013 -0
- package/drizzle/meta/_journal.json +21 -0
- package/drizzle.config.ts +1 -1
- package/package.json +44 -5
- package/src/ai/README.md +42 -0
- package/src/ai/connections.ts +172 -0
- package/src/ai/define.ts +15 -0
- package/src/ai/types.ts +31 -0
- package/src/app/components/AiAssistant/AiAssistantPanel.tsx +144 -0
- package/src/app/components/AiAssistant/AiAssistantProvider.tsx +215 -0
- package/src/app/components/AiAssistant/AiConversation.tsx +674 -0
- package/src/app/components/AiAssistant/AiToolResult.tsx +99 -0
- package/src/app/components/AiAssistant/dockState.ts +86 -0
- package/src/app/components/AiAssistant/toolLabel.ts +22 -0
- package/src/app/components/AiAssistant/useAiChat.ts +147 -0
- package/src/app/components/AiAssistant/useAiConnections.ts +86 -0
- package/src/app/components/AiAssistant/usePageContext.ts +59 -0
- package/src/app/components/Auth/AccountLayout.tsx +124 -0
- package/src/app/components/Auth/AuthControls.tsx +99 -0
- package/src/app/components/Auth/AuthShell.tsx +73 -0
- package/src/app/components/Auth/RegistryInstallGate.tsx +23 -0
- package/src/app/components/Auth/RegistrySessionProvider.tsx +15 -0
- package/src/app/components/Auth/api.ts +20 -0
- package/src/app/components/Component/PageSliceResolver.tsx +1 -0
- package/src/app/components/Component/Preview.tsx +406 -226
- package/src/app/components/Component/slices/ComponentDisplaySlice.tsx +4 -0
- package/src/app/components/CopyToClipboard.tsx +27 -26
- package/src/app/components/Foundations/DisplayLogo.tsx +8 -2
- package/src/app/components/Layout/Header.tsx +10 -14
- package/src/app/components/Layout/RuntimeModeBadge.tsx +18 -0
- package/src/app/components/Markdown/CodeHighlight.tsx +73 -70
- package/src/app/components/Markdown/MarkdownComponents.tsx +30 -32
- package/src/app/components/McpIntegration/McpConfigDialog.tsx +349 -0
- package/src/app/components/McpIntegration/McpIcon.tsx +10 -0
- package/src/app/components/Navigation/MobileNav.tsx +7 -1
- package/src/app/components/Navigation/SideNav.tsx +1 -15
- package/src/app/components/context/PreviewContext.tsx +5 -5
- package/src/app/components/ui/attachment.tsx +50 -0
- package/src/app/components/ui/bubble.tsx +57 -0
- package/src/app/components/ui/button.tsx +3 -1
- package/src/app/components/ui/dialog.tsx +73 -0
- package/src/app/components/ui/marker.tsx +56 -0
- package/src/app/components/ui/sidebar.tsx +3 -1
- package/src/app/components/util/index.ts +14 -38
- package/src/app/css/index.css +64 -0
- package/src/app/lib/ai/auth.ts +33 -0
- package/src/app/lib/ai/context.ts +96 -0
- package/src/app/lib/ai/model.ts +85 -0
- package/src/app/lib/ai/prompt.ts +36 -0
- package/src/app/lib/ai/resolve.ts +97 -0
- package/src/app/lib/ai/tools.ts +120 -0
- package/src/app/lib/api/methods.ts +13 -0
- package/src/app/lib/auth/api.ts +105 -0
- package/src/app/lib/auth/config.ts +175 -0
- package/src/app/lib/auth/email.ts +34 -0
- package/src/app/lib/docs-api/backend.ts +16 -1
- package/src/app/lib/docs-api/errors.ts +8 -7
- package/src/app/lib/docs-api/handler.ts +2 -3
- package/src/app/lib/docs-api/index.ts +2 -0
- package/src/app/lib/docs-api/page-discovery.ts +121 -0
- package/src/app/lib/docs-api/page-rendering.ts +37 -0
- package/src/app/lib/docs-api/page-search.ts +191 -0
- package/src/app/lib/docs-api/records.ts +31 -24
- package/src/app/lib/docs-api/registry.ts +92 -11
- package/src/app/lib/docs-api/runtime-config.ts +42 -35
- package/src/app/lib/docs-api/search.ts +120 -0
- package/src/app/lib/mcp/auth.ts +64 -0
- package/src/app/lib/mcp/index.ts +2 -0
- package/src/app/lib/mcp/server.ts +357 -0
- package/src/app/lib/mcp/shape.ts +628 -0
- package/src/app/lib/registry-api/allowlist.ts +7 -5
- package/src/app/lib/registry-api/asset-transfer.ts +58 -31
- package/src/app/lib/registry-api/auth.ts +108 -45
- package/src/app/lib/registry-api/entity-routes.ts +17 -7
- package/src/app/lib/registry-api/errors.ts +12 -6
- package/src/app/lib/registry-api/handler.ts +22 -19
- package/src/app/lib/registry-api/meta.ts +4 -0
- package/src/app/lib/registry-api/revalidate.ts +31 -12
- package/src/app/lib/registry-api/store.ts +89 -26
- package/src/app/lib/registry-api/sync-compat.ts +166 -0
- package/src/app/lib/registry-api/token-transfer.ts +45 -13
- package/src/app/lib/registry-api/transfer-batch.ts +116 -0
- package/src/app/lib/registry-api/transfer.ts +99 -41
- package/src/app/lib/registry-api/validation.ts +33 -1
- package/src/app/lib/registry-connection.ts +2 -2
- package/src/app/lib/utils.ts +13 -0
- package/src/app/next.config.mjs +62 -16
- package/src/app/pages/[...slug]/index.tsx +52 -51
- package/src/app/pages/_app.tsx +14 -4
- package/src/app/pages/_document.tsx +6 -0
- package/src/app/pages/account/ai.tsx +162 -0
- package/src/app/pages/account/index.tsx +148 -0
- package/src/app/pages/account/tokens.tsx +232 -0
- package/src/app/pages/account/users.tsx +310 -0
- package/src/app/pages/api/account/ai/keys/[connectionId].ts +60 -0
- package/src/app/pages/api/account/ai/keys/index.ts +20 -0
- package/src/app/pages/api/account/index.ts +26 -0
- package/src/app/pages/api/account/tokens/[id].ts +17 -0
- package/src/app/pages/api/account/tokens/index.ts +35 -0
- package/src/app/pages/api/admin/users/[id]/[action].ts +89 -0
- package/src/app/pages/api/admin/users/index.ts +53 -0
- package/src/app/pages/api/ai/chat.ts +115 -0
- package/src/app/pages/api/ai/connections.ts +23 -0
- package/src/app/pages/api/auth/[...nextauth].ts +4 -0
- package/src/app/pages/api/auth/request-reset.ts +53 -0
- package/src/app/pages/api/auth/reset-password.ts +29 -0
- package/src/app/pages/api/docs/search/pages.json.ts +25 -0
- package/src/app/pages/api/install.ts +102 -0
- package/src/app/pages/api/mcp.ts +56 -0
- package/src/app/pages/api/oauth/device/approve.ts +23 -0
- package/src/app/pages/api/oauth/device/index.ts +41 -0
- package/src/app/pages/api/oauth/revoke.ts +31 -0
- package/src/app/pages/api/oauth/token.ts +31 -0
- package/src/app/pages/api/registry/components/[id]/files/[...filePath].ts +1 -1
- package/src/app/pages/api/registry/components/[id].ts +2 -2
- package/src/app/pages/api/registry/components/index.ts +1 -1
- package/src/app/pages/api/registry/health.ts +4 -3
- package/src/app/pages/api/registry/pages/[...id].ts +20 -0
- package/src/app/pages/api/registry/pages/index.ts +19 -0
- package/src/app/pages/api/registry/patterns/[id]/files/[...filePath].ts +1 -1
- package/src/app/pages/api/registry/patterns/[id].ts +2 -2
- package/src/app/pages/api/registry/patterns/index.ts +1 -1
- package/src/app/pages/api/registry/transfer/[kind]/[id].ts +3 -3
- package/src/app/pages/api/registry/transfer/[kind]/index.ts +21 -0
- package/src/app/pages/api/registry/transfer/assets/[collection].ts +2 -1
- package/src/app/pages/api/registry/transfer/assets/blobs/[hash].ts +2 -1
- package/src/app/pages/api/registry/transfer/assets/blobs/have.ts +2 -2
- package/src/app/pages/api/registry/transfer/tokens/[...setId].ts +2 -2
- package/src/app/pages/api/sync/upload.ts +21 -0
- package/src/app/pages/assets/logos.tsx +4 -1
- package/src/app/pages/cli/device.tsx +143 -0
- package/src/app/pages/foundations/icons/index.tsx +7 -5
- package/src/app/pages/foundations/icons/{[name] → library/[name]}/index.tsx +8 -8
- package/src/app/pages/foundations/logo.tsx +5 -4
- package/src/app/pages/index/index.tsx +14 -0
- package/src/app/pages/index.tsx +31 -5
- package/src/app/pages/install.tsx +336 -0
- package/src/app/pages/login.tsx +117 -0
- package/src/app/pages/reset-password.tsx +159 -0
- package/src/app/types/next-auth.d.ts +27 -0
- package/src/app-builder/build.ts +225 -86
- package/src/app-builder/client-config.ts +18 -14
- package/src/app-builder/config-diff/strategies/pattern.ts +1 -1
- package/src/app-builder/nav-shell.ts +8 -13
- package/src/app-builder/paths.ts +25 -1
- package/src/app-builder/static-export.ts +27 -0
- package/src/app-builder/vercel-output.ts +6 -6
- package/src/app-builder/watchers/component.ts +3 -3
- package/src/app-builder/watchers/utils.ts +2 -3
- package/src/app-builder/watchers.ts +63 -57
- package/src/artifacts/index.ts +8 -1
- package/src/artifacts/url.ts +32 -0
- package/src/cache/build-cache.ts +16 -15
- package/src/catalog/README.md +95 -0
- package/src/catalog/define.ts +79 -0
- package/src/catalog/implementation.ts +145 -0
- package/src/catalog/index.ts +31 -0
- package/src/catalog/normalize.ts +145 -0
- package/src/catalog/previews.ts +114 -0
- package/src/catalog/renderers.ts +94 -0
- package/src/catalog/types.ts +82 -0
- package/src/cli/README.md +1 -1
- package/src/cli/auth/browser.ts +29 -0
- package/src/cli/auth/device.ts +186 -0
- package/src/cli/auth/store.ts +194 -0
- package/src/cli/create.ts +58 -3
- package/src/cli/make.ts +22 -74
- package/src/cli/scaffold.ts +39 -222
- package/src/cli.ts +31 -7
- package/src/commands/README.md +1 -1
- package/src/commands/build/app.ts +2 -3
- package/src/commands/build/components.ts +2 -3
- package/src/commands/build/index.ts +2 -3
- package/src/commands/checkout/index.ts +29 -50
- package/src/commands/compat/deprecations.ts +79 -0
- package/src/commands/compat/push-args.ts +106 -0
- package/src/commands/db/migrate.ts +2 -3
- package/src/commands/dev/index.ts +2 -3
- package/src/commands/eject/config.ts +2 -3
- package/src/commands/eject/pages.ts +2 -3
- package/src/commands/eject/theme.ts +2 -3
- package/src/commands/fetch/index.ts +2 -3
- package/src/commands/index.ts +8 -2
- package/src/commands/login/index.ts +61 -0
- package/src/commands/logout/index.ts +104 -0
- package/src/commands/make/component.ts +2 -3
- package/src/commands/make/page.ts +4 -5
- package/src/commands/publish/index.ts +32 -49
- package/src/commands/pull/index.ts +32 -0
- package/src/commands/push/index.ts +115 -0
- package/src/commands/scaffold/index.ts +2 -3
- package/src/commands/start/index.ts +2 -3
- package/src/commands/types.ts +13 -1
- package/src/commands/utils.ts +107 -2
- package/src/commands/validate/components.ts +2 -3
- package/src/config/README.md +63 -2
- package/src/config/catalog-include.ts +227 -0
- package/src/config/defaults.ts +26 -13
- package/src/config/env.ts +41 -0
- package/src/config/errors.ts +7 -0
- package/src/config/from-env.ts +26 -0
- package/src/config/helpers.ts +4 -2
- package/src/config/index.ts +10 -2
- package/src/config/loader.ts +208 -43
- package/src/config/normalizers/page.ts +4 -4
- package/src/config/resolve-env.ts +107 -0
- package/src/config/runtime.ts +212 -226
- package/src/config/validator.ts +4 -6
- package/src/handlebars.ts +24 -0
- package/src/index.d.ts +2 -2
- package/src/index.ts +325 -72
- package/src/nav/resolver.ts +3 -1
- package/src/nav/workspace.ts +2 -2
- package/src/pattern.ts +14 -0
- package/src/pipeline/index.ts +1 -1
- package/src/react.ts +52 -0
- package/src/registry/asset-storage/adapters/vercel-blob.ts +1 -1
- package/src/registry/asset-storage/define.ts +1 -1
- package/src/registry/asset-storage/resolve.ts +7 -4
- package/src/registry/auth/access-tokens.ts +222 -0
- package/src/registry/auth/action-tokens.ts +225 -0
- package/src/registry/auth/ai-keys.ts +62 -0
- package/src/registry/auth/crypto.ts +75 -0
- package/src/registry/auth/database.ts +15 -0
- package/src/registry/auth/device-authorizations.ts +223 -0
- package/src/registry/auth/gravatar.ts +6 -0
- package/src/registry/auth/index.ts +105 -0
- package/src/registry/auth/installation.ts +117 -0
- package/src/registry/auth/password.ts +46 -0
- package/src/registry/auth/rate-limits.ts +84 -0
- package/src/registry/auth/sync-secret.ts +67 -0
- package/src/registry/auth/types.ts +57 -0
- package/src/registry/auth/user-record.ts +25 -0
- package/src/registry/auth/users.ts +145 -0
- package/src/registry/auth/validation.ts +42 -0
- package/src/registry/checkout/assets.ts +28 -9
- package/src/registry/checkout/index.ts +582 -130
- package/src/registry/checkout/tokens.ts +16 -8
- package/src/registry/client.ts +7 -1
- package/src/registry/connection.ts +91 -19
- package/src/registry/content-kinds.ts +39 -0
- package/src/registry/db/client.ts +34 -14
- package/src/registry/db/driver.ts +66 -0
- package/src/registry/db/index.ts +16 -5
- package/src/registry/db/migrate.ts +5 -5
- package/src/registry/db/schema.ts +225 -25
- package/src/registry/publish/assets.ts +47 -37
- package/src/registry/publish/errors.ts +3 -3
- package/src/registry/publish/index.ts +286 -27
- package/src/registry/publish/package.ts +14 -1
- package/src/registry/publish/tokens.ts +35 -26
- package/src/registry/selection.ts +63 -0
- package/src/registry/transfer.ts +14 -0
- package/src/store/filesystem.ts +6 -6
- package/src/store/registry.ts +131 -15
- package/src/transformers/plugins/csf-render.ts +4 -2
- package/src/transformers/plugins/ssr-render.ts +66 -19
- package/src/transformers/preview/component/api.ts +13 -1
- package/src/transformers/preview/component/artifacts.ts +8 -4
- package/src/transformers/preview/component/builder.ts +17 -4
- package/src/transformers/preview/component/css.ts +99 -60
- package/src/transformers/preview/component/html.ts +30 -19
- package/src/transformers/preview/component/javascript.ts +1 -3
- package/src/transformers/preview/pattern/builder.ts +33 -20
- package/src/transformers/preview/pattern/html.ts +3 -1
- package/src/transformers/preview/types.ts +31 -3
- package/src/transformers/utils/build.ts +80 -0
- package/src/transformers/utils/module.ts +4 -2
- package/src/types/config.ts +168 -45
- package/src/utils/README.md +1 -0
- package/src/utils/markdown.ts +11 -0
- package/src/utils/menu-shell.ts +14 -7
- package/src/utils/pages.ts +52 -0
- package/src/utils/path.ts +15 -6
- package/templates/default/README.md.tpl +68 -1
- package/templates/default/components/button/button.react.handoff.js.tpl +19 -23
- package/templates/default/components/button/button.react.handoff.ts.tpl +22 -22
- package/templates/default/env.tpl +10 -0
- package/templates/default/gitignore.tpl +26 -3
- package/templates/default/handoff.config.js.tpl +21 -166
- package/templates/default/handoff.config.ts.tpl +21 -150
- package/templates/default/handoff.config.with-examples.js.tpl +22 -164
- package/templates/default/handoff.config.with-examples.ts.tpl +22 -148
- package/templates/default/package.json.tpl +6 -1
- package/templates/default/vercel.json.tpl +4 -0
- package/config/docs/foundations/logos.md +0 -7
- package/config/templates/component/template.json +0 -49
- package/config/templates/template.html +0 -7
- package/dist/commands/make/template.d.ts +0 -8
- package/dist/commands/make/template.js +0 -47
- package/dist/config/normalizers/declaration.d.ts +0 -11
- package/dist/config/normalizers/declaration.js +0 -122
- package/dist/config/normalizers/pattern.d.ts +0 -8
- package/dist/config/normalizers/pattern.js +0 -41
- package/dist/declarations/helpers.d.ts +0 -6
- package/dist/declarations/helpers.js +0 -19
- package/dist/declarations/index.d.ts +0 -2
- package/dist/declarations/index.js +0 -9
- package/dist/declarations/types.d.ts +0 -60
- package/dist/registry/db/adapter.d.ts +0 -43
- package/dist/registry/db/adapter.js +0 -59
- package/src/app/lib/api/redact.ts +0 -46
- package/src/commands/make/template.ts +0 -47
- package/src/config/normalizers/declaration.ts +0 -179
- package/src/config/normalizers/pattern.ts +0 -59
- package/src/declarations/helpers.ts +0 -36
- package/src/declarations/index.ts +0 -19
- package/src/declarations/types.ts +0 -70
- package/src/registry/db/adapter.ts +0 -74
- /package/dist/{declarations → catalog}/types.js +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PreviewWidth } from '@handoff/transformers/preview/types';
|
|
1
2
|
import { PreviewObject } from '@handoff/types/preview';
|
|
2
3
|
import { Filter, evaluateFilter } from '@handoff/utils/filter';
|
|
3
4
|
import React from 'react';
|
|
@@ -13,6 +14,7 @@ export interface ComponentDisplaySliceProps {
|
|
|
13
14
|
showPreview?: boolean;
|
|
14
15
|
showCodeHighlight?: boolean;
|
|
15
16
|
defaultHeight?: string;
|
|
17
|
+
defaultWidth?: PreviewWidth;
|
|
16
18
|
filterBy?: Filter;
|
|
17
19
|
codeHighlight?: boolean;
|
|
18
20
|
}
|
|
@@ -38,6 +40,7 @@ const ComponentDisplaySlice: React.FC<ComponentDisplaySliceProps> = ({
|
|
|
38
40
|
showPreview = true,
|
|
39
41
|
showCodeHighlight,
|
|
40
42
|
defaultHeight,
|
|
43
|
+
defaultWidth,
|
|
41
44
|
filterBy,
|
|
42
45
|
codeHighlight = true,
|
|
43
46
|
}) => {
|
|
@@ -68,6 +71,7 @@ const ComponentDisplaySlice: React.FC<ComponentDisplaySliceProps> = ({
|
|
|
68
71
|
title={title}
|
|
69
72
|
component={filteredPreview}
|
|
70
73
|
defaultHeight={finalDefaultHeight}
|
|
74
|
+
defaultWidth={defaultWidth}
|
|
71
75
|
onPreviewChange={onPreviewChange}
|
|
72
76
|
/>
|
|
73
77
|
)}
|
|
@@ -7,11 +7,14 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './ui/t
|
|
|
7
7
|
|
|
8
8
|
type CopyToClipboardProps = {
|
|
9
9
|
value: string;
|
|
10
|
+
/** Accessible name for the control, and the hover tooltip unless `showTooltip` is off. */
|
|
10
11
|
tooltip: string;
|
|
12
|
+
/** Hide the tooltip where the surrounding UI already says what the button copies. */
|
|
13
|
+
showTooltip?: boolean;
|
|
11
14
|
className?: string;
|
|
12
15
|
};
|
|
13
16
|
|
|
14
|
-
export const CopyToClipboard: React.FC<CopyToClipboardProps> = ({ value, tooltip, className }) => {
|
|
17
|
+
export const CopyToClipboard: React.FC<CopyToClipboardProps> = ({ value, tooltip, showTooltip = true, className }) => {
|
|
15
18
|
const [copied, setCopied] = React.useState<boolean>(false);
|
|
16
19
|
|
|
17
20
|
const handleCopy = async () => {
|
|
@@ -24,33 +27,32 @@ export const CopyToClipboard: React.FC<CopyToClipboardProps> = ({ value, tooltip
|
|
|
24
27
|
}
|
|
25
28
|
};
|
|
26
29
|
|
|
30
|
+
const button = (
|
|
31
|
+
<Button
|
|
32
|
+
variant="outline"
|
|
33
|
+
size="icon"
|
|
34
|
+
className={cn('disabled:opacity-100', className)}
|
|
35
|
+
onClick={handleCopy}
|
|
36
|
+
aria-label={copied ? 'Copied' : tooltip}
|
|
37
|
+
disabled={copied}
|
|
38
|
+
>
|
|
39
|
+
<div className={cn('transition-all', copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0')}>
|
|
40
|
+
<CheckIcon className="stroke-gray-600" size={16} aria-hidden="true" />
|
|
41
|
+
</div>
|
|
42
|
+
<div className={cn('absolute transition-all', copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100')}>
|
|
43
|
+
<CopyIcon aria-hidden="true" />
|
|
44
|
+
</div>
|
|
45
|
+
</Button>
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
if (!showTooltip) {
|
|
49
|
+
return button;
|
|
50
|
+
}
|
|
51
|
+
|
|
27
52
|
return (
|
|
28
53
|
<TooltipProvider delayDuration={0}>
|
|
29
54
|
<Tooltip>
|
|
30
|
-
<TooltipTrigger asChild>
|
|
31
|
-
<Button
|
|
32
|
-
variant="outline"
|
|
33
|
-
size="icon"
|
|
34
|
-
className={cn('disabled:opacity-100', className)}
|
|
35
|
-
onClick={handleCopy}
|
|
36
|
-
aria-label={copied ? 'Copied' : 'Copy to clipboard'}
|
|
37
|
-
disabled={copied}
|
|
38
|
-
>
|
|
39
|
-
<div
|
|
40
|
-
className={cn('transition-all', copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0')}
|
|
41
|
-
>
|
|
42
|
-
<CheckIcon className="stroke-gray-600" size={16} aria-hidden="true" />
|
|
43
|
-
</div>
|
|
44
|
-
<div
|
|
45
|
-
className={cn(
|
|
46
|
-
'absolute transition-all',
|
|
47
|
-
copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'
|
|
48
|
-
)}
|
|
49
|
-
>
|
|
50
|
-
<CopyIcon aria-hidden="true" />
|
|
51
|
-
</div>
|
|
52
|
-
</Button>
|
|
53
|
-
</TooltipTrigger>
|
|
55
|
+
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
|
54
56
|
<TooltipContent className="px-2 py-1 text-xs">{tooltip}</TooltipContent>
|
|
55
57
|
</Tooltip>
|
|
56
58
|
</TooltipProvider>
|
|
@@ -58,4 +60,3 @@ export const CopyToClipboard: React.FC<CopyToClipboardProps> = ({ value, tooltip
|
|
|
58
60
|
};
|
|
59
61
|
|
|
60
62
|
export default CopyToClipboard;
|
|
61
|
-
|
|
@@ -2,11 +2,17 @@ import React from 'react';
|
|
|
2
2
|
import type { DisplayableAsset } from '../util/useCollectionAssets';
|
|
3
3
|
|
|
4
4
|
export const DisplayLogo: React.FC<{ logo: DisplayableAsset; content?: string; correct?: boolean }> = ({ logo, content }) => {
|
|
5
|
-
//
|
|
5
|
+
// Workspace/static ships the SVG body inline in tokens.json (`data`), so render it directly and
|
|
6
|
+
// avoid depending on the fetch-only `/api/assets/logos/*` files that a static host won't have.
|
|
7
|
+
// Registry has no inline body, so it falls back to the individual asset content URL (`src`).
|
|
6
8
|
const src = logo.src ?? `${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/assets/logos/${logo.path}`;
|
|
7
9
|
return (
|
|
8
10
|
<div className="flex flex-col gap-5">
|
|
9
|
-
|
|
11
|
+
{logo.data ? (
|
|
12
|
+
<div className="rounded-3xl" dangerouslySetInnerHTML={{ __html: logo.data }} />
|
|
13
|
+
) : (
|
|
14
|
+
<img src={src} alt={logo.name} className="rounded-3xl" />
|
|
15
|
+
)}
|
|
10
16
|
<div className="flex flex-row gap-4">
|
|
11
17
|
<img src={`${process.env.HANDOFF_APP_BASE_PATH ?? ''}/assets/images/check-circle.svg`} alt="Do" className="h-6 w-6" />
|
|
12
18
|
<p className="leading-normal text-gray-500">
|
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
import Link from 'next/link';
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
|
+
import { AiAssistantTrigger } from '../../components/AiAssistant/AiAssistantProvider';
|
|
4
|
+
import { McpConfigDialog } from '../../components/McpIntegration/McpConfigDialog';
|
|
3
5
|
import { ModeToggle } from '../../components/ModeSwitcher';
|
|
4
6
|
import { MainNav } from '../../components/Navigation/MainNav';
|
|
5
7
|
import { MobileNav } from '../../components/Navigation/MobileNav';
|
|
6
8
|
import { cn } from '../../lib/utils';
|
|
7
|
-
import { Badge } from '../ui/badge';
|
|
8
9
|
import { useConfigContext } from '../context/ConfigContext';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
workspace: 'Workspace',
|
|
12
|
-
registry: 'Registry',
|
|
13
|
-
};
|
|
10
|
+
import { AuthControls } from '../Auth/AuthControls';
|
|
11
|
+
import { RuntimeModeBadge } from './RuntimeModeBadge';
|
|
14
12
|
|
|
15
13
|
export function Header() {
|
|
16
14
|
const context = useConfigContext();
|
|
17
15
|
const [isScrolled, setIsScrolled] = useState(false);
|
|
18
16
|
const runtimeMode = context.config?.runtime?.mode ?? 'workspace';
|
|
19
|
-
const runtimeModeLabel = RUNTIME_MODE_LABEL[runtimeMode];
|
|
20
17
|
// The static export is a self-contained snapshot of the workspace, not a live runtime, so the
|
|
21
18
|
// runtime-mode badge carries no meaning there and is omitted.
|
|
22
19
|
const isStaticSnapshot = process.env.HANDOFF_BUILD_TARGET === 'static';
|
|
@@ -33,8 +30,8 @@ export function Header() {
|
|
|
33
30
|
return (
|
|
34
31
|
<div
|
|
35
32
|
className={cn(
|
|
36
|
-
'sticky top-0 z-50 py-4 shadow-[0_0_3px_0_rgba(0,0,0,0.15)] backdrop-blur-sm transition-all duration-300',
|
|
37
|
-
isScrolled && 'bg-background/70
|
|
33
|
+
'ai-dock-bleed h-17 sticky top-0 z-50 py-4 shadow-[0_0_3px_0_rgba(0,0,0,0.15)] backdrop-blur-sm transition-all duration-300',
|
|
34
|
+
isScrolled && 'bg-background/70 shadow-[0_0_4px_0_rgba(0,0,0,0.15)]'
|
|
38
35
|
)}
|
|
39
36
|
>
|
|
40
37
|
<header className="border-grid container mx-auto w-full max-w-[1500px] bg-transparent px-8">
|
|
@@ -43,14 +40,13 @@ export function Header() {
|
|
|
43
40
|
<Link href="/">
|
|
44
41
|
<img className="max-h-5" src={`${process.env.HANDOFF_APP_BASE_PATH ?? ''}/logo.svg`} alt={context.config?.app?.title} />
|
|
45
42
|
</Link>
|
|
46
|
-
{!isStaticSnapshot &&
|
|
47
|
-
<Badge variant={runtimeMode === 'registry' ? 'info' : 'default'} aria-label={`Runtime mode: ${runtimeModeLabel}`}>
|
|
48
|
-
{runtimeModeLabel}
|
|
49
|
-
</Badge>
|
|
50
|
-
)}
|
|
43
|
+
{!isStaticSnapshot && <RuntimeModeBadge mode={runtimeMode} />}
|
|
51
44
|
</div>
|
|
52
45
|
<div className="hidden items-center gap-4 @2xl:flex">
|
|
53
46
|
<MainNav />
|
|
47
|
+
<AiAssistantTrigger />
|
|
48
|
+
<McpConfigDialog />
|
|
49
|
+
{runtimeMode === 'registry' ? <AuthControls /> : null}
|
|
54
50
|
<ModeToggle />
|
|
55
51
|
</div>
|
|
56
52
|
<div className="flex items-center gap-4 @2xl:hidden">
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { RuntimeMode } from '@handoff/types/config';
|
|
2
|
+
import { Badge } from '../ui/badge';
|
|
3
|
+
|
|
4
|
+
const LABEL: Record<RuntimeMode, string> = {
|
|
5
|
+
workspace: 'Workspace',
|
|
6
|
+
registry: 'Registry',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The Workspace/Registry marker, shared by the header and the MCP connect dialog. `mode` is a prop
|
|
11
|
+
* because the header reads the projected client config while the dialog reads the mode baked into
|
|
12
|
+
* the bundle.
|
|
13
|
+
*/
|
|
14
|
+
export const RuntimeModeBadge: React.FC<{ mode: RuntimeMode; className?: string }> = ({ mode, className }) => (
|
|
15
|
+
<Badge variant={mode === 'registry' ? 'info' : 'default'} className={className} aria-label={`Runtime mode: ${LABEL[mode]}`}>
|
|
16
|
+
{LABEL[mode]}
|
|
17
|
+
</Badge>
|
|
18
|
+
);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RendererKind } from '@handoff/catalog/renderers';
|
|
1
2
|
import { PreviewObject } from '@handoff/types/preview';
|
|
2
3
|
// @ts-ignore
|
|
3
4
|
import { CollapsibleTrigger } from '@radix-ui/react-collapsible';
|
|
@@ -34,6 +35,60 @@ SyntaxHighlighter.registerLanguage('html', html);
|
|
|
34
35
|
SyntaxHighlighter.registerLanguage('xml', html);
|
|
35
36
|
SyntaxHighlighter.registerLanguage('handlebars', handlebars);
|
|
36
37
|
SyntaxHighlighter.registerLanguage('hbs', handlebars);
|
|
38
|
+
|
|
39
|
+
type CodeFormat = { label: string; language: string };
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* How each renderer's implementation code is shown. Exhaustive over `RendererKind`, so a new
|
|
43
|
+
* renderer fails to compile until its label and highlighting are declared. `RENDERER_PLUGINS`
|
|
44
|
+
* puts the same guard on preview support.
|
|
45
|
+
*/
|
|
46
|
+
const CODE_FORMATS: Record<RendererKind, CodeFormat> = {
|
|
47
|
+
react: { label: 'React (TSX)', language: 'tsx' },
|
|
48
|
+
handlebars: { label: 'Handlebars', language: 'handlebars' },
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Formats that are not a renderer name: the synthetic `html` that the string and empty-data
|
|
53
|
+
* branches set, and the language names that older artifacts carry in `format`.
|
|
54
|
+
*/
|
|
55
|
+
const FORMAT_ALIASES: Record<string, CodeFormat> = {
|
|
56
|
+
html: { label: 'HTML', language: 'html' },
|
|
57
|
+
tsx: CODE_FORMATS.react,
|
|
58
|
+
jsx: { label: 'React (JSX)', language: 'jsx' },
|
|
59
|
+
ts: { label: 'TypeScript', language: 'typescript' },
|
|
60
|
+
typescript: { label: 'TypeScript', language: 'typescript' },
|
|
61
|
+
js: { label: 'JavaScript', language: 'javascript' },
|
|
62
|
+
javascript: { label: 'JavaScript', language: 'javascript' },
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const formatFor = (format?: string): CodeFormat => {
|
|
66
|
+
const key = format?.toLowerCase() ?? '';
|
|
67
|
+
// Legacy default: an unrecognized format reads as plain code and highlights as Handlebars.
|
|
68
|
+
return CODE_FORMATS[key as RendererKind] ?? FORMAT_ALIASES[key] ?? { label: 'Code', language: 'handlebars' };
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
type CodeView = { label?: string; language?: string };
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The code views, in the order they are offered. An allowlist rather than a denylist of metadata:
|
|
75
|
+
* a field added to the record later cannot become a view by default. An absent `label` or
|
|
76
|
+
* `language` is computed: from the item's format for `code`, from the `type` prop for `html`, and
|
|
77
|
+
* by JSX detection for `js`.
|
|
78
|
+
*/
|
|
79
|
+
const CODE_VIEWS: Record<string, CodeView> = {
|
|
80
|
+
usage: { label: 'Usage', language: 'tsx' },
|
|
81
|
+
code: {},
|
|
82
|
+
html: { label: 'HTML' },
|
|
83
|
+
css: { label: 'CSS', language: 'css' },
|
|
84
|
+
js: { label: 'JavaScript' },
|
|
85
|
+
sass: { label: 'SASS', language: 'scss' },
|
|
86
|
+
sharedStyles: { label: 'Shared CSS', language: 'css' },
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/** `usage` is derived from the previews, not read off the record, so it is offered separately. */
|
|
90
|
+
const RECORD_VIEWS = Object.keys(CODE_VIEWS).filter((key) => key !== 'usage');
|
|
91
|
+
|
|
37
92
|
/**
|
|
38
93
|
* Highlight code for preview elements
|
|
39
94
|
* @param param0
|
|
@@ -88,14 +143,7 @@ export const CodeHighlight: React.FC<{
|
|
|
88
143
|
}
|
|
89
144
|
if (!type) type = 'html';
|
|
90
145
|
|
|
91
|
-
const
|
|
92
|
-
'id', 'preview', 'image', 'categories', 'title', 'format',
|
|
93
|
-
'description', 'type', 'group', 'tags', 'previews', 'properties',
|
|
94
|
-
'should_do', 'should_not_do', 'figma', 'usage',
|
|
95
|
-
];
|
|
96
|
-
|
|
97
|
-
const states = Object.keys(data)
|
|
98
|
-
.filter((key) => !metadataKeys.includes(key) && !!(data as Record<string, any>)[key]);
|
|
146
|
+
const states = RECORD_VIEWS.filter((key) => !!(data as Record<string, any>)[key]);
|
|
99
147
|
const hasPerPreviewUsage =
|
|
100
148
|
typeof data === 'object' &&
|
|
101
149
|
!!data.previews &&
|
|
@@ -116,35 +164,11 @@ export const CodeHighlight: React.FC<{
|
|
|
116
164
|
theme['pre[class*="language-"]'].maxHeight = height ?? '450px';
|
|
117
165
|
theme['pre[class*="language-"]'].margin = '0';
|
|
118
166
|
|
|
119
|
-
const labels: Record<string, string> = {
|
|
120
|
-
code: 'Code',
|
|
121
|
-
handlebars: 'Handlebars',
|
|
122
|
-
hbs: 'Handlebars',
|
|
123
|
-
html: 'HTML',
|
|
124
|
-
css: 'CSS',
|
|
125
|
-
js: 'JavaScript',
|
|
126
|
-
javascript: 'JavaScript',
|
|
127
|
-
jsx: 'JSX',
|
|
128
|
-
tsx: 'TSX',
|
|
129
|
-
typescript: 'TypeScript',
|
|
130
|
-
ts: 'TypeScript',
|
|
131
|
-
sass: 'SASS',
|
|
132
|
-
scss: 'SCSS',
|
|
133
|
-
sharedStyles: 'Shared CSS',
|
|
134
|
-
usage: 'Usage',
|
|
135
|
-
json: 'JSON',
|
|
136
|
-
markdown: 'Markdown',
|
|
137
|
-
};
|
|
138
|
-
|
|
139
167
|
const getLabel = (state: string): string => {
|
|
140
168
|
if (state === 'code' && typeof data === 'object') {
|
|
141
|
-
|
|
142
|
-
if (format === 'react' || format === 'tsx') return 'React (TSX)';
|
|
143
|
-
if (format === 'jsx') return 'React (JSX)';
|
|
144
|
-
if (format === 'typescript' || format === 'ts') return 'TypeScript';
|
|
145
|
-
if (format === 'javascript' || format === 'js') return 'JavaScript';
|
|
169
|
+
return formatFor(data.format).label;
|
|
146
170
|
}
|
|
147
|
-
return
|
|
171
|
+
return CODE_VIEWS[state]?.label ?? state.charAt(0).toUpperCase() + state.slice(1);
|
|
148
172
|
};
|
|
149
173
|
|
|
150
174
|
/**
|
|
@@ -155,39 +179,22 @@ export const CodeHighlight: React.FC<{
|
|
|
155
179
|
return activeState === 'html' ? type : activeState;
|
|
156
180
|
}
|
|
157
181
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
return 'handlebars';
|
|
182
|
+
if (activeState === 'code') {
|
|
183
|
+
return formatFor(data.format).language;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// The `type` prop names the markup language of the rendered preview.
|
|
187
|
+
if (activeState === 'html') {
|
|
188
|
+
return type || 'html';
|
|
166
189
|
}
|
|
167
190
|
|
|
168
|
-
//
|
|
191
|
+
// A component's compiled JS can be plain JavaScript or still hold JSX.
|
|
169
192
|
if (activeState === 'js') {
|
|
170
|
-
// Check if the JS code contains JSX syntax (common patterns)
|
|
171
193
|
const jsCode = 'js' in data ? data.js : '';
|
|
172
|
-
|
|
173
|
-
return 'jsx';
|
|
174
|
-
}
|
|
175
|
-
return 'javascript';
|
|
194
|
+
return typeof jsCode === 'string' && hasJsxSyntax(jsCode) ? 'jsx' : 'javascript';
|
|
176
195
|
}
|
|
177
196
|
|
|
178
|
-
|
|
179
|
-
const languageMap: Record<string, string> = {
|
|
180
|
-
html: type || 'html',
|
|
181
|
-
css: 'css',
|
|
182
|
-
sass: 'scss',
|
|
183
|
-
sharedStyles: 'css',
|
|
184
|
-
usage: 'tsx',
|
|
185
|
-
json: 'json',
|
|
186
|
-
handlebars: 'handlebars',
|
|
187
|
-
hbs: 'handlebars',
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
return languageMap[activeState] || activeState;
|
|
197
|
+
return CODE_VIEWS[activeState]?.language ?? activeState;
|
|
191
198
|
};
|
|
192
199
|
|
|
193
200
|
/**
|
|
@@ -285,15 +292,11 @@ export const CodeHighlight: React.FC<{
|
|
|
285
292
|
<SelectValue placeholder="Code View" />
|
|
286
293
|
</SelectTrigger>
|
|
287
294
|
<SelectContent>
|
|
288
|
-
{selectableStates
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
{getLabel(state)}
|
|
294
|
-
</SelectItem>
|
|
295
|
-
);
|
|
296
|
-
})}
|
|
295
|
+
{selectableStates.map((state) => (
|
|
296
|
+
<SelectItem key={state} value={state}>
|
|
297
|
+
{getLabel(state)}
|
|
298
|
+
</SelectItem>
|
|
299
|
+
))}
|
|
297
300
|
</SelectContent>
|
|
298
301
|
</Select>
|
|
299
302
|
)}
|
|
@@ -70,38 +70,36 @@ function extractText(node: any): string {
|
|
|
70
70
|
|
|
71
71
|
const Headings = (element: any) => {
|
|
72
72
|
const { children, node } = element;
|
|
73
|
-
if (children
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
} else {
|
|
104
|
-
return <h1>children</h1>;
|
|
73
|
+
if (React.Children.count(children) === 0) return <></>;
|
|
74
|
+
|
|
75
|
+
const type = node.tagName || 'h6';
|
|
76
|
+
|
|
77
|
+
let anchor = extractText(children).toLowerCase();
|
|
78
|
+
anchor = anchor.replace(/[^a-zA-Z0-9 ]/g, '');
|
|
79
|
+
anchor = anchor.replace(/ /g, '-');
|
|
80
|
+
|
|
81
|
+
const container = (children: React.ReactNode): React.ReactNode => (
|
|
82
|
+
<>
|
|
83
|
+
{children}
|
|
84
|
+
<a id={anchor} href={`#${anchor}`} className="doc-link"></a>
|
|
85
|
+
</>
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
switch (type) {
|
|
89
|
+
case 'h1':
|
|
90
|
+
return <h1 className="text-2xl font-bold">{container(children)}</h1>;
|
|
91
|
+
case 'h2':
|
|
92
|
+
return <h2 className="text-xl font-bold">{container(children)}</h2>;
|
|
93
|
+
case 'h3':
|
|
94
|
+
return <h3 className="text-lg font-bold">{container(children)}</h3>;
|
|
95
|
+
case 'h4':
|
|
96
|
+
return <h4 className="text-base font-bold">{container(children)}</h4>;
|
|
97
|
+
case 'h5':
|
|
98
|
+
return <h5 className="text-sm font-bold">{container(children)}</h5>;
|
|
99
|
+
case 'h6':
|
|
100
|
+
return <h6 className="text-xs font-bold">{container(children)}</h6>;
|
|
101
|
+
default:
|
|
102
|
+
return <h6 className="text-xs font-bold">{container(children)}</h6>;
|
|
105
103
|
}
|
|
106
104
|
};
|
|
107
105
|
|