@umami/shiso 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,8 @@
1
+ import { n as highlightTerms } from "./search.js";
1
2
  import { resolveSearchProvider } from "../search.js";
2
3
  import * as React$1 from "react";
3
4
  import { Children, cloneElement, createContext, createElement, forwardRef, isValidElement, useCallback, useContext, useDebugValue, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore, useSyncExternalStore as useSyncExternalStore$1 } from "react";
4
- import "@fontsource/inter/400.css";
5
- import "@fontsource/inter/700.css";
6
- import "@fontsource/inter/800.css";
5
+ import "@fontsource-variable/inter/index.css";
7
6
  import "@fontsource/jetbrains-mono/400.css";
8
7
  import "highlight.js/styles/github.css";
9
8
  import "@umami/shiso/styles.css";
@@ -11,6 +10,7 @@ import { MDXProvider } from "@mdx-js/react";
11
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
12
11
  import * as ReactDOM from "react-dom";
13
12
  import { ICON_REGISTRY } from "@/lib/icon-registry.generated";
13
+ import shiso from "virtual:shiso-config";
14
14
  import rawConfig from "virtual:shiso-docs-config";
15
15
  import { LAST_MODIFIED } from "@/generated/last-modified";
16
16
 
@@ -4561,7 +4561,7 @@ function renderTag(Tag, props) {
4561
4561
  *
4562
4562
  * Documentation: [Base UI Button](https://base-ui.com/react/components/button)
4563
4563
  */
4564
- const Button$1 = /*#__PURE__*/ React$1.forwardRef(function Button(componentProps, forwardedRef) {
4564
+ const Button$2 = /*#__PURE__*/ React$1.forwardRef(function Button(componentProps, forwardedRef) {
4565
4565
  const { render, className, disabled = false, focusableWhenDisabled = false, nativeButton = true, style, ...elementProps } = componentProps;
4566
4566
  const { getButtonProps, buttonRef } = useButton({
4567
4567
  disabled,
@@ -4574,7 +4574,7 @@ const Button$1 = /*#__PURE__*/ React$1.forwardRef(function Button(componentProps
4574
4574
  props: [elementProps, getButtonProps]
4575
4575
  });
4576
4576
  });
4577
- Button$1.displayName = "Button";
4577
+ Button$2.displayName = "Button";
4578
4578
 
4579
4579
  //#endregion
4580
4580
  //#region ../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
@@ -8063,8 +8063,8 @@ const buttonVariants = cva("group/button inline-flex shrink-0 items-center justi
8063
8063
  size: "default"
8064
8064
  }
8065
8065
  });
8066
- function Button({ className, variant = "default", size = "default", ...props }) {
8067
- return /* @__PURE__ */ jsx(Button$1, {
8066
+ function Button$1({ className, variant = "default", size = "default", ...props }) {
8067
+ return /* @__PURE__ */ jsx(Button$2, {
8068
8068
  "data-slot": "button",
8069
8069
  className: cn(buttonVariants({
8070
8070
  variant,
@@ -9582,7 +9582,7 @@ function CodeBlock({ children, className }) {
9582
9582
  className: `code-block p-3 pr-12 text-sm text-foreground leading-[1.6] font-mono ${className || ""}`,
9583
9583
  children
9584
9584
  })
9585
- }), /* @__PURE__ */ jsx(Button, {
9585
+ }), /* @__PURE__ */ jsx(Button$1, {
9586
9586
  type: "button",
9587
9587
  variant: "ghost",
9588
9588
  size: "icon-sm",
@@ -11332,6 +11332,40 @@ function Badge({ color, size = "md", shape = "rounded", icon, stroke = false, di
11332
11332
  });
11333
11333
  }
11334
11334
 
11335
+ //#endregion
11336
+ //#region src/components/docs/Button.tsx
11337
+ /**
11338
+ * MDX-facing button. Renders a link when `href` is set (internal routes go
11339
+ * through react-router), otherwise a plain button element.
11340
+ */
11341
+ function Button({ href, variant = "default", size = "default", icon, className, children }) {
11342
+ const resolvedIcon = resolveIcon(icon, 16);
11343
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [resolvedIcon, children] });
11344
+ const baseClassName = cn(resolvedIcon ? "gap-2" : "", "[&_p]:m-0", className);
11345
+ if (!href) return /* @__PURE__ */ jsx(Button$1, {
11346
+ variant,
11347
+ size,
11348
+ className: baseClassName,
11349
+ children: content
11350
+ });
11351
+ const linkClassName = cn(buttonVariants({
11352
+ variant,
11353
+ size
11354
+ }), "no-underline hover:no-underline active:no-underline", baseClassName);
11355
+ if (/^https?:\/\//i.test(href)) return /* @__PURE__ */ jsx("a", {
11356
+ href,
11357
+ className: linkClassName,
11358
+ target: "_blank",
11359
+ rel: "noreferrer",
11360
+ children: content
11361
+ });
11362
+ return /* @__PURE__ */ jsx(Link, {
11363
+ to: href,
11364
+ className: linkClassName,
11365
+ children: content
11366
+ });
11367
+ }
11368
+
11335
11369
  //#endregion
11336
11370
  //#region src/components/ui/alert.tsx
11337
11371
  const alertVariants = cva("group/alert relative grid w-full gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4", {
@@ -12857,18 +12891,18 @@ function PropertiesTable({ children }) {
12857
12891
  return /* @__PURE__ */ jsx("div", {
12858
12892
  className: "my-4 overflow-x-auto rounded-lg border border-border px-6 py-2",
12859
12893
  children: /* @__PURE__ */ jsxs("table", {
12860
- className: "m-0 min-w-[40rem] table-fixed border-collapse",
12894
+ className: "m-0 min-w-[40rem] table-fixed border-collapse border-0",
12861
12895
  children: [/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
12862
12896
  /* @__PURE__ */ jsx("th", {
12863
- className: "w-1/3 border-x-0 border-t-0 border-b border-border bg-transparent px-0 py-2 pr-6 text-left text-sm font-semibold text-foreground",
12897
+ className: "w-1/5 border-x-0 border-t-0 border-b border-border bg-transparent px-0 py-2 pr-6 text-left text-sm font-semibold text-foreground",
12864
12898
  children: "Name"
12865
12899
  }),
12866
12900
  /* @__PURE__ */ jsx("th", {
12867
- className: "w-1/3 border-x-0 border-t-0 border-b border-border bg-transparent px-0 py-2 pr-6 text-left text-sm font-semibold text-foreground",
12901
+ className: "w-1/4 border-x-0 border-t-0 border-b border-border bg-transparent px-0 py-2 pr-6 text-left text-sm font-semibold text-foreground",
12868
12902
  children: "Type"
12869
12903
  }),
12870
12904
  /* @__PURE__ */ jsx("th", {
12871
- className: "w-1/3 border-x-0 border-t-0 border-b border-border bg-transparent px-0 py-2 text-left text-sm font-semibold text-foreground",
12905
+ className: "border-x-0 border-t-0 border-b border-border bg-transparent px-0 py-2 text-left text-sm font-semibold text-foreground",
12872
12906
  children: "Description"
12873
12907
  })
12874
12908
  ] }) }), /* @__PURE__ */ jsx("tbody", { children: rows.map((row, index) => {
@@ -20509,7 +20543,7 @@ function DialogContent$1({ className, children, showCloseButton = true, overlayC
20509
20543
  ...props,
20510
20544
  children: [children, showCloseButton && /* @__PURE__ */ jsxs(DialogClose, {
20511
20545
  "data-slot": "dialog-close",
20512
- render: /* @__PURE__ */ jsx(Button, {
20546
+ render: /* @__PURE__ */ jsx(Button$1, {
20513
20547
  variant: "ghost",
20514
20548
  className: "absolute top-2 right-2",
20515
20549
  size: "icon-sm"
@@ -20571,6 +20605,7 @@ var docs_exports = /* @__PURE__ */ __exportAll({
20571
20605
  Accordion: () => Accordion,
20572
20606
  AccordionGroup: () => AccordionGroup,
20573
20607
  Badge: () => Badge,
20608
+ Button: () => Button,
20574
20609
  Callout: () => Callout,
20575
20610
  Card: () => Card,
20576
20611
  CardGroup: () => CardGroup,
@@ -20628,7 +20663,7 @@ function Banner({ banner, dismissLabel }) {
20628
20663
  children: [/* @__PURE__ */ jsx("div", {
20629
20664
  className: "[&_a:hover]:opacity-[0.85] [&_a]:text-inherit [&_a]:underline [&_a]:underline-offset-2 [&_code]:rounded-sm [&_code]:bg-black/20 [&_code]:px-1 [&_code]:py-[0.0625rem] [&_code]:text-[0.8125rem] [&_code]:font-mono",
20630
20665
  children: renderInlineMarkdown(banner.content)
20631
- }), banner.dismissible && /* @__PURE__ */ jsx(Button, {
20666
+ }), banner.dismissible && /* @__PURE__ */ jsx(Button$1, {
20632
20667
  type: "button",
20633
20668
  variant: "ghost",
20634
20669
  size: "icon-xs",
@@ -22216,8 +22251,10 @@ function DropdownMenuItem({ className, inset, variant = "default", ...props }) {
22216
22251
  * DOCS_PREFIX but not BASE_URL. React Router's `basename` adds BASE_URL, so
22217
22252
  * only code that bypasses the router (prerender output paths, canonical URLs,
22218
22253
  * raw <a href>) needs `toHref`.
22254
+ *
22255
+ * Values from `virtual:shiso-config` arrive with defaults applied and already
22256
+ * normalized by scripts/load-shiso-config.mjs.
22219
22257
  */
22220
- const shiso = rawConfig.$shiso || {};
22221
22258
  /** Strips trailing slashes; "/" and "" both normalize to "". */
22222
22259
  function normalizePrefix(value) {
22223
22260
  const trimmed = value.trim().replace(/\/+$/, "");
@@ -22225,11 +22262,14 @@ function normalizePrefix(value) {
22225
22262
  return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
22226
22263
  }
22227
22264
  const BASE_URL = normalizePrefix(import.meta.env?.BASE_URL || "/");
22228
- const DOCS_PREFIX = normalizePrefix(shiso.docsPrefix ?? "/docs");
22265
+ const DOCS_PREFIX = shiso.docsPrefix;
22229
22266
  /** Content directory, relative to the project root, without leading/trailing slashes. */
22230
- const CONTENT_DIR = (shiso.contentDir ?? "content/docs").replace(/^\/+|\/+$/g, "");
22267
+ const CONTENT_DIR = shiso.contentDir;
22268
+ /** Fixed root for standalone (non-docs) page files. Not configurable, so page
22269
+ * slugs can never collide with the docs content tree. */
22270
+ const PAGES_DIR = "content/pages";
22231
22271
  /** Absolute origin used for canonical and og:url tags. Undefined when unconfigured. */
22232
- const SITE_URL = shiso.siteUrl?.replace(/\/+$/, "") || void 0;
22272
+ const SITE_URL = shiso.siteUrl;
22233
22273
  /** Joins path segments with exactly one slash between them. */
22234
22274
  function joinPath(...parts) {
22235
22275
  const joined = parts.filter((part) => !!part).join("/").replace(/\/{2,}/g, "/");
@@ -22813,7 +22853,7 @@ function isNodeHidden(node) {
22813
22853
  * without Suspense, at the cost of bundling all pages together.
22814
22854
  *
22815
22855
  * The glob pattern must be a literal for Vite to statically analyze it, so it
22816
- * covers all of `content/` and the configured `$shiso.contentDir` is applied at
22856
+ * covers all of `content/` and the configured shiso.config `contentDir` is applied at
22817
22857
  * lookup time instead. That also lets later versioned/localized content roots
22818
22858
  * (`content/v2`, `content/es`) work without touching this glob.
22819
22859
  */
@@ -22826,6 +22866,13 @@ const docModules = import.meta.glob("/content/**/*.{md,mdx}", { eager: true });
22826
22866
  function resolveDocFile(fileSlug, contentDir = CONTENT_DIR) {
22827
22867
  return [`/${contentDir}/${fileSlug}.mdx`, `/${contentDir}/${fileSlug}.md`].find((candidate) => candidate in docModules);
22828
22868
  }
22869
+ /**
22870
+ * Resolves a standalone page slug (docs.json `pages[].page`) to a module key
22871
+ * under the fixed content/pages root.
22872
+ */
22873
+ function resolvePageFile(fileSlug) {
22874
+ return resolveDocFile(fileSlug, PAGES_DIR);
22875
+ }
22829
22876
  function getDocModule(filePath) {
22830
22877
  return docModules[filePath];
22831
22878
  }
@@ -22866,7 +22913,7 @@ function isValidLocale(value) {
22866
22913
  }
22867
22914
  /**
22868
22915
  * Locale for a page: its scope's language code when valid, then the
22869
- * site-wide `$shiso.locale`, then en-US.
22916
+ * site-wide shiso.config `locale`, then en-US.
22870
22917
  */
22871
22918
  function resolveLocale(language, fallback) {
22872
22919
  if (isValidLocale(language)) return Intl.getCanonicalLocales(language)[0];
@@ -22975,7 +23022,7 @@ function normalizeFooter(config) {
22975
23022
  attribution
22976
23023
  } : null;
22977
23024
  }
22978
- function resolveSiteModel(config, docs) {
23025
+ function resolveSiteModel(config, docs, shiso) {
22979
23026
  const appearance = config.appearance || {};
22980
23027
  const logo = config.logo ? typeof config.logo === "string" ? {
22981
23028
  light: config.logo,
@@ -23008,7 +23055,7 @@ function resolveSiteModel(config, docs) {
23008
23055
  },
23009
23056
  showTimestamp: config.metadata?.timestamp === true,
23010
23057
  drilldown: config.interaction?.drilldown,
23011
- locale: config.$shiso?.locale?.trim() || "en-US",
23058
+ locale: shiso?.locale || "en-US",
23012
23059
  labels: SHISO_THEME_LABELS,
23013
23060
  docs
23014
23061
  };
@@ -23085,6 +23132,58 @@ function resolveContextualOptions(options, page, labels = SHISO_THEME_LABELS) {
23085
23132
  return resolved;
23086
23133
  }
23087
23134
 
23135
+ //#endregion
23136
+ //#region src/lib/standalone-pages.ts
23137
+ function invalid(message) {
23138
+ return /* @__PURE__ */ new Error(`Invalid docs config: ${message}`);
23139
+ }
23140
+ /** Trims and canonicalizes a standalone route path; throws when malformed. */
23141
+ function normalizePath(rawPath) {
23142
+ const value = typeof rawPath === "string" ? rawPath.trim() : "";
23143
+ if (!value.startsWith("/")) throw invalid(`standalone page path "${String(rawPath)}" must start with "/".`);
23144
+ if (/[:*]/.test(value)) throw invalid(`standalone page path "${value}" must not use wildcard patterns.`);
23145
+ if (/\.mdx?$/i.test(value)) throw invalid(`standalone page path "${value}" must be a route, not a file — drop the extension.`);
23146
+ return value.replace(/\/{2,}/g, "/").replace(/\/+$/, "") || "/";
23147
+ }
23148
+ /** Mirrors normalizePageReference in docs-config.ts for the `page` slug. */
23149
+ function normalizePageSlug(rawSlug) {
23150
+ return (typeof rawSlug === "string" ? rawSlug : "").trim().replace(/\\/g, "/").replace(/^\/+/, "").replace(/^pages\//, "").replace(/\.mdx?$/, "").replace(/\/+$/, "") || "index";
23151
+ }
23152
+ function normalizeStandalonePages(config, resolvePageFile, site, options = {}) {
23153
+ const items = config.pages || [];
23154
+ if (!items.length) return [];
23155
+ const docsPrefix = options.docsPrefix || "";
23156
+ const pages = [];
23157
+ const seen = /* @__PURE__ */ new Set();
23158
+ for (const item of items) {
23159
+ const path = normalizePath(item?.path);
23160
+ if (seen.has(path)) throw invalid(`duplicate standalone page path "${path}".`);
23161
+ seen.add(path);
23162
+ if (path === "/404") throw invalid("standalone page path \"/404\" is reserved for the error page.");
23163
+ const docsPage = site.pageByUrl[path];
23164
+ if (docsPage) throw invalid(`standalone page path "${path}" collides with the docs page "${docsPage.fileSlug}". Standalone pages must live outside the docs navigation.`);
23165
+ if (docsPrefix && (path === docsPrefix || path.startsWith(`${docsPrefix}/`))) throw invalid(`standalone page path "${path}" is inside the docs prefix "${docsPrefix}". Standalone pages must live outside the docs tree.`);
23166
+ const fileSlug = normalizePageSlug(item?.page);
23167
+ const filePath = resolvePageFile(fileSlug);
23168
+ if (!filePath) throw new Error(`Missing standalone page file for "${fileSlug}": expected "content/pages/${fileSlug}.mdx" or ".md".`);
23169
+ pages.push({
23170
+ path,
23171
+ filePath,
23172
+ title: item?.title?.trim() || void 0
23173
+ });
23174
+ }
23175
+ return pages;
23176
+ }
23177
+ /**
23178
+ * Exact standalone page lookup by base-relative pathname. Tolerates trailing
23179
+ * slashes and an explicit `/index` suffix, like getPageByPathname.
23180
+ */
23181
+ function getStandalonePageByPathname(pages, pathname) {
23182
+ const trimmed = pathname.replace(/\/+$/, "") || "/";
23183
+ const collapsed = trimmed === "/index" ? "/" : trimmed.replace(/\/index$/, "") || "/";
23184
+ return pages.find((page) => page.path === trimmed || page.path === collapsed) || null;
23185
+ }
23186
+
23088
23187
  //#endregion
23089
23188
  //#region src/lib/site-config.ts
23090
23189
  assertDocsConfig(rawConfig, "docs.json");
@@ -23095,7 +23194,14 @@ const docsSite = normalizeDocsSite(siteConfig, resolveDocFile);
23095
23194
  const docsConfig = getDefaultScope(docsSite).docs;
23096
23195
  /** Landing page of the default scope: the site-wide "docs home" URL. */
23097
23196
  const docsHomeUrl = getDefaultScope(docsSite).firstPageUrl;
23098
- const siteModel = resolveSiteModel(siteConfig, docsConfig);
23197
+ const siteModel = resolveSiteModel(siteConfig, docsConfig, shiso);
23198
+ /** Standalone pages declared with the top-level `pages` key, e.g. a home page. */
23199
+ const standalonePages = normalizeStandalonePages(siteConfig, resolvePageFile, docsSite, { docsPrefix: DOCS_PREFIX });
23200
+ /** True when a standalone page owns "/", replacing the root docs redirect. */
23201
+ const hasRootStandalonePage = standalonePages.some((page) => page.path === "/");
23202
+ function getStandalonePage(pathname) {
23203
+ return getStandalonePageByPathname(standalonePages, stripBase(pathname));
23204
+ }
23099
23205
  /** Scope that owns the current pathname; the default scope for unknown paths. */
23100
23206
  function getScopeByPathname(pathname) {
23101
23207
  const page = getPageByPathname(pathname);
@@ -23168,7 +23274,7 @@ function LanguageSwitcher() {
23168
23274
  const options = getLanguageScopes(docsSite);
23169
23275
  if (!current.language || options.length < 2 && !current.hidden) return null;
23170
23276
  return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(DropdownMenuTrigger, {
23171
- render: /* @__PURE__ */ jsx(Button, {
23277
+ render: /* @__PURE__ */ jsx(Button$1, {
23172
23278
  variant: "outline",
23173
23279
  className: "h-auto gap-1.5 rounded-md bg-card px-2.5 py-1.5 text-sm font-medium text-foreground"
23174
23280
  }),
@@ -25990,6 +26096,11 @@ function renderSnippet(snippet) {
25990
26096
  children: part
25991
26097
  }, index) : part);
25992
26098
  }
26099
+ function renderWithQueryHighlight(text, query) {
26100
+ const terms = query.trim().split(/\s+/).filter(Boolean);
26101
+ if (!terms.length) return text;
26102
+ return renderSnippet(highlightTerms(text, terms));
26103
+ }
25993
26104
  /**
25994
26105
  * Provider-neutral search dialog. The selected provider and its index or
25995
26106
  * client are loaded on demand, so search stays out of the initial bundle.
@@ -26081,7 +26192,7 @@ function Search({ config, labels }) {
26081
26192
  open,
26082
26193
  onOpenChange: (nextOpen) => nextOpen ? openDialog() : closeDialog(),
26083
26194
  children: [/* @__PURE__ */ jsxs(DialogTrigger, {
26084
- render: /* @__PURE__ */ jsx(Button, {
26195
+ render: /* @__PURE__ */ jsx(Button$1, {
26085
26196
  variant: "outline",
26086
26197
  className: "h-auto gap-2 rounded-md bg-card px-2.5 py-1.5 text-muted-foreground hover:border-input hover:bg-card hover:text-foreground"
26087
26198
  }),
@@ -26125,7 +26236,7 @@ function Search({ config, labels }) {
26125
26236
  onSelect: () => select(result),
26126
26237
  children: [/* @__PURE__ */ jsxs("div", {
26127
26238
  className: "text-[0.9rem] font-semibold text-foreground",
26128
- children: [result.page, result.heading ? ` › ${result.heading}` : ""]
26239
+ children: [renderWithQueryHighlight(result.page, query), result.heading ? /* @__PURE__ */ jsxs(Fragment, { children: [" › ", renderWithQueryHighlight(result.heading, query)] }) : null]
26129
26240
  }), result.snippet && /* @__PURE__ */ jsx("div", {
26130
26241
  className: "mt-[0.15rem] line-clamp-2 text-[0.8rem] text-muted-foreground",
26131
26242
  children: renderSnippet(result.snippet)
@@ -26152,7 +26263,7 @@ function ThemeToggle({ label }) {
26152
26263
  localStorage.setItem("shiso-theme", next);
26153
26264
  } catch {}
26154
26265
  };
26155
- return /* @__PURE__ */ jsxs(Button, {
26266
+ return /* @__PURE__ */ jsxs(Button$1, {
26156
26267
  type: "button",
26157
26268
  variant: "ghost",
26158
26269
  size: "icon",
@@ -26197,7 +26308,10 @@ function TopNav({ docs, label }) {
26197
26308
  const navigate = useNavigate();
26198
26309
  const tabs = docs.tabs.filter((tab) => !tab.hidden);
26199
26310
  if (!tabs.length) return null;
26200
- const selected = docs.pages.find((item) => item.url === pathname)?.tabId || [...tabs].sort((a, b) => b.url.length - a.url.length).find((tab) => pathname === tab.url || pathname.startsWith(`${tab.url}/`))?.id || tabs[0]?.id;
26311
+ const page = docs.pages.find((item) => item.url === pathname);
26312
+ const matchedTabId = [...tabs].sort((a, b) => b.url.length - a.url.length).find((tab) => pathname === tab.url || pathname.startsWith(`${tab.url}/`))?.id;
26313
+ const fallbackTabId = getStandalonePage(pathname) ? void 0 : tabs[0]?.id;
26314
+ const selected = page?.tabId || matchedTabId || fallbackTabId;
26201
26315
  const tabClass = (tab) => cn("flex h-full items-center gap-1 whitespace-nowrap border-transparent border-b-2 font-medium", {
26202
26316
  "border-b-primary text-foreground": tab.id === selected,
26203
26317
  "text-muted-foreground hover:text-foreground": tab.id !== selected
@@ -26255,7 +26369,7 @@ function VersionSwitcher() {
26255
26369
  const options = docsSite.scopes.filter((scope) => scope.version && !scope.hidden && scope.language === current.language);
26256
26370
  if (!current.version || options.length < 2 && !current.hidden) return null;
26257
26371
  return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(DropdownMenuTrigger, {
26258
- render: /* @__PURE__ */ jsx(Button, {
26372
+ render: /* @__PURE__ */ jsx(Button$1, {
26259
26373
  variant: "outline",
26260
26374
  className: "h-auto gap-1.5 rounded-md bg-card px-2.5 py-1.5 text-sm font-medium text-foreground"
26261
26375
  }),
@@ -26277,24 +26391,54 @@ function VersionSwitcher() {
26277
26391
 
26278
26392
  //#endregion
26279
26393
  //#region src/components/Header.tsx
26394
+ /**
26395
+ * Header hrefs come from config, so they may point inside the site or off it.
26396
+ * In-app routes go through react-router; anything external (or explicitly
26397
+ * opened in a new tab) stays a plain anchor and triggers a document load.
26398
+ */
26399
+ function isRoutedHref(href, target) {
26400
+ return href.startsWith("/") && !isExternalHref(href) && target !== "_blank";
26401
+ }
26280
26402
  function NavbarLinkItem({ link, primary = false }) {
26281
26403
  const iconOnly = !link.label;
26282
26404
  const accessibleLabel = link.ariaLabel || link.icon || link.href;
26283
- return /* @__PURE__ */ jsxs("a", {
26405
+ const className = primary ? `ml-1 inline-flex items-center justify-center rounded-full bg-primary text-sm font-semibold text-primary-foreground hover:opacity-90 ${iconOnly ? "size-8" : "gap-1.5 px-3.5 py-1.5"}` : `inline-flex items-center rounded-md text-sm font-medium text-foreground hover:bg-accent hover:text-foreground ${iconOnly ? "size-8 justify-center" : "gap-1.5 px-2.5 py-1.5"}`;
26406
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ConfiguredIcon, { icon: link.icon }), link.label] });
26407
+ if (isRoutedHref(link.href, link.target)) return /* @__PURE__ */ jsx(Link, {
26408
+ to: link.href,
26409
+ className,
26410
+ "aria-label": iconOnly ? accessibleLabel : void 0,
26411
+ children: content
26412
+ });
26413
+ return /* @__PURE__ */ jsx("a", {
26284
26414
  href: link.href,
26285
- className: primary ? `ml-1 inline-flex items-center justify-center rounded-full bg-primary text-sm font-semibold text-primary-foreground hover:opacity-90 ${iconOnly ? "size-8" : "gap-1.5 px-3.5 py-1.5"}` : `inline-flex items-center rounded-md text-sm font-medium text-foreground hover:bg-accent hover:text-foreground ${iconOnly ? "size-8 justify-center" : "gap-1.5 px-2.5 py-1.5"}`,
26415
+ className,
26286
26416
  target: link.target,
26287
26417
  rel: link.target === "_blank" ? "noreferrer" : void 0,
26288
26418
  "aria-label": iconOnly ? accessibleLabel : void 0,
26289
- children: [/* @__PURE__ */ jsx(ConfiguredIcon, { icon: link.icon }), link.label]
26419
+ children: content
26290
26420
  });
26291
26421
  }
26292
26422
  function Header({ site }) {
26293
26423
  const { logo, navbar, name, appearance, labels, search } = site;
26294
26424
  const { pathname } = useLocation();
26295
26425
  const docs = getScopeByPathname(pathname).docs;
26296
- const brandHref = logo?.href || docsHomeUrl;
26426
+ const brandHref = logo?.href || (hasRootStandalonePage ? "/" : docsHomeUrl);
26297
26427
  const hasBrand = !!name || !!logo?.light || !!logo?.dark;
26428
+ const brandClassName = "inline-flex items-center gap-2 text-xl font-bold text-foreground tracking-[-0.03em]";
26429
+ const brandContent = /* @__PURE__ */ jsxs(Fragment, { children: [
26430
+ logo?.light ? /* @__PURE__ */ jsx("img", {
26431
+ src: logo.light,
26432
+ alt: "",
26433
+ className: "h-6 w-auto dark:hidden"
26434
+ }) : null,
26435
+ logo?.dark ? /* @__PURE__ */ jsx("img", {
26436
+ src: logo.dark,
26437
+ alt: "",
26438
+ className: "hidden h-6 w-auto dark:block"
26439
+ }) : null,
26440
+ name ? /* @__PURE__ */ jsx("span", { children: name }) : null
26441
+ ] });
26298
26442
  return /* @__PURE__ */ jsx("header", {
26299
26443
  className: "sticky top-0 z-50 h-[var(--header-height)] shrink-0 border-border border-b bg-[color-mix(in_srgb,var(--background)_92%,transparent)] backdrop-blur-md",
26300
26444
  children: /* @__PURE__ */ jsxs("div", {
@@ -26302,24 +26446,16 @@ function Header({ site }) {
26302
26446
  children: [
26303
26447
  /* @__PURE__ */ jsxs("div", {
26304
26448
  className: "flex min-w-0 items-center gap-5 justify-self-start",
26305
- children: [hasBrand ? /* @__PURE__ */ jsxs("a", {
26449
+ children: [hasBrand ? isRoutedHref(brandHref, logo?.target) ? /* @__PURE__ */ jsx(Link, {
26450
+ to: brandHref,
26451
+ className: brandClassName,
26452
+ children: brandContent
26453
+ }) : /* @__PURE__ */ jsx("a", {
26306
26454
  href: brandHref,
26307
26455
  target: logo?.target,
26308
26456
  rel: logo?.target === "_blank" ? "noreferrer" : void 0,
26309
- className: "inline-flex items-center gap-2 text-xl font-bold text-foreground tracking-[-0.03em]",
26310
- children: [
26311
- logo?.light ? /* @__PURE__ */ jsx("img", {
26312
- src: logo.light,
26313
- alt: "",
26314
- className: "h-6 w-auto dark:hidden"
26315
- }) : null,
26316
- logo?.dark ? /* @__PURE__ */ jsx("img", {
26317
- src: logo.dark,
26318
- alt: "",
26319
- className: "hidden h-6 w-auto dark:block"
26320
- }) : null,
26321
- name ? /* @__PURE__ */ jsx("span", { children: name }) : null
26322
- ]
26457
+ className: brandClassName,
26458
+ children: brandContent
26323
26459
  }) : null, /* @__PURE__ */ jsxs("div", {
26324
26460
  className: "hidden items-center gap-2 lg:flex",
26325
26461
  children: [/* @__PURE__ */ jsx(VersionSwitcher, {}), /* @__PURE__ */ jsx(LanguageSwitcher, {})]
@@ -26365,14 +26501,16 @@ function escapeJsonLd(value) {
26365
26501
  }
26366
26502
  function buildHead(pathname) {
26367
26503
  const page = getPageByPathname(pathname);
26368
- const frontmatter = (page ? getDocModule(page.filePath) : void 0)?.frontmatter;
26504
+ const standalone = page ? null : getStandalonePage(pathname);
26505
+ const filePath = page?.filePath || standalone?.filePath;
26506
+ const frontmatter = (filePath ? getDocModule(filePath) : void 0)?.frontmatter;
26369
26507
  const seo = getSeo();
26370
- const pageTitle = frontmatter?.title || page?.label;
26508
+ const pageTitle = frontmatter?.title || standalone?.title || page?.label;
26371
26509
  const title = getPageTitle(pageTitle);
26372
26510
  const description = frontmatter?.description || siteConfig.description;
26373
- const canonical = page ? toAbsoluteUrl(page.url) : void 0;
26511
+ const canonical = page ? toAbsoluteUrl(page.url) : standalone ? toAbsoluteUrl(standalone.path) : void 0;
26374
26512
  const hidden = !!page && (!!page.hidden || !!getScopeByPathname(pathname).hidden);
26375
- const noindex = !page || frontmatter?.noindex === true || hidden && seo.indexing !== "all";
26513
+ const noindex = !page && !standalone || frontmatter?.noindex === true || hidden && seo.indexing !== "all";
26376
26514
  const tags = [{
26377
26515
  tag: "title",
26378
26516
  children: title
@@ -26402,7 +26540,7 @@ function buildHead(pathname) {
26402
26540
  tag: "meta",
26403
26541
  attrs: {
26404
26542
  property: "og:type",
26405
- content: "article"
26543
+ content: standalone ? "website" : "article"
26406
26544
  }
26407
26545
  }, {
26408
26546
  tag: "meta",
@@ -26452,7 +26590,7 @@ function buildHead(pathname) {
26452
26590
  content: description
26453
26591
  }
26454
26592
  });
26455
- const lastModified = page && showTimestamp(frontmatter?.timestamp) ? getLastModified(page.filePath) : void 0;
26593
+ const lastModified = filePath && showTimestamp(frontmatter?.timestamp) ? getLastModified(filePath) : void 0;
26456
26594
  if (lastModified) tags.push({
26457
26595
  tag: "meta",
26458
26596
  attrs: {
@@ -26600,14 +26738,14 @@ function ContextualMenu({ options, labels }) {
26600
26738
  const optionIcon = (option, showCopied = false) => showCopied && copied ? /* @__PURE__ */ jsx(Check$1, { className: "size-3.5" }) : /* @__PURE__ */ jsx(ConfiguredIcon, { icon: option.icon });
26601
26739
  return /* @__PURE__ */ jsxs("div", {
26602
26740
  className: "inline-flex shrink-0 items-stretch",
26603
- children: [/* @__PURE__ */ jsxs(Button, {
26741
+ children: [/* @__PURE__ */ jsxs(Button$1, {
26604
26742
  variant: "outline",
26605
26743
  size: "sm",
26606
26744
  className: "rounded-r-none bg-card text-foreground only:rounded-md",
26607
26745
  onClick: () => runOption(primary),
26608
26746
  children: [optionIcon(primary, primary.action === "copy"), primary.action === "copy" && copied ? labels.copied : primary.title]
26609
26747
  }), options.length > 1 && /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
26610
- render: /* @__PURE__ */ jsx(Button, {
26748
+ render: /* @__PURE__ */ jsx(Button$1, {
26611
26749
  variant: "outline",
26612
26750
  size: "icon-sm",
26613
26751
  className: "rounded-l-none border-l-0 bg-card",
@@ -26694,13 +26832,13 @@ function DocContent({ page, doc, site }) {
26694
26832
  ...pagefindAttrs,
26695
26833
  children: [
26696
26834
  eyebrow && /* @__PURE__ */ jsx("div", {
26697
- className: "text-sm font-bold text-primary",
26835
+ className: "text-sm font-medium text-primary",
26698
26836
  children: eyebrow
26699
26837
  }),
26700
26838
  /* @__PURE__ */ jsxs("div", {
26701
26839
  className: "flex items-start justify-between gap-4",
26702
26840
  children: [title && /* @__PURE__ */ jsx("h1", {
26703
- className: "mt-2 text-4xl text-foreground leading-[1.2] tracking-[-0.03em] [font-family:var(--font-heading)] [font-weight:var(--font-heading-weight,800)]",
26841
+ className: "mt-2 text-4xl text-foreground leading-[1.2] tracking-[-0.03em] [font-family:var(--font-heading)] [font-weight:var(--font-heading-weight,700)]",
26704
26842
  children: title
26705
26843
  }), /* @__PURE__ */ jsx(ContextualMenu, {
26706
26844
  options: contextualOptions,
@@ -26708,7 +26846,7 @@ function DocContent({ page, doc, site }) {
26708
26846
  })]
26709
26847
  }),
26710
26848
  description && /* @__PURE__ */ jsx("p", {
26711
- className: "mt-1 mb-6 text-base text-muted-foreground",
26849
+ className: "mt-3 mb-8 text-lg text-muted-foreground leading-relaxed",
26712
26850
  children: description
26713
26851
  }),
26714
26852
  /* @__PURE__ */ jsx("div", {
@@ -26948,7 +27086,7 @@ function CollapsibleGroup({ node, pathname, depth, drilldown, expandLabel, colla
26948
27086
  className: isTopLevel ? sectionLabelClass : groupLabelClass,
26949
27087
  children: [resolveIcon(node.icon), node.label]
26950
27088
  }), /* @__PURE__ */ jsx(CollapsibleTrigger, {
26951
- render: /* @__PURE__ */ jsx(Button, {
27089
+ render: /* @__PURE__ */ jsx(Button$1, {
26952
27090
  type: "button",
26953
27091
  variant: "ghost",
26954
27092
  size: "icon-xs",
@@ -26958,7 +27096,7 @@ function CollapsibleGroup({ node, pathname, depth, drilldown, expandLabel, colla
26958
27096
  children: chevron
26959
27097
  })]
26960
27098
  }) : /* @__PURE__ */ jsxs(CollapsibleTrigger, {
26961
- render: /* @__PURE__ */ jsx(Button, {
27099
+ render: /* @__PURE__ */ jsx(Button$1, {
26962
27100
  type: "button",
26963
27101
  variant: "ghost",
26964
27102
  className: cn(headerClass, "group/section group/collapsible-trigger flex h-auto w-full items-center justify-start gap-[0.4rem] whitespace-normal rounded-none px-0 py-0 text-left hover:bg-transparent aria-expanded:bg-transparent dark:hover:bg-transparent", {
@@ -27119,7 +27257,7 @@ function SheetContent({ className, children, side = "right", showCloseButton = t
27119
27257
  ...props,
27120
27258
  children: [children, showCloseButton && /* @__PURE__ */ jsxs(DialogClose, {
27121
27259
  "data-slot": "sheet-close",
27122
- render: /* @__PURE__ */ jsx(Button, {
27260
+ render: /* @__PURE__ */ jsx(Button$1, {
27123
27261
  variant: "ghost",
27124
27262
  className: "absolute top-3 right-3",
27125
27263
  size: "icon-sm"
@@ -27185,7 +27323,7 @@ function Docs({ page, doc, site }) {
27185
27323
  children: [/* @__PURE__ */ jsx("div", {
27186
27324
  className: "flex justify-end lg:hidden",
27187
27325
  children: /* @__PURE__ */ jsxs(SheetTrigger, {
27188
- render: /* @__PURE__ */ jsx(Button, {
27326
+ render: /* @__PURE__ */ jsx(Button$1, {
27189
27327
  variant: "outline",
27190
27328
  className: "bg-card"
27191
27329
  }),
@@ -27277,6 +27415,40 @@ function DocPage({ site }) {
27277
27415
  });
27278
27416
  }
27279
27417
 
27418
+ //#endregion
27419
+ //#region src/pages/StandalonePage.tsx
27420
+ /**
27421
+ * A standalone (non-docs) page: site chrome from Layout (banner, header),
27422
+ * the MDX content at full container width — no sidebar, TOC, or pager — and
27423
+ * the footer. MDX components come from the app-level MDXProvider.
27424
+ */
27425
+ function StandalonePageView({ page, site }) {
27426
+ const { pathname } = useLocation();
27427
+ const doc = getDocModule(page.filePath);
27428
+ useEffect(() => {
27429
+ if (!window.location.hash) window.scrollTo({
27430
+ top: 0,
27431
+ left: 0
27432
+ });
27433
+ }, [pathname]);
27434
+ if (!doc) return /* @__PURE__ */ jsx(Docs, {
27435
+ page: null,
27436
+ doc: null,
27437
+ site
27438
+ });
27439
+ const Content = doc.default;
27440
+ return /* @__PURE__ */ jsxs("div", {
27441
+ className: "flex min-h-full flex-col",
27442
+ children: [/* @__PURE__ */ jsx("article", {
27443
+ className: "grow py-8",
27444
+ children: /* @__PURE__ */ jsx("div", {
27445
+ className: "docs-markdown",
27446
+ children: /* @__PURE__ */ jsx(Content, {})
27447
+ })
27448
+ }), /* @__PURE__ */ jsx(Footer, { footer: site.footer })]
27449
+ });
27450
+ }
27451
+
27280
27452
  //#endregion
27281
27453
  //#region src/App.tsx
27282
27454
  const mdxComponents = {
@@ -27289,19 +27461,29 @@ function App() {
27289
27461
  components: mdxComponents,
27290
27462
  children: /* @__PURE__ */ jsx(Layout, {
27291
27463
  site: siteModel,
27292
- children: /* @__PURE__ */ jsxs(Routes, { children: [docsHomeUrl !== "/" ? /* @__PURE__ */ jsx(Route, {
27293
- path: "/",
27294
- element: /* @__PURE__ */ jsx(Navigate, {
27295
- to: docsHomeUrl,
27296
- replace: true
27464
+ children: /* @__PURE__ */ jsxs(Routes, { children: [
27465
+ standalonePages.map((page) => /* @__PURE__ */ jsx(Route, {
27466
+ path: page.path,
27467
+ element: /* @__PURE__ */ jsx(StandalonePageView, {
27468
+ page,
27469
+ site: siteModel
27470
+ })
27471
+ }, page.path)),
27472
+ docsHomeUrl !== "/" && !hasRootStandalonePage ? /* @__PURE__ */ jsx(Route, {
27473
+ path: "/",
27474
+ element: /* @__PURE__ */ jsx(Navigate, {
27475
+ to: docsHomeUrl,
27476
+ replace: true
27477
+ })
27478
+ }) : null,
27479
+ /* @__PURE__ */ jsx(Route, {
27480
+ path: "*",
27481
+ element: /* @__PURE__ */ jsx(DocPage, { site: siteModel })
27297
27482
  })
27298
- }) : null, /* @__PURE__ */ jsx(Route, {
27299
- path: "*",
27300
- element: /* @__PURE__ */ jsx(DocPage, { site: siteModel })
27301
- })] })
27483
+ ] })
27302
27484
  })
27303
27485
  }) });
27304
27486
  }
27305
27487
 
27306
27488
  //#endregion
27307
- export { createPath as _, docsSite as a, getSeo as c, getLastModified as d, getScopeForPage as f, Router as g, BrowserRouter as h, docsHomeUrl as i, siteName as l, toAbsoluteUrl as m, buildHead as n, getLocaleByPathname as o, BASE_URL as p, renderHeadToString as r, getRedirects as s, App as t, getDocModule as u, parsePath as v, ABSOLUTE_URL_REGEX as y };
27489
+ export { Router as _, docsSite as a, ABSOLUTE_URL_REGEX as b, getSeo as c, getDocModule as d, getLastModified as f, BrowserRouter as g, toAbsoluteUrl as h, docsHomeUrl as i, siteName as l, BASE_URL as m, buildHead as n, getLocaleByPathname as o, getScopeForPage as p, renderHeadToString as r, getRedirects as s, App as t, standalonePages as u, createPath as v, parsePath as y };