blume 2.0.1 → 2.0.3
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/CHANGELOG.md +147 -0
- package/dist/cli/{chunk-qwsrynx5.js → chunk-1d7ve1dm.js} +38 -19
- package/dist/cli/{chunk-qwsrynx5.js.map → chunk-1d7ve1dm.js.map} +4 -4
- package/dist/cli/{chunk-s6jhgk0q.js → chunk-2eytanqx.js} +2 -2
- package/dist/cli/{chunk-kdp5q7ke.js → chunk-2hsdwb9n.js} +18 -19
- package/dist/cli/{chunk-kdp5q7ke.js.map → chunk-2hsdwb9n.js.map} +2 -2
- package/dist/cli/{chunk-hdpx1tax.js → chunk-2z928egk.js} +5 -5
- package/dist/cli/{chunk-jwyddg7y.js → chunk-35d4wj9f.js} +30 -24
- package/dist/cli/chunk-35d4wj9f.js.map +15 -0
- package/dist/cli/{chunk-ah61y8py.js → chunk-364znk6q.js} +2 -2
- package/dist/cli/{chunk-jts8mvcz.js → chunk-3em5wd2y.js} +25 -6
- package/dist/cli/{chunk-jts8mvcz.js.map → chunk-3em5wd2y.js.map} +3 -3
- package/dist/cli/{chunk-s1p84fyh.js → chunk-5f86nr5m.js} +63 -22
- package/dist/cli/chunk-5f86nr5m.js.map +11 -0
- package/dist/cli/{chunk-2hn4b8z7.js → chunk-5m5nmvyq.js} +170 -76
- package/dist/cli/chunk-5m5nmvyq.js.map +13 -0
- package/dist/cli/{chunk-epjnccmv.js → chunk-5xvm6tfj.js} +18 -15
- package/dist/cli/chunk-5xvm6tfj.js.map +10 -0
- package/dist/cli/{chunk-fz5wtpmh.js → chunk-6dsbexzp.js} +18 -15
- package/dist/cli/chunk-6dsbexzp.js.map +10 -0
- package/dist/cli/{chunk-vtk4a6dg.js → chunk-8ktnccpt.js} +1 -1
- package/dist/cli/{chunk-6hsn950k.js → chunk-9t7a85s3.js} +178 -48
- package/dist/cli/chunk-9t7a85s3.js.map +10 -0
- package/dist/cli/{chunk-fxypxtvm.js → chunk-a58773jm.js} +2 -2
- package/dist/cli/{chunk-mb2919y2.js → chunk-acanzt5p.js} +17 -6
- package/dist/cli/chunk-acanzt5p.js.map +10 -0
- package/dist/cli/{chunk-27g6wdth.js → chunk-akbpwfxc.js} +90 -26
- package/dist/cli/chunk-akbpwfxc.js.map +10 -0
- package/dist/cli/{chunk-wm7js3j9.js → chunk-b07cmahc.js} +2 -2
- package/dist/cli/{chunk-wgm7m9qk.js → chunk-c8chx29p.js} +179 -51
- package/dist/cli/chunk-c8chx29p.js.map +36 -0
- package/dist/cli/{chunk-qs4q5p4e.js → chunk-crgn1q09.js} +32 -14
- package/dist/cli/chunk-crgn1q09.js.map +10 -0
- package/dist/cli/chunk-e04dxsz1.js +39 -0
- package/dist/cli/chunk-e04dxsz1.js.map +10 -0
- package/dist/cli/{chunk-yt5n7ppj.js → chunk-ey84smr6.js} +17 -7
- package/dist/cli/chunk-ey84smr6.js.map +10 -0
- package/dist/cli/{chunk-f2z5v128.js → chunk-g4hq16wv.js} +14 -15
- package/dist/cli/{chunk-f2z5v128.js.map → chunk-g4hq16wv.js.map} +2 -2
- package/dist/cli/{chunk-fa25z98p.js → chunk-ga0pf4aj.js} +9 -8
- package/dist/cli/chunk-ga0pf4aj.js.map +11 -0
- package/dist/cli/{chunk-kpf8rrjc.js → chunk-hm3vjy5s.js} +109 -58
- package/dist/cli/chunk-hm3vjy5s.js.map +19 -0
- package/dist/cli/{chunk-fs23ddbb.js → chunk-j85vccga.js} +625 -750
- package/dist/cli/chunk-j85vccga.js.map +36 -0
- package/dist/cli/{chunk-ch6g3ar0.js → chunk-p3v96n38.js} +6 -6
- package/dist/cli/{chunk-ch6g3ar0.js.map → chunk-p3v96n38.js.map} +3 -3
- package/dist/cli/{chunk-q5163e60.js → chunk-p73c0m7w.js} +21 -19
- package/dist/cli/chunk-p73c0m7w.js.map +11 -0
- package/dist/cli/{chunk-dh8cwk36.js → chunk-pehfxfta.js} +24 -9
- package/dist/cli/chunk-pehfxfta.js.map +10 -0
- package/dist/cli/{chunk-qkqwkpte.js → chunk-pv29h0wf.js} +3688 -1313
- package/dist/cli/chunk-pv29h0wf.js.map +190 -0
- package/dist/cli/{chunk-6vm74dry.js → chunk-q58y5e6a.js} +10 -10
- package/dist/cli/{chunk-6vm74dry.js.map → chunk-q58y5e6a.js.map} +3 -3
- package/dist/cli/{chunk-zxcczpyx.js → chunk-r20tn01b.js} +1 -1
- package/dist/cli/{chunk-m3vmjgmq.js → chunk-r9rcc4w7.js} +16 -8
- package/dist/cli/chunk-r9rcc4w7.js.map +10 -0
- package/dist/cli/{chunk-5shv93fd.js → chunk-tkacnehg.js} +2 -2
- package/dist/cli/{chunk-zxh4d9vy.js → chunk-tzmab476.js} +4 -4
- package/dist/cli/{chunk-yw7dm696.js → chunk-vg9r4eb9.js} +24 -11
- package/dist/cli/chunk-vg9r4eb9.js.map +14 -0
- package/dist/cli/{chunk-79jhk4py.js → chunk-wrr3j9w9.js} +260 -132
- package/dist/cli/chunk-wrr3j9w9.js.map +35 -0
- package/dist/cli/{chunk-6crbhc3x.js → chunk-yfyb25rh.js} +54 -27
- package/dist/cli/chunk-yfyb25rh.js.map +14 -0
- package/dist/cli/index.js +162 -35
- package/dist/cli/index.js.map +4 -4
- package/dist/types/ai/agent-surface.d.ts +32 -0
- package/dist/types/ai/api-catalog.d.ts +7 -1
- package/dist/types/ai/ask-context.d.ts +7 -0
- package/dist/types/ai/component-markdown.d.ts +4 -4
- package/dist/types/ai/link-headers.d.ts +8 -1
- package/dist/types/ai/openapi-components.d.ts +5 -2
- package/dist/types/ai/relative-links.d.ts +11 -4
- package/dist/types/ai/skills.d.ts +4 -1
- package/dist/types/ai/static-expression.d.ts +28 -0
- package/dist/types/ai/tar.d.ts +1 -3
- package/dist/types/analytics/databuddy.d.ts +43 -0
- package/dist/types/analytics/index.d.ts +4 -0
- package/dist/types/analytics/one-dollar-stats.d.ts +48 -0
- package/dist/types/analytics/schema.d.ts +28 -0
- package/dist/types/astro/integration.d.ts +3 -2
- package/dist/types/cli/env.d.ts +5 -0
- package/dist/types/cli/init/scaffold.d.ts +19 -3
- package/dist/types/cli/init/starter-spec.d.ts +11 -0
- package/dist/types/core/base-path.d.ts +24 -1
- package/dist/types/core/config-input.d.ts +13 -11
- package/dist/types/core/config.d.ts +2 -2
- package/dist/types/core/directive-diagnostics.d.ts +12 -0
- package/dist/types/core/graph.d.ts +2 -0
- package/dist/types/core/heading-markers.d.ts +5 -7
- package/dist/types/core/i18n-ui.d.ts +31 -0
- package/dist/types/core/i18n.d.ts +9 -1
- package/dist/types/core/last-modified.d.ts +10 -0
- package/dist/types/core/links.d.ts +3 -1
- package/dist/types/core/load-module.d.ts +10 -0
- package/dist/types/core/locale-links.d.ts +12 -2
- package/dist/types/core/meta.d.ts +13 -1
- package/dist/types/core/nav-diagnostics.d.ts +10 -0
- package/dist/types/core/navigation.d.ts +38 -0
- package/dist/types/core/ordering-prefix.d.ts +4 -0
- package/dist/types/core/safe-links.d.ts +3 -1
- package/dist/types/core/schema.d.ts +59 -13
- package/dist/types/core/sources/github-releases.d.ts +5 -0
- package/dist/types/core/sources/lower.d.ts +38 -13
- package/dist/types/core/sources/normalize.d.ts +23 -2
- package/dist/types/core/sources/remote.d.ts +11 -1
- package/dist/types/core/sources/resolve.d.ts +12 -0
- package/dist/types/core/sources/types.d.ts +31 -0
- package/dist/types/core/sources/watch.d.ts +12 -5
- package/dist/types/core/standard-schema.d.ts +5 -0
- package/dist/types/core/types.d.ts +9 -0
- package/dist/types/deploy/adapters/node.d.ts +5 -2
- package/dist/types/deploy/adapters/types.d.ts +7 -0
- package/dist/types/deploy/artifacts.d.ts +6 -4
- package/dist/types/deploy/cloudflare-negotiation.d.ts +3 -2
- package/dist/types/deploy/headers.d.ts +36 -7
- package/dist/types/deploy/node-headers.d.ts +43 -8
- package/dist/types/deploy/platforms/netlify.d.ts +27 -2
- package/dist/types/deploy/platforms/node.d.ts +6 -5
- package/dist/types/deploy/platforms/types.d.ts +15 -0
- package/dist/types/deploy/platforms/vercel.d.ts +3 -2
- package/dist/types/deploy/redirects.d.ts +31 -15
- package/dist/types/deploy/vercel-negotiation.d.ts +3 -2
- package/dist/types/markdown/directives.d.ts +62 -0
- package/dist/types/markdown/features.d.ts +21 -0
- package/dist/types/markdown/mdast.d.ts +63 -0
- package/dist/types/openapi/asyncapi.d.ts +4 -2
- package/dist/types/openapi/model.d.ts +20 -6
- package/dist/types/search/sync/algolia.d.ts +3 -1
- package/docs/01-quickstart.mdx +3 -2
- package/docs/02-deployment.mdx +20 -9
- package/docs/08-faq.mdx +10 -3
- package/docs/advanced/changelog.mdx +1 -1
- package/docs/advanced/custom-pages.mdx +7 -5
- package/docs/cli/audit.mdx +19 -3
- package/docs/cli/doctor.mdx +2 -2
- package/docs/cli/evals.mdx +4 -4
- package/docs/cli/index.mdx +4 -1
- package/docs/cli/translate.mdx +4 -4
- package/docs/cli/version.mdx +1 -1
- package/docs/configuration/analytics.mdx +42 -2
- package/docs/configuration/assistant.mdx +1 -1
- package/docs/configuration/customization.mdx +6 -3
- package/docs/configuration/index.mdx +5 -3
- package/docs/configuration/search.mdx +2 -2
- package/docs/content/components.mdx +2 -2
- package/docs/content/frontmatter.mdx +5 -1
- package/docs/content/i18n.mdx +3 -1
- package/docs/content/index.mdx +8 -4
- package/docs/content/islands.mdx +1 -1
- package/docs/content/meta.mdx +7 -3
- package/docs/content/navigation.mdx +29 -4
- package/docs/content/sources.mdx +18 -16
- package/docs/content/syntax.mdx +14 -0
- package/docs/content/versioning.mdx +2 -1
- package/docs/discoverability/agent-discovery.mdx +22 -8
- package/docs/discoverability/index.mdx +4 -3
- package/docs/discoverability/llms-txt.mdx +2 -5
- package/docs/discoverability/markdown.mdx +6 -4
- package/docs/discoverability/mcp.mdx +4 -0
- package/docs/discoverability/metadata.mdx +3 -2
- package/docs/discoverability/open-graph.mdx +8 -4
- package/docs/discoverability/rss.mdx +4 -2
- package/docs/references/asyncapi.mdx +2 -2
- package/docs/references/graphql.mdx +2 -2
- package/docs/references/openapi.mdx +6 -4
- package/package.json +1 -1
- package/skills/blume-migrate/SKILL.md +6 -6
- package/skills/blume-migrate/references/docusaurus.md +6 -6
- package/skills/blume-migrate/references/fumadocs.md +1 -1
- package/skills/blume-migrate/references/mintlify.md +3 -3
- package/skills/blume-migrate/references/monorepo.md +1 -1
- package/skills/blume-migrate/references/nextra.md +2 -2
- package/skills/blume-migrate/references/starlight.md +5 -5
- package/skills/blume-migrate/scripts/mintlify-codemod.mjs +9 -4
- package/skills/blume-update-docs/references/audit-checklist.md +1 -1
- package/src/ai/agent-readability.ts +2 -2
- package/src/ai/agent-surface.ts +56 -0
- package/src/ai/ai-catalog.ts +6 -2
- package/src/ai/api/handlers.ts +2 -2
- package/src/ai/api/spec.ts +17 -4
- package/src/ai/api-catalog.ts +13 -3
- package/src/ai/ask-context.ts +14 -2
- package/src/ai/ask-data.ts +26 -12
- package/src/ai/changelog-markdown.ts +2 -2
- package/src/ai/component-markdown.ts +43 -37
- package/src/ai/link-headers.ts +22 -8
- package/src/ai/llms.ts +22 -10
- package/src/ai/markdown.ts +23 -11
- package/src/ai/mcp/discovery.ts +2 -2
- package/src/ai/mcp/query.ts +2 -2
- package/src/ai/mcp/server.ts +80 -9
- package/src/ai/openapi-components.ts +22 -6
- package/src/ai/relative-links.ts +99 -15
- package/src/ai/serializers.ts +2 -1
- package/src/ai/skills.ts +14 -1
- package/src/ai/static-expression.ts +416 -0
- package/src/ai/tar.ts +139 -12
- package/src/ai/visibility.ts +45 -14
- package/src/analytics/databuddy.ts +67 -0
- package/src/analytics/head.ts +8 -0
- package/src/analytics/index.ts +7 -0
- package/src/analytics/one-dollar-stats.ts +86 -0
- package/src/analytics/posthog.ts +21 -3
- package/src/analytics/schema.ts +4 -0
- package/src/astro/generate.ts +72 -28
- package/src/astro/include-hmr.ts +31 -12
- package/src/astro/include-refresh.ts +19 -8
- package/src/astro/integration.ts +108 -14
- package/src/astro/runtime-modules.ts +28 -13
- package/src/astro/templates.ts +139 -57
- package/src/audit/catalog.ts +2 -2
- package/src/audit/checks/assets.ts +25 -5
- package/src/audit/checks/content.ts +20 -2
- package/src/audit/checks/i18n.ts +46 -8
- package/src/audit/checks/indexability.ts +39 -19
- package/src/audit/checks/links.ts +22 -1
- package/src/audit/checks/llms.ts +6 -3
- package/src/audit/checks/network.ts +3 -1
- package/src/audit/checks/og-image.ts +10 -0
- package/src/audit/checks/robots.ts +6 -1
- package/src/audit/checks/sitemap.ts +56 -31
- package/src/audit/checks/social.ts +21 -2
- package/src/audit/crawl.ts +88 -15
- package/src/audit/graph.ts +3 -1
- package/src/audit/report.ts +54 -17
- package/src/audit/run.ts +13 -9
- package/src/audit/snapshot.ts +5 -0
- package/src/audit/types.ts +18 -0
- package/src/audit/url.ts +37 -6
- package/src/cli/args.ts +32 -0
- package/src/cli/build-failure.ts +50 -0
- package/src/cli/commands/audit.ts +11 -1
- package/src/cli/commands/build.ts +19 -5
- package/src/cli/commands/check.ts +2 -0
- package/src/cli/commands/doctor.ts +3 -1
- package/src/cli/commands/eval.ts +20 -18
- package/src/cli/commands/init.ts +15 -5
- package/src/cli/commands/preview.ts +15 -0
- package/src/cli/commands/sync.ts +2 -0
- package/src/cli/commands/translate.ts +18 -18
- package/src/cli/commands/upgrade.ts +11 -0
- package/src/cli/commands/validate.ts +3 -1
- package/src/cli/dev-lock.ts +157 -37
- package/src/cli/eject-scripts.ts +32 -7
- package/src/cli/env.ts +12 -1
- package/src/cli/init/scaffold.ts +117 -11
- package/src/cli/init/starter-spec.ts +235 -0
- package/src/cli/report-format.ts +11 -6
- package/src/components/colors.ts +19 -0
- package/src/components/content/AccordionItem.astro +26 -22
- package/src/components/content/Badge.astro +7 -12
- package/src/components/content/Card.astro +2 -2
- package/src/components/content/Component.astro +11 -5
- package/src/components/content/Expandable.astro +5 -1
- package/src/components/content/Frame.astro +2 -7
- package/src/components/content/GithubInfo.astro +12 -2
- package/src/components/content/Prompt.astro +2 -7
- package/src/components/content/Tab.astro +0 -1
- package/src/components/content/Tabs.astro +58 -5
- package/src/components/content/Tile.astro +1 -1
- package/src/components/content/Tooltip.astro +69 -7
- package/src/components/content/Tree.astro +7 -2
- package/src/components/content/TypeTable.astro +10 -5
- package/src/components/content/Update.astro +8 -2
- package/src/components/content/auto-type-table.ts +4 -1
- package/src/components/content/badge-color.ts +20 -0
- package/src/components/content/base-href.ts +14 -22
- package/src/components/content/inline-markdown.ts +27 -7
- package/src/components/copy-feedback.ts +35 -8
- package/src/components/islands/assistant.tsx +37 -6
- package/src/components/islands/base-path.ts +47 -10
- package/src/components/islands/hooks.ts +42 -21
- package/src/components/islands/webmcp.ts +16 -10
- package/src/components/layout/Banner.astro +23 -4
- package/src/components/layout/Breadcrumbs.astro +5 -2
- package/src/components/layout/DiscoveryLinks.astro +9 -5
- package/src/components/layout/Header.astro +23 -10
- package/src/components/layout/LanguageSwitcher.astro +2 -2
- package/src/components/layout/Logo.astro +5 -0
- package/src/components/layout/NavSelector.astro +8 -3
- package/src/components/layout/NavTabMenu.astro +133 -0
- package/src/components/layout/NavTree.astro +31 -12
- package/src/components/layout/NavTreeCache.astro +5 -2
- package/src/components/layout/NavTreeScript.astro +45 -5
- package/src/components/layout/PageActions.astro +4 -3
- package/src/components/layout/PageLayout.astro +28 -13
- package/src/components/layout/Pagination.astro +3 -3
- package/src/components/layout/ReferenceLayout.astro +4 -1
- package/src/components/layout/RootLayout.astro +25 -12
- package/src/components/layout/Search.astro +38 -14
- package/src/components/layout/VersionBanner.astro +2 -2
- package/src/components/layout/analytics-client.ts +14 -0
- package/src/components/layout/toc-active.ts +41 -0
- package/src/components/layout/toc-element.ts +8 -14
- package/src/components/openapi/ApiTagOperations.astro +2 -2
- package/src/components/openapi/AsyncApiOperation.astro +7 -4
- package/src/components/openapi/GraphqlChip.astro +2 -2
- package/src/components/openapi/GraphqlType.astro +11 -3
- package/src/components/openapi/MessageComposer.astro +1 -1
- package/src/components/openapi/Operation.astro +23 -5
- package/src/components/openapi/PanelTabs.astro +4 -1
- package/src/components/openapi/Playground.astro +8 -2
- package/src/components/openapi/RequestPanel.astro +13 -6
- package/src/components/openapi/SchemaProperty.astro +11 -33
- package/src/components/openapi/SchemaTable.astro +34 -52
- package/src/components/openapi/async.ts +38 -6
- package/src/components/openapi/helpers.ts +100 -12
- package/src/components/openapi/message-composer.ts +14 -1
- package/src/components/openapi/message-model.ts +12 -2
- package/src/components/openapi/message.ts +21 -3
- package/src/components/openapi/operation-model.ts +119 -17
- package/src/components/openapi/panel.ts +31 -5
- package/src/components/openapi/param-style.ts +181 -0
- package/src/components/openapi/playground-client.ts +110 -23
- package/src/components/openapi/playground-schema.ts +25 -6
- package/src/components/openapi/request.ts +192 -26
- package/src/components/openapi/schema-tree.ts +209 -0
- package/src/components/openapi/snippets.ts +113 -19
- package/src/components/openapi/validate-json.ts +1 -1
- package/src/components/openapi/ws-client.ts +18 -2
- package/src/core/base-path.ts +69 -8
- package/src/core/config-input.ts +13 -11
- package/src/core/config.ts +18 -4
- package/src/core/diagnostics.ts +219 -30
- package/src/core/directive-diagnostics.ts +99 -0
- package/src/core/frontmatter.ts +21 -18
- package/src/core/graph.ts +120 -11
- package/src/core/heading-markers.ts +5 -18
- package/src/core/i18n-ui.ts +39 -2
- package/src/core/i18n.ts +44 -5
- package/src/core/last-modified.ts +25 -3
- package/src/core/links.ts +7 -4
- package/src/core/load-module.ts +20 -0
- package/src/core/locale-links.ts +22 -18
- package/src/core/manifest.ts +3 -2
- package/src/core/meta.ts +89 -12
- package/src/core/nav-diagnostics.ts +56 -1
- package/src/core/navigation.ts +272 -83
- package/src/core/ordering-prefix.ts +27 -0
- package/src/core/project-graph.ts +50 -6
- package/src/core/safe-href.ts +53 -1
- package/src/core/safe-links.ts +11 -2
- package/src/core/schema.ts +94 -18
- package/src/core/sources/assets.ts +83 -41
- package/src/core/sources/contentful-rich-text.ts +28 -20
- package/src/core/sources/contentful.ts +25 -12
- package/src/core/sources/filesystem.ts +25 -3
- package/src/core/sources/github-releases.ts +131 -11
- package/src/core/sources/lexical.ts +30 -20
- package/src/core/sources/lower.ts +276 -56
- package/src/core/sources/mdx-remote.ts +52 -16
- package/src/core/sources/normalize.ts +456 -119
- package/src/core/sources/notion.ts +77 -34
- package/src/core/sources/obsidian.ts +40 -9
- package/src/core/sources/payload.ts +1 -0
- package/src/core/sources/portable-text.ts +85 -49
- package/src/core/sources/remote.ts +18 -2
- package/src/core/sources/resolve.ts +52 -33
- package/src/core/sources/sanity.ts +1 -0
- package/src/core/sources/strapi-blocks.ts +28 -19
- package/src/core/sources/strapi.ts +1 -0
- package/src/core/sources/types.ts +31 -0
- package/src/core/sources/watch.ts +20 -7
- package/src/core/standard-schema.ts +10 -6
- package/src/core/types.ts +9 -0
- package/src/core/ui-packs/ar.ts +13 -0
- package/src/core/ui-packs/bg.ts +13 -0
- package/src/core/ui-packs/bn.ts +13 -0
- package/src/core/ui-packs/ca.ts +13 -0
- package/src/core/ui-packs/cs.ts +13 -0
- package/src/core/ui-packs/da.ts +13 -0
- package/src/core/ui-packs/de.ts +13 -0
- package/src/core/ui-packs/el.ts +13 -0
- package/src/core/ui-packs/es.ts +13 -0
- package/src/core/ui-packs/fa.ts +13 -0
- package/src/core/ui-packs/fi.ts +13 -0
- package/src/core/ui-packs/fr.ts +13 -0
- package/src/core/ui-packs/he.ts +13 -0
- package/src/core/ui-packs/hi.ts +13 -0
- package/src/core/ui-packs/hr.ts +13 -0
- package/src/core/ui-packs/hu.ts +13 -0
- package/src/core/ui-packs/id.ts +13 -0
- package/src/core/ui-packs/it.ts +13 -0
- package/src/core/ui-packs/ja.ts +13 -0
- package/src/core/ui-packs/ko.ts +13 -0
- package/src/core/ui-packs/nl.ts +13 -0
- package/src/core/ui-packs/no.ts +13 -0
- package/src/core/ui-packs/pl.ts +13 -0
- package/src/core/ui-packs/pt-br.ts +13 -0
- package/src/core/ui-packs/pt.ts +13 -0
- package/src/core/ui-packs/ro.ts +13 -0
- package/src/core/ui-packs/ru.ts +13 -0
- package/src/core/ui-packs/sk.ts +13 -0
- package/src/core/ui-packs/sr.ts +13 -0
- package/src/core/ui-packs/sv.ts +13 -0
- package/src/core/ui-packs/th.ts +13 -0
- package/src/core/ui-packs/tr.ts +13 -0
- package/src/core/ui-packs/uk.ts +13 -0
- package/src/core/ui-packs/vi.ts +13 -0
- package/src/core/ui-packs/zh-tw.ts +13 -0
- package/src/core/ui-packs/zh.ts +13 -0
- package/src/core/version-cut.ts +69 -17
- package/src/core/versions.ts +4 -1
- package/src/deploy/adapters/node.ts +5 -2
- package/src/deploy/adapters/registry.ts +2 -1
- package/src/deploy/adapters/types.ts +13 -1
- package/src/deploy/artifacts.ts +52 -11
- package/src/deploy/cloudflare-negotiation.ts +27 -16
- package/src/deploy/headers.ts +75 -55
- package/src/deploy/node-headers.ts +148 -27
- package/src/deploy/platforms/cloudflare.ts +13 -3
- package/src/deploy/platforms/netlify.ts +83 -5
- package/src/deploy/platforms/node.ts +8 -5
- package/src/deploy/platforms/static.ts +2 -0
- package/src/deploy/platforms/types.ts +15 -0
- package/src/deploy/platforms/vercel.ts +10 -3
- package/src/deploy/redirects.ts +68 -21
- package/src/deploy/robots.ts +2 -2
- package/src/deploy/rss.ts +4 -3
- package/src/deploy/sitemap.ts +7 -5
- package/src/deploy/vercel-negotiation.ts +35 -3
- package/src/eval/agents.ts +10 -2
- package/src/eval/run.ts +25 -0
- package/src/markdown/base-links.ts +74 -29
- package/src/markdown/directives.ts +242 -36
- package/src/markdown/features.ts +17 -0
- package/src/markdown/index.ts +13 -9
- package/src/markdown/mdast.ts +5 -2
- package/src/markdown/relative-links.ts +15 -27
- package/src/markdown/route-snapshot.ts +37 -0
- package/src/og/card.ts +149 -9
- package/src/og/derive.ts +156 -5
- package/src/og/index.ts +1 -0
- package/src/openapi/asyncapi.ts +4 -2
- package/src/openapi/graphql-build.ts +28 -2
- package/src/openapi/model.ts +99 -27
- package/src/openapi/proxy.ts +63 -10
- package/src/openapi/render-mdx.ts +51 -3
- package/src/registry/eject.ts +297 -43
- package/src/search/adapters/version-scope.ts +30 -0
- package/src/search/documents.ts +89 -27
- package/src/search/popular.ts +2 -1
- package/src/search/sync/algolia.ts +36 -2
- package/src/seo/jsonld.ts +7 -3
- package/src/sources/registry.ts +5 -0
- package/src/theme/entry.ts +11 -4
- package/src/translate/agents.ts +6 -1
- package/src/translate/ledger.ts +26 -3
- package/src/translate/meta.ts +76 -24
- package/src/translate/run.ts +14 -8
- package/src/translate/validate.ts +14 -2
- package/src/translate/work-list.ts +91 -19
- package/src/upgrade/upgrade.ts +36 -4
- package/dist/cli/chunk-27g6wdth.js.map +0 -10
- package/dist/cli/chunk-2hn4b8z7.js.map +0 -12
- package/dist/cli/chunk-6crbhc3x.js.map +0 -14
- package/dist/cli/chunk-6hsn950k.js.map +0 -10
- package/dist/cli/chunk-79jhk4py.js.map +0 -35
- package/dist/cli/chunk-82bbrxdn.js +0 -51
- package/dist/cli/chunk-82bbrxdn.js.map +0 -10
- package/dist/cli/chunk-abh8yjkn.js +0 -31
- package/dist/cli/chunk-abh8yjkn.js.map +0 -10
- package/dist/cli/chunk-ce574jw2.js +0 -23
- package/dist/cli/chunk-ce574jw2.js.map +0 -10
- package/dist/cli/chunk-dh8cwk36.js.map +0 -10
- package/dist/cli/chunk-epjnccmv.js.map +0 -10
- package/dist/cli/chunk-fa25z98p.js.map +0 -11
- package/dist/cli/chunk-fs23ddbb.js.map +0 -35
- package/dist/cli/chunk-fz5wtpmh.js.map +0 -10
- package/dist/cli/chunk-jwyddg7y.js.map +0 -15
- package/dist/cli/chunk-kpf8rrjc.js.map +0 -19
- package/dist/cli/chunk-m3vmjgmq.js.map +0 -10
- package/dist/cli/chunk-mb2919y2.js.map +0 -10
- package/dist/cli/chunk-q5163e60.js.map +0 -11
- package/dist/cli/chunk-qkqwkpte.js.map +0 -182
- package/dist/cli/chunk-qs4q5p4e.js.map +0 -10
- package/dist/cli/chunk-s1p84fyh.js.map +0 -10
- package/dist/cli/chunk-wgm7m9qk.js.map +0 -36
- package/dist/cli/chunk-yt5n7ppj.js.map +0 -10
- package/dist/cli/chunk-yw7dm696.js.map +0 -14
- /package/dist/cli/{chunk-s6jhgk0q.js.map → chunk-2eytanqx.js.map} +0 -0
- /package/dist/cli/{chunk-hdpx1tax.js.map → chunk-2z928egk.js.map} +0 -0
- /package/dist/cli/{chunk-ah61y8py.js.map → chunk-364znk6q.js.map} +0 -0
- /package/dist/cli/{chunk-vtk4a6dg.js.map → chunk-8ktnccpt.js.map} +0 -0
- /package/dist/cli/{chunk-fxypxtvm.js.map → chunk-a58773jm.js.map} +0 -0
- /package/dist/cli/{chunk-wm7js3j9.js.map → chunk-b07cmahc.js.map} +0 -0
- /package/dist/cli/{chunk-zxcczpyx.js.map → chunk-r20tn01b.js.map} +0 -0
- /package/dist/cli/{chunk-5shv93fd.js.map → chunk-tkacnehg.js.map} +0 -0
- /package/dist/cli/{chunk-zxh4d9vy.js.map → chunk-tzmab476.js.map} +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
---
|
|
2
|
+
// A header tab with dropdown `items` (`navigation.tabs[].items`). In the
|
|
3
|
+
// header's tab bar (`variant="bar"`) it is the nav selectors' floating
|
|
4
|
+
// `<details>` dropdown: the `<summary>` is the disclosure button (the browser
|
|
5
|
+
// exposes its expanded state), the panel a list of links, and the shared
|
|
6
|
+
// light-dismiss closes it on an outside press, Escape (focus returns to the
|
|
7
|
+
// tab), or focus leaving it. In a navigation drawer (`variant="drawer"`) the
|
|
8
|
+
// same items expand in place under the tab, like a sidebar group, open from
|
|
9
|
+
// the start on the tab's own section. Both are server-rendered and the scripts
|
|
10
|
+
// delegate from `document`, so client-router swaps need no re-init.
|
|
11
|
+
import type { NavTab } from "../../core/types.ts";
|
|
12
|
+
import Icon from "../Icon.astro";
|
|
13
|
+
import { withMountedBase } from "../islands/base-path.ts";
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
tab: NavTab;
|
|
17
|
+
/** The page's route, to mark the item it is on. */
|
|
18
|
+
route: string;
|
|
19
|
+
/** Whether the current route falls under this tab. */
|
|
20
|
+
active: boolean;
|
|
21
|
+
variant: "bar" | "drawer";
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const { tab, route, active, variant } = Astro.props;
|
|
25
|
+
const items = tab.items ?? [];
|
|
26
|
+
// The tab itself is a button, not a page, so its "you are here" state is
|
|
27
|
+
// `aria-current="true"` (current item of a set); an item is the page.
|
|
28
|
+
const tabCurrent = active ? "true" : undefined;
|
|
29
|
+
const itemCurrent = (path: string): "page" | undefined =>
|
|
30
|
+
path === route ? "page" : undefined;
|
|
31
|
+
|
|
32
|
+
const barRowClass =
|
|
33
|
+
"flex w-full items-start gap-2.5 rounded-md px-2 py-1.5 text-start text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=page]:text-foreground";
|
|
34
|
+
const drawerRowClass =
|
|
35
|
+
"flex items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=page]:bg-muted aria-[current=page]:text-foreground";
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
{
|
|
39
|
+
variant === "bar" ? (
|
|
40
|
+
<details class="group relative" data-blume-dropdown>
|
|
41
|
+
<summary
|
|
42
|
+
aria-current={tabCurrent}
|
|
43
|
+
class="inline-flex cursor-pointer list-none items-center gap-1 rounded-full px-3 py-1.5 font-medium text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=true]:text-foreground [&::-webkit-details-marker]:hidden"
|
|
44
|
+
>
|
|
45
|
+
{tab.icon && (
|
|
46
|
+
<Icon class="me-0.5 shrink-0" name={tab.icon} size={14} />
|
|
47
|
+
)}
|
|
48
|
+
{tab.label}
|
|
49
|
+
<Icon
|
|
50
|
+
class="transition-transform group-open:rotate-180"
|
|
51
|
+
name="chevron-down"
|
|
52
|
+
size={14}
|
|
53
|
+
/>
|
|
54
|
+
</summary>
|
|
55
|
+
<div
|
|
56
|
+
class="absolute start-0 z-50 mt-2 min-w-56 max-w-[calc(100vw-1rem)] rounded-blume border border-border bg-background p-1 shadow-xl"
|
|
57
|
+
data-blume-dropdown-panel
|
|
58
|
+
>
|
|
59
|
+
{items.map((item) => (
|
|
60
|
+
<a
|
|
61
|
+
aria-current={itemCurrent(item.path)}
|
|
62
|
+
class={barRowClass}
|
|
63
|
+
href={withMountedBase(item.path)}
|
|
64
|
+
>
|
|
65
|
+
{item.icon && <Icon class="mt-0.5" name={item.icon} size={16} />}
|
|
66
|
+
<span class="flex-1">
|
|
67
|
+
<span class="flex items-center gap-2">
|
|
68
|
+
{item.label}
|
|
69
|
+
{item.tag && (
|
|
70
|
+
<span class="rounded-full bg-muted px-1.5 py-0.5 text-[0.65rem] text-muted-foreground">
|
|
71
|
+
{item.tag}
|
|
72
|
+
</span>
|
|
73
|
+
)}
|
|
74
|
+
</span>
|
|
75
|
+
{item.description && (
|
|
76
|
+
<span class="mt-0.5 block text-muted-foreground text-xs">
|
|
77
|
+
{item.description}
|
|
78
|
+
</span>
|
|
79
|
+
)}
|
|
80
|
+
</span>
|
|
81
|
+
</a>
|
|
82
|
+
))}
|
|
83
|
+
</div>
|
|
84
|
+
</details>
|
|
85
|
+
) : (
|
|
86
|
+
<details class="group" open={active}>
|
|
87
|
+
<summary
|
|
88
|
+
aria-current={tabCurrent}
|
|
89
|
+
class="flex cursor-pointer list-none items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 font-medium text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=true]:text-foreground [&::-webkit-details-marker]:hidden"
|
|
90
|
+
>
|
|
91
|
+
{tab.icon && <Icon class="shrink-0" name={tab.icon} size={14} />}
|
|
92
|
+
<span class="flex-1 truncate">{tab.label}</span>
|
|
93
|
+
<Icon
|
|
94
|
+
class="shrink-0 transition-transform group-open:rotate-180"
|
|
95
|
+
name="chevron-down"
|
|
96
|
+
size={14}
|
|
97
|
+
/>
|
|
98
|
+
</summary>
|
|
99
|
+
<ul class="m-0 ms-2.5 list-none space-y-px border-border border-s p-0 ps-2">
|
|
100
|
+
{items.map((item) => (
|
|
101
|
+
<li>
|
|
102
|
+
<a
|
|
103
|
+
aria-current={itemCurrent(item.path)}
|
|
104
|
+
class={drawerRowClass}
|
|
105
|
+
href={withMountedBase(item.path)}
|
|
106
|
+
>
|
|
107
|
+
{item.icon && (
|
|
108
|
+
<Icon class="shrink-0" name={item.icon} size={14} />
|
|
109
|
+
)}
|
|
110
|
+
<span class="flex-1 truncate">{item.label}</span>
|
|
111
|
+
{item.tag && (
|
|
112
|
+
<span class="shrink-0 rounded-full bg-muted px-1.5 py-0.5 text-[0.65rem] text-muted-foreground">
|
|
113
|
+
{item.tag}
|
|
114
|
+
</span>
|
|
115
|
+
)}
|
|
116
|
+
</a>
|
|
117
|
+
</li>
|
|
118
|
+
))}
|
|
119
|
+
</ul>
|
|
120
|
+
</details>
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
<script>
|
|
125
|
+
import { installDropdownDismiss } from "../dropdown-dismiss.ts";
|
|
126
|
+
import { installDropdownClamp } from "./dropdown-clamp.ts";
|
|
127
|
+
|
|
128
|
+
// Outside-click / Escape / focus-out dismissal and viewport clamping for
|
|
129
|
+
// the header dropdown, shared with the nav selectors. The drawer variant
|
|
130
|
+
// opts into neither: it is an in-place disclosure, not a floating panel.
|
|
131
|
+
installDropdownDismiss();
|
|
132
|
+
installDropdownClamp();
|
|
133
|
+
</script>
|
|
@@ -4,7 +4,7 @@ import type { UIStrings } from "../../core/i18n-ui.ts";
|
|
|
4
4
|
import type { NavNode } from "../../core/types.ts";
|
|
5
5
|
import { methodColor } from "../colors.ts";
|
|
6
6
|
import Icon from "../Icon.astro";
|
|
7
|
-
import { withBase } from "../islands/base-path.ts";
|
|
7
|
+
import { withBase, withMountedBase } from "../islands/base-path.ts";
|
|
8
8
|
import Self from "./NavTree.astro";
|
|
9
9
|
import NavTreeCache from "./NavTreeCache.astro";
|
|
10
10
|
import NavTreeScript from "./NavTreeScript.astro";
|
|
@@ -79,6 +79,19 @@ const fragmentFor = (node: NavNode, id: string): string | undefined =>
|
|
|
79
79
|
// blank — the PageActions pattern.
|
|
80
80
|
const n = { ...EN_UI.nav, ...strings };
|
|
81
81
|
|
|
82
|
+
/** The DOM id of a drill-in panel, which its drill button controls. */
|
|
83
|
+
const navPanelId = (id: string): string => `blume-nav-panel-${id}`;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* A page row's href. A row backed by a page links a route Blume generates, so
|
|
87
|
+
* the deployment base always goes on — even over a route that starts with the
|
|
88
|
+
* base's own name. A config `href` link (no backing page) is authored, and
|
|
89
|
+
* keeps a base written by hand. Group rows link their index page the same way
|
|
90
|
+
* a backed page row does.
|
|
91
|
+
*/
|
|
92
|
+
const pageHref = (item: Extract<NavNode, { kind: "page" }>): string =>
|
|
93
|
+
item.pageId ? withMountedBase(item.route) : withBase(item.route);
|
|
94
|
+
|
|
82
95
|
const badgeBase =
|
|
83
96
|
"shrink-0 rounded-full px-1.5 py-0.5 font-medium text-[0.65rem] leading-none";
|
|
84
97
|
// HTTP-method, AsyncAPI-action, and GraphQL operation-kind badges (from a
|
|
@@ -165,6 +178,7 @@ const initialId =
|
|
|
165
178
|
data-nav-panel={panel.id}
|
|
166
179
|
data-nav-src={src}
|
|
167
180
|
hidden={panel.id !== initialId}
|
|
181
|
+
id={navPanelId(panel.id)}
|
|
168
182
|
>
|
|
169
183
|
{/* The title is the only sidebar link to the section's own page, so
|
|
170
184
|
a routed panel keeps it as a link; without a route the whole row
|
|
@@ -174,7 +188,7 @@ const initialId =
|
|
|
174
188
|
<div class="mb-3 flex items-center gap-0.5">
|
|
175
189
|
<button
|
|
176
190
|
aria-label={n.back}
|
|
177
|
-
class="-
|
|
191
|
+
class="-ms-1 flex shrink-0 items-center justify-center self-stretch rounded-[0.65rem] px-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
|
|
178
192
|
data-nav-back={panel.parentId}
|
|
179
193
|
type="button"
|
|
180
194
|
>
|
|
@@ -187,7 +201,7 @@ const initialId =
|
|
|
187
201
|
: undefined
|
|
188
202
|
}
|
|
189
203
|
class="flex-1 truncate rounded-[0.65rem] px-1 py-1 font-semibold text-foreground text-sm transition-colors hover:bg-muted"
|
|
190
|
-
href={
|
|
204
|
+
href={withMountedBase(panel.route)}
|
|
191
205
|
>
|
|
192
206
|
{panel.label}
|
|
193
207
|
</a>
|
|
@@ -195,7 +209,7 @@ const initialId =
|
|
|
195
209
|
) : (
|
|
196
210
|
<button
|
|
197
211
|
aria-label={`${n.back}: ${panel.label}`}
|
|
198
|
-
class="-
|
|
212
|
+
class="-ms-1 mb-3 flex w-full items-center gap-1.5 rounded-[0.65rem] p-1 text-start font-semibold text-foreground text-sm transition-colors hover:bg-muted"
|
|
199
213
|
data-nav-back={panel.parentId}
|
|
200
214
|
type="button"
|
|
201
215
|
>
|
|
@@ -253,7 +267,7 @@ const initialId =
|
|
|
253
267
|
<a
|
|
254
268
|
aria-current={current}
|
|
255
269
|
class="blume-nav-link truncate"
|
|
256
|
-
href={
|
|
270
|
+
href={pageHref(item)}
|
|
257
271
|
>
|
|
258
272
|
{item.label}
|
|
259
273
|
</a>
|
|
@@ -265,7 +279,7 @@ const initialId =
|
|
|
265
279
|
<a
|
|
266
280
|
aria-current={current}
|
|
267
281
|
class="blume-nav-link"
|
|
268
|
-
href={
|
|
282
|
+
href={pageHref(item)}
|
|
269
283
|
>
|
|
270
284
|
<span class="flex items-center gap-2">
|
|
271
285
|
{item.icon && (
|
|
@@ -293,11 +307,16 @@ const initialId =
|
|
|
293
307
|
const spacing =
|
|
294
308
|
index === 0 ? "mt-0" : display === "flat" ? "mt-6" : "mt-0.5";
|
|
295
309
|
|
|
296
|
-
// `page`: a single row that drills into this group's panel.
|
|
310
|
+
// `page`: a single row that drills into this group's panel. It
|
|
311
|
+
// controls that panel; NavTreeScript keeps `aria-expanded` in step
|
|
312
|
+
// with the panel shown (static markup, since cached subtrees and
|
|
313
|
+
// fragments can't carry per-page state).
|
|
297
314
|
if (display === "page") {
|
|
298
315
|
return (
|
|
299
316
|
<li class={spacing}>
|
|
300
317
|
<button
|
|
318
|
+
aria-controls={navPanelId(id)}
|
|
319
|
+
aria-expanded="false"
|
|
301
320
|
class="blume-nav-drill"
|
|
302
321
|
data-nav-to={id}
|
|
303
322
|
type="button"
|
|
@@ -339,7 +358,7 @@ const initialId =
|
|
|
339
358
|
: undefined
|
|
340
359
|
}
|
|
341
360
|
class="blume-nav-summary-link"
|
|
342
|
-
href={
|
|
361
|
+
href={withMountedBase(item.route)}
|
|
343
362
|
>
|
|
344
363
|
{item.icon && (
|
|
345
364
|
<Icon
|
|
@@ -377,7 +396,7 @@ const initialId =
|
|
|
377
396
|
</span>
|
|
378
397
|
</summary>
|
|
379
398
|
<div
|
|
380
|
-
class="space-y-0.5 border-border border-
|
|
399
|
+
class="space-y-0.5 border-border border-s ps-3"
|
|
381
400
|
data-nav-src={open ? undefined : fragmentFor(item, id)}
|
|
382
401
|
>
|
|
383
402
|
{/* A closed group's children are deferred (fetched into this
|
|
@@ -423,7 +442,7 @@ const initialId =
|
|
|
423
442
|
isGroupRowCurrent(item, currentRoute) ? "page" : undefined
|
|
424
443
|
}
|
|
425
444
|
class="blume-nav-heading-link"
|
|
426
|
-
href={
|
|
445
|
+
href={withMountedBase(item.route)}
|
|
427
446
|
>
|
|
428
447
|
{item.icon && (
|
|
429
448
|
<Icon
|
|
@@ -434,7 +453,7 @@ const initialId =
|
|
|
434
453
|
)}
|
|
435
454
|
<span class="truncate">{item.label}</span>
|
|
436
455
|
{item.badge && (
|
|
437
|
-
<span class={`
|
|
456
|
+
<span class={`ms-auto ${badgeClassFor(item.badge)}`}>{item.badge}</span>
|
|
438
457
|
)}
|
|
439
458
|
</a>
|
|
440
459
|
) : (
|
|
@@ -448,7 +467,7 @@ const initialId =
|
|
|
448
467
|
)}
|
|
449
468
|
<span class="truncate">{item.label}</span>
|
|
450
469
|
{item.badge && (
|
|
451
|
-
<span class={`
|
|
470
|
+
<span class={`ms-auto ${badgeClassFor(item.badge)}`}>{item.badge}</span>
|
|
452
471
|
)}
|
|
453
472
|
</>
|
|
454
473
|
)}
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
// once per group instead of once per page. Off in dev, where component edits
|
|
5
5
|
// must show on the next request. The cached HTML references the page's icon
|
|
6
6
|
// sprite (see icon-sprite.ts), so the symbols it used ride along and are
|
|
7
|
-
// registered into whichever page reuses it.
|
|
7
|
+
// registered into whichever page reuses it. A render with no sprite (the
|
|
8
|
+
// `/blume-nav/` fragment route) inlines its icons instead, so it is cached
|
|
9
|
+
// apart: sprite references reused there would point at symbols the page that
|
|
10
|
+
// fetches the fragment may never have rendered.
|
|
8
11
|
import type { NavNode } from "../../core/types.ts";
|
|
9
12
|
import { iconSpriteFor, referencedIconSymbols } from "../icon-sprite.ts";
|
|
10
13
|
import type { IconSymbol } from "../icon-sprite.ts";
|
|
@@ -19,7 +22,7 @@ const { node, variant } = Astro.props;
|
|
|
19
22
|
const sprite = iconSpriteFor(Astro.locals);
|
|
20
23
|
const { html, icons } = await cachedNavSubtree(
|
|
21
24
|
node,
|
|
22
|
-
variant
|
|
25
|
+
`${variant}|${sprite ? "sprite" : "inline"}`,
|
|
23
26
|
async () => {
|
|
24
27
|
const rendered = await Astro.slots.render("default");
|
|
25
28
|
const used: [string, IconSymbol][] = [];
|
|
@@ -40,7 +40,12 @@
|
|
|
40
40
|
return pending;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Fill a deferred element from its fragment; a no-op once filled. The rows
|
|
45
|
+
* are appended, not swapped in: a drill-in panel keeps its own back row
|
|
46
|
+
* (the Back button and the section's title) above the deferred rows, and a
|
|
47
|
+
* collapsed group's slot is empty anyway.
|
|
48
|
+
*/
|
|
44
49
|
const fillDeferred = async (slot: HTMLElement): Promise<void> => {
|
|
45
50
|
const src = slot.dataset.navSrc;
|
|
46
51
|
if (!src) {
|
|
@@ -48,8 +53,12 @@
|
|
|
48
53
|
}
|
|
49
54
|
slot.setAttribute("aria-busy", "true");
|
|
50
55
|
try {
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
const html = await loadFragment(src);
|
|
57
|
+
// Two opens racing on the same fetch fill it once.
|
|
58
|
+
if (slot.dataset.navSrc) {
|
|
59
|
+
slot.insertAdjacentHTML("beforeend", html);
|
|
60
|
+
delete slot.dataset.navSrc;
|
|
61
|
+
}
|
|
53
62
|
} finally {
|
|
54
63
|
slot.removeAttribute("aria-busy");
|
|
55
64
|
}
|
|
@@ -179,21 +188,52 @@
|
|
|
179
188
|
if (prev === next) {
|
|
180
189
|
return;
|
|
181
190
|
}
|
|
191
|
+
// The pressed drill or back button sits in the panel about to hide, so
|
|
192
|
+
// its focus has to move into the panel replacing it — left behind, the
|
|
193
|
+
// next Tab would leave the sidebar.
|
|
194
|
+
const hadFocus = prev?.contains(document.activeElement) ?? false;
|
|
182
195
|
// Settle any in-flight slide before starting the next one.
|
|
183
196
|
if (this.finishSlide) {
|
|
184
197
|
this.finishSlide();
|
|
185
198
|
}
|
|
186
199
|
this.active = next;
|
|
187
200
|
this.dataset.active = next.dataset.navPanel;
|
|
201
|
+
this.syncExpanded(next);
|
|
188
202
|
|
|
189
203
|
if (!(animate && prev) || this.reduced()) {
|
|
190
204
|
for (const panel of this.querySelectorAll<HTMLElement>("[data-nav-panel]")) {
|
|
191
205
|
panel.hidden = panel !== next;
|
|
192
206
|
}
|
|
193
|
-
|
|
207
|
+
} else {
|
|
208
|
+
this.slide(prev, next, this.depth(next) > this.depth(prev));
|
|
194
209
|
}
|
|
210
|
+
if (hadFocus && prev) {
|
|
211
|
+
this.focusInto(next, prev);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Each drill button is expanded exactly while the panel it opens shows. */
|
|
216
|
+
syncExpanded(shown: HTMLElement): void {
|
|
217
|
+
for (const drill of this.querySelectorAll("[data-nav-to]")) {
|
|
218
|
+
drill.setAttribute(
|
|
219
|
+
"aria-expanded",
|
|
220
|
+
String(drill.getAttribute("data-nav-to") === shown.dataset.navPanel)
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
195
224
|
|
|
196
|
-
|
|
225
|
+
/**
|
|
226
|
+
* Focus `next` after leaving `prev`: going back, the drill button that
|
|
227
|
+
* opened `prev`; drilling in, the new panel's back button (its first
|
|
228
|
+
* control). `preventScroll` keeps the focus from scrolling the clipped
|
|
229
|
+
* container mid-slide.
|
|
230
|
+
*/
|
|
231
|
+
focusInto(next: HTMLElement, prev: HTMLElement): void {
|
|
232
|
+
const target =
|
|
233
|
+
next.querySelector<HTMLElement>(
|
|
234
|
+
`[data-nav-to="${prev.dataset.navPanel}"]`
|
|
235
|
+
) ?? next.querySelector<HTMLElement>("button, a[href]");
|
|
236
|
+
target?.focus({ preventScroll: true });
|
|
197
237
|
}
|
|
198
238
|
|
|
199
239
|
slide(out: HTMLElement, into: HTMLElement, forward: boolean): void {
|
|
@@ -262,7 +262,7 @@ const menuRowClass =
|
|
|
262
262
|
<script>
|
|
263
263
|
import { copyDeferredText, copyText, flashLabel } from "../copy-feedback.ts";
|
|
264
264
|
import { installDropdownDismiss } from "../dropdown-dismiss.ts";
|
|
265
|
-
import {
|
|
265
|
+
import { mountBase } from "../islands/base-path.ts";
|
|
266
266
|
import { rafThrottle } from "../raf-throttle.ts";
|
|
267
267
|
|
|
268
268
|
const CHAT_URLS: Record<string, (q: string) => string> = {
|
|
@@ -390,9 +390,10 @@ hr { border: 0; border-top: 1px solid #ddd; margin: 2em 0; }`;
|
|
|
390
390
|
|
|
391
391
|
// `data-md` is the base-less logical route; the raw-markdown endpoint is a
|
|
392
392
|
// generated page route, so it's served under the deployment base like any
|
|
393
|
-
// other page
|
|
393
|
+
// other page, even when it starts with the base's own name. Mount it at
|
|
394
|
+
// emit time (the Search-island pattern).
|
|
394
395
|
const mdRoute = root.getAttribute("data-md") ?? "";
|
|
395
|
-
const md =
|
|
396
|
+
const md = mountBase(import.meta.env.BASE_URL, mdRoute);
|
|
396
397
|
const copiedLabel = root.getAttribute("data-i18n-copied") || "Copied!";
|
|
397
398
|
const copyFailedLabel =
|
|
398
399
|
root.getAttribute("data-i18n-copy-failed") || "Copy failed";
|
|
@@ -38,7 +38,8 @@ import {
|
|
|
38
38
|
} from "../../og/dimensions.ts";
|
|
39
39
|
import { buildStructuredData } from "../../seo/jsonld.ts";
|
|
40
40
|
import { normalizeXHandle } from "../../seo/x-handle.ts";
|
|
41
|
-
import
|
|
41
|
+
import Icon from "../Icon.astro";
|
|
42
|
+
import { stripBase, withBase, withMountedBase } from "../islands/base-path.ts";
|
|
42
43
|
import { pageDirection, pageLocale } from "./page-locale.ts";
|
|
43
44
|
import { searchLocaleFor } from "./search-locale.ts";
|
|
44
45
|
import "blume:theme";
|
|
@@ -55,6 +56,7 @@ import {
|
|
|
55
56
|
} from "./head-scripts.ts";
|
|
56
57
|
import Header from "./Header.astro";
|
|
57
58
|
import { currentTabForRoute } from "./nav-utils.ts";
|
|
59
|
+
import NavTabMenu from "./NavTabMenu.astro";
|
|
58
60
|
import WebMcp from "./WebMcp.astro";
|
|
59
61
|
|
|
60
62
|
interface Props {
|
|
@@ -217,7 +219,7 @@ const activeTab = currentTabForRoute(navigation.tabs, route, navigation.root);
|
|
|
217
219
|
// llms.txt index), and the homepage HTTP `Link` header already advertises it,
|
|
218
220
|
// so the head is its HTML counterpart on hosts that can't set that header.
|
|
219
221
|
// Advertising a mirror for any other custom route would 404.
|
|
220
|
-
const markdownMirror = route === "/" ?
|
|
222
|
+
const markdownMirror = route === "/" ? withMountedBase("/index.md") : null;
|
|
221
223
|
|
|
222
224
|
// Derive canonical + og:image from the site URL the same way the catch-all does
|
|
223
225
|
// for content pages, so a custom page gets both for free. The matching OG card
|
|
@@ -228,8 +230,9 @@ const markdownMirror = route === "/" ? withBase("/index.md") : null;
|
|
|
228
230
|
const ogSlug = route === "/" ? "index" : route.slice(1);
|
|
229
231
|
const ogCardGenerated = !Astro.routePattern.includes("[");
|
|
230
232
|
// Absolute URLs carry the deployment base too (`site + base + route`), since the
|
|
231
|
-
// page is served under it
|
|
232
|
-
|
|
233
|
+
// page is served under it — even when the route starts with the base's own
|
|
234
|
+
// name. `withMountedBase` handles a root base as a no-op.
|
|
235
|
+
const basedRoute = withMountedBase(route);
|
|
233
236
|
// The schema accepts a trailing-slash site URL (`https://docs.example.com/`);
|
|
234
237
|
// strip it before joining with the root-relative route so canonical/og URLs
|
|
235
238
|
// don't come out double-slashed — the catch-all strips it the same way.
|
|
@@ -251,7 +254,7 @@ const absolutizeOgImage = (value: string): string =>
|
|
|
251
254
|
const resolvedOgImage = ogImage
|
|
252
255
|
? absolutizeOgImage(ogImage)
|
|
253
256
|
: ogEnabled && ogCardGenerated && siteBase
|
|
254
|
-
? `${siteBase}${encodeURI(
|
|
257
|
+
? `${siteBase}${encodeURI(withMountedBase(`/og/${ogSlug}.png`))}`
|
|
255
258
|
: null;
|
|
256
259
|
// Only the generated card has a known size and format, so its dimensions are
|
|
257
260
|
// declared for crawlers; a user-supplied `ogImage` could be any image.
|
|
@@ -387,7 +390,7 @@ createIconSprite(Astro.locals);
|
|
|
387
390
|
>
|
|
388
391
|
{/* Every new-tab link's aria-describedby target (see core/new-tab.ts). */}
|
|
389
392
|
<span hidden id={NEW_TAB_HINT_ID}>{navStrings.opensInNewTab}</span>
|
|
390
|
-
<Banner banner={banner} strings={strings.banner} />
|
|
393
|
+
<Banner banner={banner} locale={locale} strings={strings.banner} />
|
|
391
394
|
<Header
|
|
392
395
|
assistantEnabled={assistantEnabled}
|
|
393
396
|
assistantStrings={strings.assistant}
|
|
@@ -426,13 +429,25 @@ createIconSprite(Astro.locals);
|
|
|
426
429
|
<ul class="m-0 list-none p-0">
|
|
427
430
|
{navigation.tabs.map((tab) => (
|
|
428
431
|
<li>
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
432
|
+
{tab.items && tab.items.length > 0 ? (
|
|
433
|
+
<NavTabMenu
|
|
434
|
+
active={tab === activeTab}
|
|
435
|
+
route={route}
|
|
436
|
+
tab={tab}
|
|
437
|
+
variant="drawer"
|
|
438
|
+
/>
|
|
439
|
+
) : (
|
|
440
|
+
<a
|
|
441
|
+
aria-current={tab === activeTab ? "page" : undefined}
|
|
442
|
+
class="flex items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 font-medium text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=page]:bg-muted aria-[current=page]:text-foreground"
|
|
443
|
+
href={withMountedBase(tab.href ?? tab.path)}
|
|
444
|
+
>
|
|
445
|
+
{tab.icon && (
|
|
446
|
+
<Icon class="shrink-0" name={tab.icon} size={14} />
|
|
447
|
+
)}
|
|
448
|
+
<span class="flex-1 truncate">{tab.label}</span>
|
|
449
|
+
</a>
|
|
450
|
+
)}
|
|
436
451
|
</li>
|
|
437
452
|
))}
|
|
438
453
|
</ul>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
2
|
+
import { withMountedBase } from "../islands/base-path.ts";
|
|
3
3
|
import { EN_UI } from "../../core/i18n-ui.ts";
|
|
4
4
|
import type { UIStrings } from "../../core/i18n-ui.ts";
|
|
5
5
|
import type { FlatPage } from "./nav-utils.ts";
|
|
@@ -31,7 +31,7 @@ const s = { ...EN_UI.page, ...strings };
|
|
|
31
31
|
{prev ? (
|
|
32
32
|
<a
|
|
33
33
|
class="flex max-w-[48%] flex-1 items-center gap-2 rounded-blume border border-border px-4 py-3 text-foreground transition-colors hover:border-foreground"
|
|
34
|
-
href={
|
|
34
|
+
href={withMountedBase(prev.route)}
|
|
35
35
|
>
|
|
36
36
|
<Icon class="rtl:-scale-x-100" name="arrow-left" size={16} />
|
|
37
37
|
<span class="min-w-0">
|
|
@@ -47,7 +47,7 @@ const s = { ...EN_UI.page, ...strings };
|
|
|
47
47
|
{next && (
|
|
48
48
|
<a
|
|
49
49
|
class="ms-auto flex max-w-[48%] flex-1 items-center justify-end gap-2 rounded-blume border border-border px-4 py-3 text-end text-foreground transition-colors hover:border-foreground"
|
|
50
|
-
href={
|
|
50
|
+
href={withMountedBase(next.route)}
|
|
51
51
|
>
|
|
52
52
|
<span class="min-w-0">
|
|
53
53
|
<span class="block text-muted-foreground text-xs">
|
|
@@ -146,18 +146,21 @@ createIconSprite(Astro.locals);
|
|
|
146
146
|
>
|
|
147
147
|
{/* Every new-tab link's aria-describedby target (see core/new-tab.ts). */}
|
|
148
148
|
<span hidden id={NEW_TAB_HINT_ID}>{navStrings.opensInNewTab}</span>
|
|
149
|
-
<Banner banner={banner} strings={strings.banner} />
|
|
149
|
+
<Banner banner={banner} locale={locale} strings={strings.banner} />
|
|
150
150
|
<Header
|
|
151
151
|
assistantStrings={strings.assistant}
|
|
152
152
|
hasDrawer={false}
|
|
153
153
|
hasSidebar={false}
|
|
154
154
|
locale={locale}
|
|
155
155
|
logo={logo}
|
|
156
|
+
navStrings={navStrings}
|
|
156
157
|
navigation={navigation}
|
|
157
158
|
route={route}
|
|
158
159
|
searchEnabled={searchEnabled}
|
|
159
160
|
searchLocale={searchLocale}
|
|
161
|
+
searchStrings={strings.search}
|
|
160
162
|
site={site}
|
|
163
|
+
switcherStrings={strings.languageSwitcher}
|
|
161
164
|
/>
|
|
162
165
|
<div
|
|
163
166
|
class="h-[calc(100dvh-4rem)] overflow-auto border-border border-t [&>[data-scalar-client]]:h-full"
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
} from "../../og/dimensions.ts";
|
|
40
40
|
import { buildStructuredData, toIso } from "../../seo/jsonld.ts";
|
|
41
41
|
import { normalizeXHandle } from "../../seo/x-handle.ts";
|
|
42
|
-
import { withBase } from "../islands/base-path.ts";
|
|
42
|
+
import { withBase, withMountedBase } from "../islands/base-path.ts";
|
|
43
43
|
import { isExternalUrl } from "../../core/base-path.ts";
|
|
44
44
|
import { NEW_TAB_HINT_ID, newTabAttrs } from "../../core/new-tab.ts";
|
|
45
45
|
import Analytics from "./Analytics.astro";
|
|
@@ -66,6 +66,7 @@ import {
|
|
|
66
66
|
navGroupIds,
|
|
67
67
|
sidebarForRoute,
|
|
68
68
|
} from "./nav-utils.ts";
|
|
69
|
+
import NavTabMenu from "./NavTabMenu.astro";
|
|
69
70
|
import NavTree from "./NavTree.astro";
|
|
70
71
|
import { resolveSlot } from "./overrides.ts";
|
|
71
72
|
import { pageDirection, pageLocale } from "./page-locale.ts";
|
|
@@ -400,12 +401,12 @@ const formattedLastModified =
|
|
|
400
401
|
// not a content route and has none.
|
|
401
402
|
const markdownMirror = isBare
|
|
402
403
|
? null
|
|
403
|
-
:
|
|
404
|
+
: withMountedBase(page.route === "/" ? "/index.md" : `${page.route}.md`);
|
|
404
405
|
|
|
405
406
|
// The hosted MCP server's absolute URL, used by the page-actions install menu.
|
|
406
407
|
// Needs a configured site to be useful, so the menu is hidden without one.
|
|
407
408
|
const mcpUrl =
|
|
408
|
-
mcp && siteUrl ? new URL(
|
|
409
|
+
mcp && siteUrl ? new URL(withMountedBase(mcp.route), siteUrl).href : null;
|
|
409
410
|
|
|
410
411
|
// Scope the sidebar (and the breadcrumbs/pagination derived from it) to the
|
|
411
412
|
// active tab's section, so a multi-section site drills each tab into its own
|
|
@@ -539,7 +540,7 @@ createIconSprite(Astro.locals);
|
|
|
539
540
|
{
|
|
540
541
|
feeds?.map((feed) => (
|
|
541
542
|
<link
|
|
542
|
-
href={
|
|
543
|
+
href={withMountedBase(feed.href)}
|
|
543
544
|
rel="alternate"
|
|
544
545
|
title={feed.title}
|
|
545
546
|
type="application/rss+xml"
|
|
@@ -579,7 +580,7 @@ createIconSprite(Astro.locals);
|
|
|
579
580
|
>
|
|
580
581
|
{/* Every new-tab link's aria-describedby target (see core/new-tab.ts). */}
|
|
581
582
|
<span hidden id={NEW_TAB_HINT_ID}>{navStrings.opensInNewTab}</span>
|
|
582
|
-
<Banner banner={banner} strings={strings.banner} />
|
|
583
|
+
<Banner banner={banner} locale={locale} strings={strings.banner} />
|
|
583
584
|
<VersionBanner notice={versionNotice ?? null} />
|
|
584
585
|
<HeaderSlot
|
|
585
586
|
assistantEnabled={assistantEnabled}
|
|
@@ -677,13 +678,25 @@ createIconSprite(Astro.locals);
|
|
|
677
678
|
<ul class="m-0 list-none p-0">
|
|
678
679
|
{navigation.tabs.map((tab) => (
|
|
679
680
|
<li>
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
681
|
+
{tab.items && tab.items.length > 0 ? (
|
|
682
|
+
<NavTabMenu
|
|
683
|
+
active={tab === activeTab}
|
|
684
|
+
route={page.route}
|
|
685
|
+
tab={tab}
|
|
686
|
+
variant="drawer"
|
|
687
|
+
/>
|
|
688
|
+
) : (
|
|
689
|
+
<a
|
|
690
|
+
aria-current={tab === activeTab ? "page" : undefined}
|
|
691
|
+
class="flex items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 font-medium text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=page]:bg-muted aria-[current=page]:text-foreground"
|
|
692
|
+
href={withMountedBase(tab.href ?? tab.path)}
|
|
693
|
+
>
|
|
694
|
+
{tab.icon && (
|
|
695
|
+
<Icon class="shrink-0" name={tab.icon} size={14} />
|
|
696
|
+
)}
|
|
697
|
+
<span class="flex-1 truncate">{tab.label}</span>
|
|
698
|
+
</a>
|
|
699
|
+
)}
|
|
687
700
|
</li>
|
|
688
701
|
))}
|
|
689
702
|
</ul>
|