@tenphi/renderer 0.20.4 → 0.21.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.
Files changed (44) hide show
  1. package/README.md +2 -2
  2. package/dist/client/navigation.js +2 -6
  3. package/dist/client/navigation.js.map +1 -1
  4. package/dist/client/popover-motion.d.ts +6 -0
  5. package/dist/client/popover-motion.d.ts.map +1 -0
  6. package/dist/client/popover-motion.js +14 -0
  7. package/dist/client/popover-motion.js.map +1 -0
  8. package/dist/client/search.js +55 -14
  9. package/dist/client/search.js.map +1 -1
  10. package/dist/components/GlobalStyles.js +97 -48
  11. package/dist/components/HeaderLinks.astro +14 -3
  12. package/dist/components/Icon.astro +1 -1
  13. package/dist/components/LayoutComponents.js +31 -40
  14. package/dist/components/Preview.astro +1 -1
  15. package/dist/components/SelectPopover.astro +64 -0
  16. package/dist/components/TastyComponents.js +16 -2
  17. package/dist/components/VersionSwitcher.astro +11 -18
  18. package/dist/components/component-styles.test.ts +4 -20
  19. package/dist/components/component-styles.ts +2 -22
  20. package/dist/components/select-popover-styles.js +107 -0
  21. package/dist/eslint-plugin.js +2 -2
  22. package/dist/eslint-plugin.js.map +1 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +6 -10
  25. package/dist/index.js.map +1 -1
  26. package/dist/localization.d.ts.map +1 -1
  27. package/dist/localization.js +19 -5
  28. package/dist/localization.js.map +1 -1
  29. package/dist/overrides/Head.astro +3 -0
  30. package/dist/overrides/Header.astro +8 -0
  31. package/dist/overrides/LanguageSelect.astro +29 -35
  32. package/dist/overrides/MobileMenuFooter.astro +1 -1
  33. package/dist/overrides/Search.astro +25 -1
  34. package/dist/overrides/ThemeSelect.astro +2 -0
  35. package/dist/routes/Page.astro +1 -0
  36. package/dist/styling.d.ts.map +1 -1
  37. package/dist/styling.js +1 -1
  38. package/dist/{tasty-states-BDKIbfw2.js → tasty-states-rTLFy26t.js} +5 -13
  39. package/dist/tasty-states-rTLFy26t.js.map +1 -0
  40. package/dist/ui.d.ts.map +1 -1
  41. package/dist/ui.js +2 -0
  42. package/dist/ui.js.map +1 -1
  43. package/package.json +2 -2
  44. package/dist/tasty-states-BDKIbfw2.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"localization.d.ts","names":[],"sources":["../src/localization.ts"],"mappings":";;;KAMK;EACH,UAAU;EACV,gBAAgB;EAChB,eAAe;;iBAGD,YAAY,cAAc,SAAS;;iBAMnC,gBACd,kBACA,cACA,SAAS;iBAWK,WAAW,cAAc,SAAS;iBAQlC,eACd,cACA,gBACA,SAAS;;iBASK,aACd,cACA,gBACA,QAAQ,aACR,SAAS;iBAoBK,WACd,cACA,qBACA,QAAQ,aACR,SAAS,eACT;;iBAec,oBACd,QAAQ,0BACR,QAAQ,aACR,qBACA,SAAS;EACN,QAAQ;EAA0B,QAAQ;;cAiElC;WACX;WACA;WACA;WACA;WACA;WACA;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;KAEU,0BAA0B;iBA0CtB,SACd,cACA,UAAS,gBACR,OAAO;iBAUM,iBACd,cACA,QAAQ,aACR,SAAS,gBACR;EAAQ;EAAc"}
1
+ {"version":3,"file":"localization.d.ts","names":[],"sources":["../src/localization.ts"],"mappings":";;;KAMK;EACH,UAAU;EACV,gBAAgB;EAChB,eAAe;;iBAGD,YAAY,cAAc,SAAS;;iBAMnC,gBACd,kBACA,cACA,SAAS;iBAWK,WAAW,cAAc,SAAS;iBAQlC,eACd,cACA,gBACA,SAAS;;iBASK,aACd,cACA,gBACA,QAAQ,aACR,SAAS;iBAoBK,WACd,cACA,qBACA,QAAQ,aACR,SAAS,eACT;;iBAec,oBACd,QAAQ,0BACR,QAAQ,aACR,qBACA,SAAS;EACN,QAAQ;EAA0B,QAAQ;;cA8FlC;WACX;WACA;WACA;WACA;WACA;WACA;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;KAEU,0BAA0B;iBA0CtB,SACd,cACA,UAAS,gBACR,OAAO;iBAUM,iBACd,cACA,QAAQ,aACR,SAAS,gBACR;EAAQ;EAAc"}
@@ -51,24 +51,38 @@ function localizedNavigation(layout, routes, currentPath, options) {
51
51
  route: localePath(route.route, options)
52
52
  }));
53
53
  const available = new Set(localRoutes.filter((route) => route.discoverable !== false).map((route) => route.route));
54
+ const visibleRoutes = new Map(routes.filter((route) => route.discoverable !== false).map((route) => [route.route, route]));
55
+ const fallbackLocale = options.defaultLocale ?? (options.locales.root ? "root" : Object.keys(options.locales)[0]);
54
56
  const convert = (items) => items.flatMap((item) => {
55
57
  const link = typeof item === "string" ? item : item.link;
56
58
  const internal = link?.startsWith("/") && !link.startsWith("//");
57
59
  const translated = internal ? localePath(link, options) : link;
58
- if (typeof item === "string") return !internal || available.has(translated) ? [translated] : [];
60
+ const fallback = internal ? localizedRoute(link, fallbackLocale, options) : void 0;
61
+ const target = !internal || available.has(translated) ? translated : fallback && visibleRoutes.has(fallback) ? fallback : void 0;
62
+ if (typeof item === "string") {
63
+ if (!target) return [];
64
+ if (!internal || available.has(translated)) return [target];
65
+ const route = visibleRoutes.get(target);
66
+ return [{
67
+ label: typeof route.sidebar === "object" && route.sidebar.label ? route.sidebar.label : route.title,
68
+ link: target
69
+ }];
70
+ }
59
71
  if ("items" in item || "autogenerate" in item) {
60
72
  const { link: _link, ...group } = item;
73
+ const children = "items" in item ? convert(item.items) : void 0;
74
+ if (children?.length === 0 && !target) return [];
61
75
  return [{
62
76
  ...group,
63
77
  label: label(group.label),
64
- ...translated && (!internal || available.has(translated)) ? { link: translated } : {},
65
- ..."items" in item ? { items: convert(item.items) } : { autogenerate: { directory: localePath(item.autogenerate.directory, options) } }
78
+ ...target ? { link: target } : {},
79
+ ..."items" in item ? { items: children } : { autogenerate: { directory: localePath(item.autogenerate.directory, options) } }
66
80
  }];
67
81
  }
68
- return !internal || available.has(translated) ? [{
82
+ return target ? [{
69
83
  ...item,
70
84
  label: label(item.label),
71
- link: translated
85
+ link: target
72
86
  }] : [];
73
87
  });
74
88
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"localization.js","names":[],"sources":["../src/localization.ts"],"sourcesContent":["import type { DocsConfig, DocsRoute, NavigationItem } from \"@tenphi/docs\";\nimport {\n normalizeNavigationPath,\n type ResolvedNavigationLayout,\n} from \"./navigation.js\";\n\ntype LocaleOptions = {\n locales?: DocsConfig[\"locales\"] | undefined;\n defaultLocale?: DocsConfig[\"defaultLocale\"] | undefined;\n translations?: DocsConfig[\"translations\"] | undefined;\n};\n\nexport function routeLocale(path: string, options: LocaleOptions): string {\n const first = normalizeNavigationPath(path).split(\"/\")[1];\n return first && first !== \"root\" && options.locales?.[first] ? first : \"root\";\n}\n\n/** Author components can render before the page initializes route locals. */\nexport function requestLanguage(\n pathname: string,\n base: string,\n options: LocaleOptions,\n): string {\n const prefix = base.replace(/\\/$/, \"\");\n const path =\n prefix && (pathname === prefix || pathname.startsWith(`${prefix}/`))\n ? pathname.slice(prefix.length)\n : pathname;\n const locale = routeLocale(path, options);\n return options.locales?.[locale]?.lang ?? (locale === \"root\" ? \"en\" : locale);\n}\n\nexport function localePath(path: string, options: LocaleOptions): string {\n const route = normalizeNavigationPath(path);\n const locale = routeLocale(route, options);\n return locale === \"root\"\n ? route\n : normalizeNavigationPath(route.slice(locale.length + 1));\n}\n\nexport function localizedRoute(\n path: string,\n locale: string,\n options: LocaleOptions,\n): string {\n const suffix = localePath(path, options);\n return normalizeNavigationPath(\n `${locale === \"root\" ? \"\" : `/${locale}`}${suffix}`,\n );\n}\n\n/** Missing translations use a real default-language page, then a real locale home. */\nexport function localeTarget(\n path: string,\n locale: string,\n routes: DocsRoute[],\n options: LocaleOptions,\n): string | undefined {\n const visible = new Set(\n routes\n .filter((route) => route.discoverable !== false)\n .map((route) => route.route),\n );\n const fallback =\n options.defaultLocale ??\n (options.locales?.root\n ? \"root\"\n : (Object.keys(options.locales ?? {})[0] ?? \"root\"));\n return [\n localizedRoute(path, locale, options),\n localizedRoute(path, fallback, options),\n localizedRoute(\"/\", locale, options),\n localizedRoute(\"/\", fallback, options),\n ].find((route) => visible.has(route));\n}\n\nexport function localeHref(\n link: string,\n currentPath: string,\n routes: DocsRoute[],\n options: LocaleOptions,\n base = \"/\",\n): string {\n if (!link.startsWith(\"/\") || link.startsWith(\"//\")) return link;\n const suffix = /[?#].*$/.exec(link)?.[0] ?? \"\";\n const path = suffix ? link.slice(0, -suffix.length) : link;\n const target = options.locales\n ? localeTarget(path, routeLocale(currentPath, options), routes, options)\n : normalizeNavigationPath(path);\n return (\n `${base.replace(/\\/$/, \"\")}${target ?? normalizeNavigationPath(path)}${suffix}` ||\n \"/\"\n );\n}\n\n/** Resolve navigation against the current locale's available routes. */\nexport function localizedNavigation(\n layout: ResolvedNavigationLayout,\n routes: DocsRoute[],\n currentPath: string,\n options: LocaleOptions,\n): { layout: ResolvedNavigationLayout; routes: DocsRoute[] } {\n if (!options.locales) return { layout, routes };\n const locale = routeLocale(currentPath, options);\n const language =\n options.locales[locale]?.lang ?? (locale === \"root\" ? \"en\" : locale);\n const label = (value: string) =>\n options.translations?.[language]?.[`navigation.${value}`] ??\n options.translations?.[language.split(\"-\")[0]!]?.[`navigation.${value}`] ??\n value;\n const localRoutes = routes\n .filter((route) => routeLocale(route.route, options) === locale)\n .map((route) => ({ ...route, route: localePath(route.route, options) }));\n const available = new Set(\n localRoutes\n .filter((route) => route.discoverable !== false)\n .map((route) => route.route),\n );\n const convert = (items: NavigationItem[]): NavigationItem[] =>\n items.flatMap((item): NavigationItem[] => {\n const link = typeof item === \"string\" ? item : item.link;\n const internal = link?.startsWith(\"/\") && !link.startsWith(\"//\");\n const translated = internal ? localePath(link!, options) : link;\n if (typeof item === \"string\")\n return !internal || available.has(translated!) ? [translated!] : [];\n if (\"items\" in item || \"autogenerate\" in item) {\n const { link: _link, ...group } = item;\n return [\n {\n ...group,\n label: label(group.label),\n ...(translated && (!internal || available.has(translated))\n ? { link: translated }\n : {}),\n ...(\"items\" in item\n ? { items: convert(item.items) }\n : {\n autogenerate: {\n directory: localePath(item.autogenerate.directory, options),\n },\n }),\n },\n ];\n }\n return !internal || available.has(translated!)\n ? [{ ...item, label: label(item.label), link: translated! }]\n : [];\n });\n return {\n layout: {\n ...layout,\n ...(layout.items ? { items: convert(layout.items) } : {}),\n tabs: layout.tabs.map((tab) => ({\n ...tab,\n label: label(tab.label),\n link:\n tab.link.startsWith(\"/\") && !tab.link.startsWith(\"//\")\n ? localePath(tab.link, options)\n : tab.link,\n ...(tab.items ? { items: convert(tab.items) } : {}),\n })),\n },\n routes: localRoutes,\n };\n}\n\nexport const ENGLISH_MESSAGES = {\n copyPage: \"Copy page\",\n viewMarkdown: \"Download Markdown\",\n pageCopied: \"Page copied\",\n pageCopyError: \"Could not copy. Download Markdown to read or copy the text.\",\n draftTitle: \"Draft\",\n draftNotice:\n \"This page is available by direct link and excluded from navigation and indexes.\",\n searchError: \"Search could not load. Close and try again.\",\n appearance: \"Appearance\",\n colorScheme: \"Color scheme\",\n contrast: \"Contrast\",\n normalContrast: \"Normal\",\n highContrast: \"High\",\n auto: \"Auto\",\n closeNavigation: \"Close navigation\",\n primary: \"Primary\",\n sections: \"Sections\",\n chooseSection: \"Choose section\",\n headerLinks: \"Header links\",\n more: \"More\",\n closeMore: \"Close more menu\",\n moreLinks: \"More links\",\n versions: \"Versions\",\n documentationVersion: \"Documentation version\",\n documentationVersions: \"Documentation versions\",\n version: \"Version\",\n home: \"Home\",\n generatedWith: \"Generated with\",\n viewSource: \"View source\",\n copyCode: \"Copy code\",\n codeCopied: \"Code copied\",\n codeCopyError: \"Could not copy code\",\n copyHeading: \"Copy link to “{heading}”\",\n linkCopied: \"Link copied\",\n linkCopyError: \"Could not copy link\",\n notFound: \"Page not found\",\n notFoundDescription: \"The page you requested could not be found.\",\n fallback: \"fallback\",\n} as const;\nexport type MessageKey = keyof typeof ENGLISH_MESSAGES;\nconst FRENCH_MESSAGES: Record<MessageKey, string> = {\n copyPage: \"Copier la page\",\n viewMarkdown: \"Télécharger le Markdown\",\n pageCopied: \"Page copiée\",\n pageCopyError:\n \"Copie impossible. Téléchargez le Markdown pour lire ou copier le texte.\",\n draftTitle: \"Brouillon\",\n draftNotice:\n \"Cette page est accessible par son lien direct et exclue de la navigation et des index.\",\n searchError: \"La recherche n’a pas pu se charger. Fermez et réessayez.\",\n appearance: \"Apparence\",\n colorScheme: \"Thème de couleur\",\n contrast: \"Contraste\",\n normalContrast: \"Normal\",\n highContrast: \"Élevé\",\n auto: \"Auto\",\n closeNavigation: \"Fermer la navigation\",\n primary: \"Navigation principale\",\n sections: \"Sections\",\n chooseSection: \"Choisir une section\",\n headerLinks: \"Liens d’en-tête\",\n more: \"Plus\",\n closeMore: \"Fermer le menu\",\n moreLinks: \"Autres liens\",\n versions: \"Versions\",\n documentationVersion: \"Version de la documentation\",\n documentationVersions: \"Versions de la documentation\",\n version: \"Version\",\n home: \"Accueil\",\n generatedWith: \"Créé avec\",\n viewSource: \"Voir le code source\",\n copyCode: \"Copier le code\",\n codeCopied: \"Code copié\",\n codeCopyError: \"Impossible de copier le code\",\n copyHeading: \"Copier le lien vers « {heading} »\",\n linkCopied: \"Lien copié\",\n linkCopyError: \"Impossible de copier le lien\",\n notFound: \"Page introuvable\",\n notFoundDescription: \"La page demandée est introuvable.\",\n fallback: \"langue de secours\",\n};\nexport function messages(\n lang: string,\n options: LocaleOptions = {},\n): Record<MessageKey, string> {\n const language = lang.split(\"-\")[0] ?? \"en\";\n return {\n ...ENGLISH_MESSAGES,\n ...(language === \"fr\" ? FRENCH_MESSAGES : {}),\n ...options.translations?.[language],\n ...options.translations?.[lang],\n };\n}\n\nexport function localeAlternates(\n path: string,\n routes: DocsRoute[],\n options: LocaleOptions,\n): Array<{ lang: string; route: string }> {\n const available = new Set(\n routes\n .filter((route) => route.discoverable !== false)\n .map((route) => route.route),\n );\n if (!options.locales || !available.has(path)) return [];\n const alternates = Object.entries(options.locales).flatMap(\n ([locale, config]) => {\n const route = localizedRoute(path, locale, options);\n return available.has(route)\n ? [{ lang: config.lang ?? locale, route }]\n : [];\n },\n );\n const fallback = localizedRoute(\n path,\n options.defaultLocale ??\n (options.locales.root ? \"root\" : Object.keys(options.locales)[0]!),\n options,\n );\n if (available.has(fallback))\n alternates.push({ lang: \"x-default\", route: fallback });\n return alternates;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"localization.js","names":[],"sources":["../src/localization.ts"],"sourcesContent":["import type { DocsConfig, DocsRoute, NavigationItem } from \"@tenphi/docs\";\nimport {\n normalizeNavigationPath,\n type ResolvedNavigationLayout,\n} from \"./navigation.js\";\n\ntype LocaleOptions = {\n locales?: DocsConfig[\"locales\"] | undefined;\n defaultLocale?: DocsConfig[\"defaultLocale\"] | undefined;\n translations?: DocsConfig[\"translations\"] | undefined;\n};\n\nexport function routeLocale(path: string, options: LocaleOptions): string {\n const first = normalizeNavigationPath(path).split(\"/\")[1];\n return first && first !== \"root\" && options.locales?.[first] ? first : \"root\";\n}\n\n/** Author components can render before the page initializes route locals. */\nexport function requestLanguage(\n pathname: string,\n base: string,\n options: LocaleOptions,\n): string {\n const prefix = base.replace(/\\/$/, \"\");\n const path =\n prefix && (pathname === prefix || pathname.startsWith(`${prefix}/`))\n ? pathname.slice(prefix.length)\n : pathname;\n const locale = routeLocale(path, options);\n return options.locales?.[locale]?.lang ?? (locale === \"root\" ? \"en\" : locale);\n}\n\nexport function localePath(path: string, options: LocaleOptions): string {\n const route = normalizeNavigationPath(path);\n const locale = routeLocale(route, options);\n return locale === \"root\"\n ? route\n : normalizeNavigationPath(route.slice(locale.length + 1));\n}\n\nexport function localizedRoute(\n path: string,\n locale: string,\n options: LocaleOptions,\n): string {\n const suffix = localePath(path, options);\n return normalizeNavigationPath(\n `${locale === \"root\" ? \"\" : `/${locale}`}${suffix}`,\n );\n}\n\n/** Missing translations use a real default-language page, then a real locale home. */\nexport function localeTarget(\n path: string,\n locale: string,\n routes: DocsRoute[],\n options: LocaleOptions,\n): string | undefined {\n const visible = new Set(\n routes\n .filter((route) => route.discoverable !== false)\n .map((route) => route.route),\n );\n const fallback =\n options.defaultLocale ??\n (options.locales?.root\n ? \"root\"\n : (Object.keys(options.locales ?? {})[0] ?? \"root\"));\n return [\n localizedRoute(path, locale, options),\n localizedRoute(path, fallback, options),\n localizedRoute(\"/\", locale, options),\n localizedRoute(\"/\", fallback, options),\n ].find((route) => visible.has(route));\n}\n\nexport function localeHref(\n link: string,\n currentPath: string,\n routes: DocsRoute[],\n options: LocaleOptions,\n base = \"/\",\n): string {\n if (!link.startsWith(\"/\") || link.startsWith(\"//\")) return link;\n const suffix = /[?#].*$/.exec(link)?.[0] ?? \"\";\n const path = suffix ? link.slice(0, -suffix.length) : link;\n const target = options.locales\n ? localeTarget(path, routeLocale(currentPath, options), routes, options)\n : normalizeNavigationPath(path);\n return (\n `${base.replace(/\\/$/, \"\")}${target ?? normalizeNavigationPath(path)}${suffix}` ||\n \"/\"\n );\n}\n\n/** Resolve navigation against the current locale's available routes. */\nexport function localizedNavigation(\n layout: ResolvedNavigationLayout,\n routes: DocsRoute[],\n currentPath: string,\n options: LocaleOptions,\n): { layout: ResolvedNavigationLayout; routes: DocsRoute[] } {\n if (!options.locales) return { layout, routes };\n const locale = routeLocale(currentPath, options);\n const language =\n options.locales[locale]?.lang ?? (locale === \"root\" ? \"en\" : locale);\n const label = (value: string) =>\n options.translations?.[language]?.[`navigation.${value}`] ??\n options.translations?.[language.split(\"-\")[0]!]?.[`navigation.${value}`] ??\n value;\n const localRoutes = routes\n .filter((route) => routeLocale(route.route, options) === locale)\n .map((route) => ({ ...route, route: localePath(route.route, options) }));\n const available = new Set(\n localRoutes\n .filter((route) => route.discoverable !== false)\n .map((route) => route.route),\n );\n const visibleRoutes = new Map(\n routes\n .filter((route) => route.discoverable !== false)\n .map((route) => [route.route, route]),\n );\n const fallbackLocale =\n options.defaultLocale ??\n (options.locales.root ? \"root\" : Object.keys(options.locales)[0]!);\n const convert = (items: NavigationItem[]): NavigationItem[] =>\n items.flatMap((item): NavigationItem[] => {\n const link = typeof item === \"string\" ? item : item.link;\n const internal = link?.startsWith(\"/\") && !link.startsWith(\"//\");\n const translated = internal ? localePath(link!, options) : link;\n const fallback = internal\n ? localizedRoute(link!, fallbackLocale, options)\n : undefined;\n const target =\n !internal || available.has(translated!)\n ? translated\n : fallback && visibleRoutes.has(fallback)\n ? fallback\n : undefined;\n if (typeof item === \"string\") {\n if (!target) return [];\n if (!internal || available.has(translated!)) return [target];\n const route = visibleRoutes.get(target)!;\n return [\n {\n label:\n typeof route.sidebar === \"object\" && route.sidebar.label\n ? route.sidebar.label\n : route.title,\n link: target,\n },\n ];\n }\n if (\"items\" in item || \"autogenerate\" in item) {\n const { link: _link, ...group } = item;\n const children = \"items\" in item ? convert(item.items) : undefined;\n if (children?.length === 0 && !target) return [];\n return [\n {\n ...group,\n label: label(group.label),\n ...(target ? { link: target } : {}),\n ...(\"items\" in item\n ? { items: children! }\n : {\n autogenerate: {\n directory: localePath(item.autogenerate.directory, options),\n },\n }),\n },\n ];\n }\n return target\n ? [{ ...item, label: label(item.label), link: target }]\n : [];\n });\n return {\n layout: {\n ...layout,\n ...(layout.items ? { items: convert(layout.items) } : {}),\n tabs: layout.tabs.map((tab) => ({\n ...tab,\n label: label(tab.label),\n link:\n tab.link.startsWith(\"/\") && !tab.link.startsWith(\"//\")\n ? localePath(tab.link, options)\n : tab.link,\n ...(tab.items ? { items: convert(tab.items) } : {}),\n })),\n },\n routes: localRoutes,\n };\n}\n\nexport const ENGLISH_MESSAGES = {\n copyPage: \"Copy page\",\n viewMarkdown: \"Download Markdown\",\n pageCopied: \"Page copied\",\n pageCopyError: \"Could not copy. Download Markdown to read or copy the text.\",\n draftTitle: \"Draft\",\n draftNotice:\n \"This page is available by direct link and excluded from navigation and indexes.\",\n searchError: \"Search could not load. Close and try again.\",\n appearance: \"Appearance\",\n colorScheme: \"Color scheme\",\n contrast: \"Contrast\",\n normalContrast: \"Normal\",\n highContrast: \"High\",\n auto: \"Auto\",\n closeNavigation: \"Close navigation\",\n primary: \"Primary\",\n sections: \"Sections\",\n chooseSection: \"Choose section\",\n headerLinks: \"Header links\",\n more: \"More\",\n closeMore: \"Close more menu\",\n moreLinks: \"More links\",\n versions: \"Versions\",\n documentationVersion: \"Documentation version\",\n documentationVersions: \"Documentation versions\",\n version: \"Version\",\n home: \"Home\",\n generatedWith: \"Generated with\",\n viewSource: \"View source\",\n copyCode: \"Copy code\",\n codeCopied: \"Code copied\",\n codeCopyError: \"Could not copy code\",\n copyHeading: \"Copy link to “{heading}”\",\n linkCopied: \"Link copied\",\n linkCopyError: \"Could not copy link\",\n notFound: \"Page not found\",\n notFoundDescription: \"The page you requested could not be found.\",\n fallback: \"fallback\",\n} as const;\nexport type MessageKey = keyof typeof ENGLISH_MESSAGES;\nconst FRENCH_MESSAGES: Record<MessageKey, string> = {\n copyPage: \"Copier la page\",\n viewMarkdown: \"Télécharger le Markdown\",\n pageCopied: \"Page copiée\",\n pageCopyError:\n \"Copie impossible. Téléchargez le Markdown pour lire ou copier le texte.\",\n draftTitle: \"Brouillon\",\n draftNotice:\n \"Cette page est accessible par son lien direct et exclue de la navigation et des index.\",\n searchError: \"La recherche n’a pas pu se charger. Fermez et réessayez.\",\n appearance: \"Apparence\",\n colorScheme: \"Thème de couleur\",\n contrast: \"Contraste\",\n normalContrast: \"Normal\",\n highContrast: \"Élevé\",\n auto: \"Auto\",\n closeNavigation: \"Fermer la navigation\",\n primary: \"Navigation principale\",\n sections: \"Sections\",\n chooseSection: \"Choisir une section\",\n headerLinks: \"Liens d’en-tête\",\n more: \"Plus\",\n closeMore: \"Fermer le menu\",\n moreLinks: \"Autres liens\",\n versions: \"Versions\",\n documentationVersion: \"Version de la documentation\",\n documentationVersions: \"Versions de la documentation\",\n version: \"Version\",\n home: \"Accueil\",\n generatedWith: \"Créé avec\",\n viewSource: \"Voir le code source\",\n copyCode: \"Copier le code\",\n codeCopied: \"Code copié\",\n codeCopyError: \"Impossible de copier le code\",\n copyHeading: \"Copier le lien vers « {heading} »\",\n linkCopied: \"Lien copié\",\n linkCopyError: \"Impossible de copier le lien\",\n notFound: \"Page introuvable\",\n notFoundDescription: \"La page demandée est introuvable.\",\n fallback: \"langue de secours\",\n};\nexport function messages(\n lang: string,\n options: LocaleOptions = {},\n): Record<MessageKey, string> {\n const language = lang.split(\"-\")[0] ?? \"en\";\n return {\n ...ENGLISH_MESSAGES,\n ...(language === \"fr\" ? FRENCH_MESSAGES : {}),\n ...options.translations?.[language],\n ...options.translations?.[lang],\n };\n}\n\nexport function localeAlternates(\n path: string,\n routes: DocsRoute[],\n options: LocaleOptions,\n): Array<{ lang: string; route: string }> {\n const available = new Set(\n routes\n .filter((route) => route.discoverable !== false)\n .map((route) => route.route),\n );\n if (!options.locales || !available.has(path)) return [];\n const alternates = Object.entries(options.locales).flatMap(\n ([locale, config]) => {\n const route = localizedRoute(path, locale, options);\n return available.has(route)\n ? [{ lang: config.lang ?? locale, route }]\n : [];\n },\n );\n const fallback = localizedRoute(\n path,\n options.defaultLocale ??\n (options.locales.root ? \"root\" : Object.keys(options.locales)[0]!),\n options,\n );\n if (available.has(fallback))\n alternates.push({ lang: \"x-default\", route: fallback });\n return alternates;\n}\n"],"mappings":"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"}
@@ -14,6 +14,9 @@ const head = (
14
14
  ]
15
15
  ).filter(
16
16
  (tag) =>
17
+ !(
18
+ tag.tag === "meta" && String(tag.attrs?.name).toLowerCase() === "viewport"
19
+ ) &&
17
20
  (tag.tag !== "link" ||
18
21
  tag.attrs?.rel !== "sitemap" ||
19
22
  content.routes.some((route) => route.sitemap !== false)) &&
@@ -107,6 +107,14 @@ const ui = messages(Astro.locals.cookbookRoute?.lang ?? "en", content);
107
107
  >
108
108
  <ThemeSelect />
109
109
  </div>
110
+ {
111
+ !Astro.locals.cookbookRoute.hasSidebar &&
112
+ Object.keys(content.locales ?? {}).length > 1 && (
113
+ <div class="td-header__mobile-language cookbook-print-hidden">
114
+ <LanguageSelect compact />
115
+ </div>
116
+ )
117
+ }
110
118
  <div
111
119
  class="td-header__tools cookbook-hidden md:cookbook-flex cookbook-print-hidden"
112
120
  >
@@ -2,10 +2,16 @@
2
2
  import { content } from "virtual:cookbook/config";
3
3
  import { localeTarget, routeLocale, messages } from "../localization.js";
4
4
  import { navigationPath } from "../navigation.js";
5
- import Icon from "../components/Icon.astro";
5
+ import SelectPopover from "../components/SelectPopover.astro";
6
+ interface Props {
7
+ compact?: boolean;
8
+ sidebar?: boolean;
9
+ }
10
+ const { compact = false, sidebar = false } = Astro.props;
6
11
  const current = navigationPath(Astro.url.pathname, content.base);
7
12
  const selected = routeLocale(current, content);
8
13
  const ui = messages(Astro.locals.cookbookRoute.lang, content);
14
+ const accessibleLabel = Astro.locals.t("languageSelect.accessibleLabel");
9
15
  const options = Object.entries(content.locales ?? {}).flatMap(
10
16
  ([locale, config]) => {
11
17
  const target = localeTarget(current, locale, content.routes, content);
@@ -14,50 +20,38 @@ const options = Object.entries(content.locales ?? {}).flatMap(
14
20
  ? [
15
21
  {
16
22
  locale,
17
- label: `${config.label}${fallback ? ` (${ui.fallback})` : ""}`,
23
+ label: config.label,
24
+ lang: config.lang ?? (locale === "root" ? "en" : locale),
25
+ fallback,
18
26
  href: `${content.base.replace(/\/$/, "")}${target === "/" ? "/" : `${target}/`}`,
19
27
  },
20
28
  ]
21
29
  : [];
22
30
  },
23
31
  );
32
+ const selectedOption = options.find((option) => option.locale === selected);
24
33
  ---
25
34
 
26
35
  {
27
36
  options.length > 1 && (
28
- <cookbook-language-select>
29
- <label>
30
- <Icon name="translate" class="label-icon" />
31
- <span class="sr-only">
32
- {Astro.locals.t("languageSelect.accessibleLabel")}
33
- </span>
34
- <select>
35
- {options.map((option) => (
36
- <option value={option.href} selected={option.locale === selected}>
37
- {option.label}
38
- </option>
39
- ))}
40
- </select>
41
- <Icon name="down-caret" class="caret" />
42
- </label>
37
+ <cookbook-language-select
38
+ data-compact={compact ? "" : undefined}
39
+ data-sidebar={sidebar ? "" : undefined}
40
+ data-tasty-anatomy="LanguageSelect"
41
+ >
42
+ <SelectPopover
43
+ triggerLabel={`${accessibleLabel}: ${selectedOption?.label ?? ""}`}
44
+ selectedLabel={selectedOption?.label ?? ""}
45
+ title={accessibleLabel}
46
+ icon="translate"
47
+ options={options.map((option) => ({
48
+ href: option.href,
49
+ label: option.label,
50
+ lang: option.lang,
51
+ hint: option.fallback ? ui.fallback : undefined,
52
+ current: option.locale === selected,
53
+ }))}
54
+ />
43
55
  </cookbook-language-select>
44
56
  )
45
57
  }
46
-
47
- <script>
48
- class CookbookLanguageSelect extends HTMLElement {
49
- connectedCallback() {
50
- const select = this.querySelector("select");
51
- select?.addEventListener("change", () => {
52
- window.location.href = select.value;
53
- });
54
- window.addEventListener("pageshow", () => {
55
- if (select)
56
- select.selectedIndex =
57
- select.querySelector("option[selected]")?.index ?? 0;
58
- });
59
- }
60
- }
61
- if (!customElements.get("cookbook-language-select"))
62
- customElements.define("cookbook-language-select", CookbookLanguageSelect);
63
- </script>
@@ -11,5 +11,5 @@ import { MobileMenuFooterRoot } from "../components/LayoutComponents.js";
11
11
  <div class="td-mobile-preferences__social">
12
12
  <SocialIcons />
13
13
  </div>
14
- <LanguageSelect />
14
+ <LanguageSelect sidebar />
15
15
  </MobileMenuFooterRoot>
@@ -45,7 +45,31 @@ const translations = {
45
45
  ) : (
46
46
  <div class="search-container">
47
47
  <p data-search-status role="status" hidden />
48
- <div id="cookbook__search" />
48
+ <div id="cookbook__search">
49
+ <div class="pagefind-ui" role="search" aria-label={label}>
50
+ <div class="cookbook-search-field">
51
+ <input
52
+ class="cookbook-search-input"
53
+ data-search-input
54
+ type="text"
55
+ aria-label={label}
56
+ placeholder={label}
57
+ autocapitalize="none"
58
+ autocomplete="off"
59
+ enterkeyhint="search"
60
+ autofocus
61
+ />
62
+ <button
63
+ class="cookbook-search-clear"
64
+ data-clear-search
65
+ type="button"
66
+ aria-label={Astro.locals.t("pagefind.clear_search")}
67
+ hidden
68
+ />
69
+ </div>
70
+ <div data-search-results />
71
+ </div>
72
+ </div>
49
73
  </div>
50
74
  )
51
75
  }
@@ -82,6 +82,7 @@ const contrasts = [
82
82
  parseScheme,
83
83
  parseContrast,
84
84
  } from "../components/appearance-preferences.js";
85
+ import { initializePopoverMotion } from "../client/popover-motion.js";
85
86
 
86
87
  let current = loadPreferences();
87
88
  const systemScheme = matchMedia("(prefers-color-scheme: light)");
@@ -127,6 +128,7 @@ const contrasts = [
127
128
  connectedCallback(): void {
128
129
  if (this.dataset.ready) return;
129
130
  this.dataset.ready = "true";
131
+ initializePopoverMotion(this.querySelector<HTMLElement>("[popover]")!);
130
132
  this.addEventListener("change", (event) => {
131
133
  const input = event.target;
132
134
  if (!(input instanceof HTMLInputElement)) return;
@@ -43,6 +43,7 @@ const indexed = route.id !== "/404" && data.pagefind !== false && !data.draft;
43
43
  >
44
44
  <head>
45
45
  <meta charset="utf-8" />
46
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
46
47
  <Head />
47
48
  </head>
48
49
  <body>
@@ -1 +1 @@
1
- {"version":3,"file":"styling.d.ts","names":[],"sources":["../src/define-component.ts","../src/components/component-styles.ts"],"mappings":";;;;KAoBK,cAAc,mBAAmB,8BACpC,4BACI,aACA;EAAqB,WAAW;IAC9B,kBAAkB,IAAI,oBACpB;KAKL,YAAY,UAAU,yBACxB,cAAc,IAAI,0BACjB,gBAAgB,gBAAgB,cAAc,EAAE,WAC9C,cACE,cAAc,EAAE,qBAAqB,wBACjC,sBAAsB,cAAc,EAAE;;iBAOlC,gBACd,0BAA0B,oBAC1B,UAAU,YACV,UAAU,qBAAqB,uBAC/B,eAAe,qBACf,UAAU,kCACV,WAAW,oCAEX,cACA,SAAS,oBAAoB,GAAG,GAAG,GAAG,QAAQ,GAAG,MAChD,0BAA0B,QAAQ,GAAG,GAAG,GAAG,MAAM,YAAY;;;;iBCjChD,uBACd,cACA,YAAY,WACX"}
1
+ {"version":3,"file":"styling.d.ts","names":[],"sources":["../src/define-component.ts","../src/components/component-styles.ts"],"mappings":";;;;KAoBK,cAAc,mBAAmB,8BACpC,4BACI,aACA;EAAqB,WAAW;IAC9B,kBAAkB,IAAI,oBACpB;KAKL,YAAY,UAAU,yBACxB,cAAc,IAAI,0BACjB,gBAAgB,gBAAgB,cAAc,EAAE,WAC9C,cACE,cAAc,EAAE,qBAAqB,wBACjC,sBAAsB,cAAc,EAAE;;iBAOlC,gBACd,0BAA0B,oBAC1B,UAAU,YACV,UAAU,qBAAqB,uBAC/B,eAAe,qBACf,UAAU,kCACV,WAAW,oCAEX,cACA,SAAS,oBAAoB,GAAG,GAAG,GAAG,QAAQ,GAAG,MAChD,0BAA0B,QAAQ,GAAG,GAAG,GAAG,MAAM,YAAY;;;;iBCnChD,uBACd,cACA,YAAY,WACX"}
package/dist/styling.js CHANGED
@@ -1,4 +1,4 @@
1
- import { i as resolveComponentStyles, t as configureCookbookStates } from "./tasty-states-BDKIbfw2.js";
1
+ import { i as resolveComponentStyles, t as configureCookbookStates } from "./tasty-states-rTLFy26t.js";
2
2
  import { mergeStyles, tasty, tasty as tasty$1, useGlobalStyles } from "@tenphi/tasty";
3
3
  //#region src/define-component.ts
4
4
  /** Create a named Tasty component with theme.styles[name] merged into its defaults. */
@@ -1,11 +1,9 @@
1
1
  import { resolveTypographyPresets } from "./theme/defaults.js";
2
2
  import { TASTY_UNITS } from "./theme/tasty-config.js";
3
- import { COOKBOOK_COMPONENT_NAMES } from "@tenphi/docs";
4
3
  import { mergeStyles } from "@tenphi/tasty/core";
5
4
  import { configure as configure$1, getGlobalPredefinedStates } from "@tenphi/tasty";
6
5
  //#region src/components/component-styles.ts
7
6
  const sharedConfiguration = globalThis;
8
- const cookbookComponentNames = new Set(COOKBOOK_COMPONENT_NAMES);
9
7
  function configureComponentStyles(styles) {
10
8
  sharedConfiguration.__tenphiCookbookComponentStyles = styles ?? {};
11
9
  sharedConfiguration.__tenphiCookbookUsedComponentStyles = /* @__PURE__ */ new Set();
@@ -16,15 +14,9 @@ function resolveComponentStyles(name, baseStyles) {
16
14
  const configuredStyles = sharedConfiguration.__tenphiCookbookComponentStyles?.[name];
17
15
  return configuredStyles ? mergeStyles(baseStyles, configuredStyles) : baseStyles;
18
16
  }
19
- /** Find custom names without a component style resolver or rendered anatomy. */
20
- function unusedCustomStyleNames(styles, anatomyNames) {
21
- return Object.keys(styles ?? {}).filter((name) => !sharedConfiguration.__tenphiCookbookUsedComponentStyles?.has(name) && !anatomyNames.has(name));
22
- }
23
- /** Preserve custom anatomy names from the pre-component style API. */
24
- function resolveLegacyAnatomyStyles(styles) {
25
- if (!styles) return void 0;
26
- const entries = Object.entries(styles).filter((entry) => !cookbookComponentNames.has(entry[0]) && entry[1] !== void 0).map(([name, value]) => [`[data-tasty-anatomy="${name}"]`, value]);
27
- return entries.length ? Object.fromEntries(entries) : void 0;
17
+ /** Find custom names without a component style resolver match. */
18
+ function unusedCustomStyleNames(styles) {
19
+ return Object.keys(styles ?? {}).filter((name) => !sharedConfiguration.__tenphiCookbookUsedComponentStyles?.has(name));
28
20
  }
29
21
  //#endregion
30
22
  //#region src/components/tasty-states.js
@@ -60,6 +52,6 @@ function configureCookbookStates() {
60
52
  configured = true;
61
53
  }
62
54
  //#endregion
63
- export { resolveLegacyAnatomyStyles as a, resolveComponentStyles as i, cookbookStates as n, unusedCustomStyleNames as o, configureComponentStyles as r, configureCookbookStates as t };
55
+ export { unusedCustomStyleNames as a, resolveComponentStyles as i, cookbookStates as n, configureComponentStyles as r, configureCookbookStates as t };
64
56
 
65
- //# sourceMappingURL=tasty-states-BDKIbfw2.js.map
57
+ //# sourceMappingURL=tasty-states-rTLFy26t.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasty-states-rTLFy26t.js","names":[],"sources":["../src/components/component-styles.ts","../src/components/tasty-states.js"],"sourcesContent":["import { mergeStyles, type Styles } from \"@tenphi/tasty/core\";\n\n// Astro can load the integration and renderer through separate module graphs.\n// Keep their component configuration on the shared process global.\nconst sharedConfiguration = globalThis as typeof globalThis & {\n __tenphiCookbookComponentStyles?: Record<string, Styles | undefined>;\n __tenphiCookbookUsedComponentStyles?: Set<string>;\n};\n\nexport function configureComponentStyles(\n styles: Record<string, Styles | undefined> | undefined,\n): void {\n sharedConfiguration.__tenphiCookbookComponentStyles = styles ?? {};\n sharedConfiguration.__tenphiCookbookUsedComponentStyles = new Set();\n}\n\n/** Merge a partial theme override into a built-in or consumer style tree. */\nexport function resolveComponentStyles(\n name: string,\n baseStyles: Styles,\n): Styles {\n sharedConfiguration.__tenphiCookbookUsedComponentStyles?.add(name);\n const configuredStyles = sharedConfiguration\n .__tenphiCookbookComponentStyles?.[name] as Styles | undefined;\n return configuredStyles\n ? mergeStyles(baseStyles, configuredStyles as Styles)\n : baseStyles;\n}\n\n/** Find custom names without a component style resolver match. */\nexport function unusedCustomStyleNames(\n styles: Record<string, Styles> | undefined,\n): string[] {\n return Object.keys(styles ?? {}).filter(\n (name) =>\n !sharedConfiguration.__tenphiCookbookUsedComponentStyles?.has(name),\n );\n}\n\nexport function resolveComponentStyleOverride(\n name: string,\n): Styles | undefined {\n return sharedConfiguration.__tenphiCookbookComponentStyles?.[name] as\n Styles | undefined;\n}\n","import { configure, getGlobalPredefinedStates } from \"@tenphi/tasty\";\nimport { resolveTypographyPresets } from \"../theme/defaults.js\";\nimport { TASTY_UNITS } from \"../theme/tasty-config.js\";\n\nexport const cookbookStates = {\n \"@mobile\": \"@media(w < 50rem)\",\n \"@desktop\": \"@media(w >= 50rem)\",\n \"@small\": \"@media(w <= 40rem)\",\n \"@compact\": \"@media(w <= 23rem)\",\n \"@shell-mobile\": \"@media(w <= 48rem)\",\n \"@shell-desktop\": \"@media(w > 48rem)\",\n \"@narrow-layout\": \"@media(w < 72rem)\",\n \"@medium-layout\": \"@media(w >= 50rem) & @media(w < 72rem)\",\n \"@reduced-motion\": \"@media(prefers-reduced-motion: reduce)\",\n};\n\nlet configured = false;\nlet configuredRuntime;\n\n/** Configure aliases in the renderer's Tasty module before styles are parsed. */\nexport function configureCookbookStates() {\n // Process-local server configuration shared across Astro/Vite module graphs.\n // The integration prevents this module from entering browser bundles.\n const runtime = globalThis.__tenphiCookbookTastyRuntime;\n if (configured && configuredRuntime === runtime) return;\n configure({\n presets: resolveTypographyPresets(),\n ...runtime,\n units: { ...TASTY_UNITS, ...runtime?.units },\n });\n configuredRuntime = runtime;\n // The integration may have configured this runtime already, including\n // consumer overrides of built-in breakpoints. Only supply missing aliases.\n const existingStates = getGlobalPredefinedStates();\n const missingStates = Object.fromEntries(\n Object.entries(cookbookStates).filter(\n ([name]) => existingStates[name] === undefined,\n ),\n );\n if (Object.keys(missingStates).length) configure({ states: missingStates });\n configured = true;\n}\n"],"mappings":";;;;;AAIA,MAAM,sBAAsB;AAK5B,SAAgB,yBACd,QACM;CACN,oBAAoB,kCAAkC,UAAU,CAAC;CACjE,oBAAoB,sDAAsC,IAAI,IAAI;AACpE;;AAGA,SAAgB,uBACd,MACA,YACQ;CACR,oBAAoB,qCAAqC,IAAI,IAAI;CACjE,MAAM,mBAAmB,oBACtB,kCAAkC;CACrC,OAAO,mBACH,YAAY,YAAY,gBAA0B,IAClD;AACN;;AAGA,SAAgB,uBACd,QACU;CACV,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,QAC9B,SACC,CAAC,oBAAoB,qCAAqC,IAAI,IAAI,CACtE;AACF;;;ACjCA,MAAa,iBAAiB;CAC5B,WAAW;CACX,YAAY;CACZ,UAAU;CACV,YAAY;CACZ,iBAAiB;CACjB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,mBAAmB;AACrB;AAEA,IAAI,aAAa;AACjB,IAAI;;AAGJ,SAAgB,0BAA0B;CAGxC,MAAM,UAAU,WAAW;CAC3B,IAAI,cAAc,sBAAsB,SAAS;CACjD,YAAU;EACR,SAAS,yBAAyB;EAClC,GAAG;EACH,OAAO;GAAE,GAAG;GAAa,GAAG,SAAS;EAAM;CAC7C,CAAC;CACD,oBAAoB;CAGpB,MAAM,iBAAiB,0BAA0B;CACjD,MAAM,gBAAgB,OAAO,YAC3B,OAAO,QAAQ,cAAc,CAAC,CAAC,QAC5B,CAAC,UAAU,eAAe,UAAU,KAAA,CACvC,CACF;CACA,IAAI,OAAO,KAAK,aAAa,CAAC,CAAC,QAAQ,YAAU,EAAE,QAAQ,cAAc,CAAC;CAC1E,aAAa;AACf"}
package/dist/ui.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ui.d.ts","names":[],"sources":["../src/ui.ts"],"mappings":";;iBAgDgB,eACd,cACA,SAAS,KAAK,8BACb"}
1
+ {"version":3,"file":"ui.d.ts","names":[],"sources":["../src/ui.ts"],"mappings":";;iBAkDgB,eACd,cACA,SAAS,KAAK,8BACb"}
package/dist/ui.js CHANGED
@@ -17,6 +17,7 @@ const english = {
17
17
  "page.lastUpdated": "Last updated",
18
18
  "page.skipToContent": "Skip to content",
19
19
  "pagefind.search": "Search for",
20
+ "pagefind.clear_search": "Clear search",
20
21
  "pagefind.zero_results": "No results",
21
22
  "pagefind.many_results": "[COUNT] results",
22
23
  "pagefind.one_result": "[COUNT] result"
@@ -33,6 +34,7 @@ const french = {
33
34
  "search.cancelLabel": "Annuler",
34
35
  "search.devWarning": "La recherche est disponible après la génération du site.",
35
36
  "pagefind.search": "Rechercher",
37
+ "pagefind.clear_search": "Effacer la recherche",
36
38
  "pagefind.zero_results": "Aucun résultat",
37
39
  "pagefind.many_results": "[COUNT] résultats",
38
40
  "pagefind.one_result": "[COUNT] résultat",
package/dist/ui.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ui.js","names":[],"sources":["../src/ui.ts"],"sourcesContent":["import type { DocsConfig } from \"@tenphi/docs\";\n\nconst english: Record<string, string> = {\n \"sidebarNav.accessibleLabel\": \"Main navigation\",\n \"menuButton.accessibleLabel\": \"Menu\",\n \"tableOfContents.onThisPage\": \"On this page\",\n \"languageSelect.accessibleLabel\": \"Select language\",\n \"themeSelect.light\": \"Light\",\n \"themeSelect.dark\": \"Dark\",\n \"themeSelect.auto\": \"Auto\",\n \"search.label\": \"Search\",\n \"search.ctrlKey\": \"Ctrl+\",\n \"search.cancelLabel\": \"Cancel\",\n \"search.devWarning\": \"Search is available after building the site.\",\n \"page.nextLink\": \"Next\",\n \"page.previousLink\": \"Previous\",\n \"page.editLink\": \"Edit page\",\n \"page.lastUpdated\": \"Last updated\",\n \"page.skipToContent\": \"Skip to content\",\n \"pagefind.search\": \"Search for\",\n \"pagefind.zero_results\": \"No results\",\n \"pagefind.many_results\": \"[COUNT] results\",\n \"pagefind.one_result\": \"[COUNT] result\",\n};\n\nconst french: Record<string, string> = {\n \"sidebarNav.accessibleLabel\": \"Navigation principale\",\n \"menuButton.accessibleLabel\": \"Menu\",\n \"tableOfContents.onThisPage\": \"Sur cette page\",\n \"languageSelect.accessibleLabel\": \"Choisir la langue\",\n \"themeSelect.light\": \"Clair\",\n \"themeSelect.dark\": \"Sombre\",\n \"themeSelect.auto\": \"Auto\",\n \"search.label\": \"Rechercher\",\n \"search.cancelLabel\": \"Annuler\",\n \"search.devWarning\":\n \"La recherche est disponible après la génération du site.\",\n \"pagefind.search\": \"Rechercher\",\n \"pagefind.zero_results\": \"Aucun résultat\",\n \"pagefind.many_results\": \"[COUNT] résultats\",\n \"pagefind.one_result\": \"[COUNT] résultat\",\n \"page.nextLink\": \"Suivant\",\n \"page.previousLink\": \"Précédent\",\n \"page.editLink\": \"Modifier la page\",\n \"page.lastUpdated\": \"Dernière mise à jour\",\n \"page.skipToContent\": \"Aller au contenu\",\n};\n\nexport function uiTranslations(\n lang: string,\n options: Pick<DocsConfig, \"translations\">,\n): Record<string, string> {\n const language = lang.split(\"-\")[0] ?? \"en\";\n return {\n ...english,\n ...(language === \"fr\" ? french : {}),\n ...options.translations?.[language],\n ...options.translations?.[lang],\n };\n}\n"],"mappings":";AAEA,MAAM,UAAkC;CACtC,8BAA8B;CAC9B,8BAA8B;CAC9B,8BAA8B;CAC9B,kCAAkC;CAClC,qBAAqB;CACrB,oBAAoB;CACpB,oBAAoB;CACpB,gBAAgB;CAChB,kBAAkB;CAClB,sBAAsB;CACtB,qBAAqB;CACrB,iBAAiB;CACjB,qBAAqB;CACrB,iBAAiB;CACjB,oBAAoB;CACpB,sBAAsB;CACtB,mBAAmB;CACnB,yBAAyB;CACzB,yBAAyB;CACzB,uBAAuB;AACzB;AAEA,MAAM,SAAiC;CACrC,8BAA8B;CAC9B,8BAA8B;CAC9B,8BAA8B;CAC9B,kCAAkC;CAClC,qBAAqB;CACrB,oBAAoB;CACpB,oBAAoB;CACpB,gBAAgB;CAChB,sBAAsB;CACtB,qBACE;CACF,mBAAmB;CACnB,yBAAyB;CACzB,yBAAyB;CACzB,uBAAuB;CACvB,iBAAiB;CACjB,qBAAqB;CACrB,iBAAiB;CACjB,oBAAoB;CACpB,sBAAsB;AACxB;AAEA,SAAgB,eACd,MACA,SACwB;CACxB,MAAM,WAAW,KAAK,MAAM,GAAG,CAAC,CAAC,MAAM;CACvC,OAAO;EACL,GAAG;EACH,GAAI,aAAa,OAAO,SAAS,CAAC;EAClC,GAAG,QAAQ,eAAe;EAC1B,GAAG,QAAQ,eAAe;CAC5B;AACF"}
1
+ {"version":3,"file":"ui.js","names":[],"sources":["../src/ui.ts"],"sourcesContent":["import type { DocsConfig } from \"@tenphi/docs\";\n\nconst english: Record<string, string> = {\n \"sidebarNav.accessibleLabel\": \"Main navigation\",\n \"menuButton.accessibleLabel\": \"Menu\",\n \"tableOfContents.onThisPage\": \"On this page\",\n \"languageSelect.accessibleLabel\": \"Select language\",\n \"themeSelect.light\": \"Light\",\n \"themeSelect.dark\": \"Dark\",\n \"themeSelect.auto\": \"Auto\",\n \"search.label\": \"Search\",\n \"search.ctrlKey\": \"Ctrl+\",\n \"search.cancelLabel\": \"Cancel\",\n \"search.devWarning\": \"Search is available after building the site.\",\n \"page.nextLink\": \"Next\",\n \"page.previousLink\": \"Previous\",\n \"page.editLink\": \"Edit page\",\n \"page.lastUpdated\": \"Last updated\",\n \"page.skipToContent\": \"Skip to content\",\n \"pagefind.search\": \"Search for\",\n \"pagefind.clear_search\": \"Clear search\",\n \"pagefind.zero_results\": \"No results\",\n \"pagefind.many_results\": \"[COUNT] results\",\n \"pagefind.one_result\": \"[COUNT] result\",\n};\n\nconst french: Record<string, string> = {\n \"sidebarNav.accessibleLabel\": \"Navigation principale\",\n \"menuButton.accessibleLabel\": \"Menu\",\n \"tableOfContents.onThisPage\": \"Sur cette page\",\n \"languageSelect.accessibleLabel\": \"Choisir la langue\",\n \"themeSelect.light\": \"Clair\",\n \"themeSelect.dark\": \"Sombre\",\n \"themeSelect.auto\": \"Auto\",\n \"search.label\": \"Rechercher\",\n \"search.cancelLabel\": \"Annuler\",\n \"search.devWarning\":\n \"La recherche est disponible après la génération du site.\",\n \"pagefind.search\": \"Rechercher\",\n \"pagefind.clear_search\": \"Effacer la recherche\",\n \"pagefind.zero_results\": \"Aucun résultat\",\n \"pagefind.many_results\": \"[COUNT] résultats\",\n \"pagefind.one_result\": \"[COUNT] résultat\",\n \"page.nextLink\": \"Suivant\",\n \"page.previousLink\": \"Précédent\",\n \"page.editLink\": \"Modifier la page\",\n \"page.lastUpdated\": \"Dernière mise à jour\",\n \"page.skipToContent\": \"Aller au contenu\",\n};\n\nexport function uiTranslations(\n lang: string,\n options: Pick<DocsConfig, \"translations\">,\n): Record<string, string> {\n const language = lang.split(\"-\")[0] ?? \"en\";\n return {\n ...english,\n ...(language === \"fr\" ? french : {}),\n ...options.translations?.[language],\n ...options.translations?.[lang],\n };\n}\n"],"mappings":";AAEA,MAAM,UAAkC;CACtC,8BAA8B;CAC9B,8BAA8B;CAC9B,8BAA8B;CAC9B,kCAAkC;CAClC,qBAAqB;CACrB,oBAAoB;CACpB,oBAAoB;CACpB,gBAAgB;CAChB,kBAAkB;CAClB,sBAAsB;CACtB,qBAAqB;CACrB,iBAAiB;CACjB,qBAAqB;CACrB,iBAAiB;CACjB,oBAAoB;CACpB,sBAAsB;CACtB,mBAAmB;CACnB,yBAAyB;CACzB,yBAAyB;CACzB,yBAAyB;CACzB,uBAAuB;AACzB;AAEA,MAAM,SAAiC;CACrC,8BAA8B;CAC9B,8BAA8B;CAC9B,8BAA8B;CAC9B,kCAAkC;CAClC,qBAAqB;CACrB,oBAAoB;CACpB,oBAAoB;CACpB,gBAAgB;CAChB,sBAAsB;CACtB,qBACE;CACF,mBAAmB;CACnB,yBAAyB;CACzB,yBAAyB;CACzB,yBAAyB;CACzB,uBAAuB;CACvB,iBAAiB;CACjB,qBAAqB;CACrB,iBAAiB;CACjB,oBAAoB;CACpB,sBAAsB;AACxB;AAEA,SAAgB,eACd,MACA,SACwB;CACxB,MAAM,WAAW,KAAK,MAAM,GAAG,CAAC,CAAC,MAAM;CACvC,OAAO;EACL,GAAG;EACH,GAAI,aAAa,OAAO,SAAS,CAAC;EAClC,GAAG,QAAQ,eAAe;EAC1B,GAAG,QAAQ,eAAe;CAC5B;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenphi/renderer",
3
- "version": "0.20.4",
3
+ "version": "0.21.0",
4
4
  "description": "Astro renderer and Tasty theme for Cookbook",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -61,7 +61,7 @@
61
61
  "@fontsource-variable/jetbrains-mono": "^5.3.0",
62
62
  "@fontsource-variable/onest": "^5.3.0",
63
63
  "@pagefind/default-ui": "1.5.2",
64
- "@tenphi/docs": "0.20.4",
64
+ "@tenphi/docs": "0.21.0",
65
65
  "@tenphi/eslint-plugin-tasty": "1.1.0",
66
66
  "@tenphi/glaze": "2.0.0",
67
67
  "@tenphi/tasty": "3.8.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"tasty-states-BDKIbfw2.js","names":[],"sources":["../src/components/component-styles.ts","../src/components/tasty-states.js"],"sourcesContent":["import { mergeStyles, type Styles } from \"@tenphi/tasty/core\";\nimport { COOKBOOK_COMPONENT_NAMES } from \"@tenphi/docs\";\n\n// Astro can load the integration and renderer through separate module graphs.\n// Keep their component configuration on the shared process global.\nconst sharedConfiguration = globalThis as typeof globalThis & {\n __tenphiCookbookComponentStyles?: Record<string, Styles | undefined>;\n __tenphiCookbookUsedComponentStyles?: Set<string>;\n};\nconst cookbookComponentNames = new Set<string>(COOKBOOK_COMPONENT_NAMES);\n\nexport function configureComponentStyles(\n styles: Record<string, Styles | undefined> | undefined,\n): void {\n sharedConfiguration.__tenphiCookbookComponentStyles = styles ?? {};\n sharedConfiguration.__tenphiCookbookUsedComponentStyles = new Set();\n}\n\n/** Merge a partial theme override into a built-in or consumer style tree. */\nexport function resolveComponentStyles(\n name: string,\n baseStyles: Styles,\n): Styles {\n sharedConfiguration.__tenphiCookbookUsedComponentStyles?.add(name);\n const configuredStyles = sharedConfiguration\n .__tenphiCookbookComponentStyles?.[name] as Styles | undefined;\n return configuredStyles\n ? mergeStyles(baseStyles, configuredStyles as Styles)\n : baseStyles;\n}\n\n/** Find custom names without a component style resolver or rendered anatomy. */\nexport function unusedCustomStyleNames(\n styles: Record<string, Styles> | undefined,\n anatomyNames: ReadonlySet<string>,\n): string[] {\n return Object.keys(styles ?? {}).filter(\n (name) =>\n !sharedConfiguration.__tenphiCookbookUsedComponentStyles?.has(name) &&\n !anatomyNames.has(name),\n );\n}\n\nexport function resolveComponentStyleOverride(\n name: string,\n): Styles | undefined {\n return sharedConfiguration.__tenphiCookbookComponentStyles?.[name] as\n Styles | undefined;\n}\n\n/** Preserve custom anatomy names from the pre-component style API. */\nexport function resolveLegacyAnatomyStyles(\n styles: Record<string, Styles | undefined> | undefined,\n): Record<string, Styles> | undefined {\n if (!styles) return undefined;\n const entries = Object.entries(styles)\n .filter(\n (entry): entry is [string, Styles] =>\n !cookbookComponentNames.has(entry[0]) && entry[1] !== undefined,\n )\n .map(([name, value]) => [`[data-tasty-anatomy=\"${name}\"]`, value]);\n return entries.length\n ? (Object.fromEntries(entries) as Record<string, Styles>)\n : undefined;\n}\n","import { configure, getGlobalPredefinedStates } from \"@tenphi/tasty\";\nimport { resolveTypographyPresets } from \"../theme/defaults.js\";\nimport { TASTY_UNITS } from \"../theme/tasty-config.js\";\n\nexport const cookbookStates = {\n \"@mobile\": \"@media(w < 50rem)\",\n \"@desktop\": \"@media(w >= 50rem)\",\n \"@small\": \"@media(w <= 40rem)\",\n \"@compact\": \"@media(w <= 23rem)\",\n \"@shell-mobile\": \"@media(w <= 48rem)\",\n \"@shell-desktop\": \"@media(w > 48rem)\",\n \"@narrow-layout\": \"@media(w < 72rem)\",\n \"@medium-layout\": \"@media(w >= 50rem) & @media(w < 72rem)\",\n \"@reduced-motion\": \"@media(prefers-reduced-motion: reduce)\",\n};\n\nlet configured = false;\nlet configuredRuntime;\n\n/** Configure aliases in the renderer's Tasty module before styles are parsed. */\nexport function configureCookbookStates() {\n // Process-local server configuration shared across Astro/Vite module graphs.\n // The integration prevents this module from entering browser bundles.\n const runtime = globalThis.__tenphiCookbookTastyRuntime;\n if (configured && configuredRuntime === runtime) return;\n configure({\n presets: resolveTypographyPresets(),\n ...runtime,\n units: { ...TASTY_UNITS, ...runtime?.units },\n });\n configuredRuntime = runtime;\n // The integration may have configured this runtime already, including\n // consumer overrides of built-in breakpoints. Only supply missing aliases.\n const existingStates = getGlobalPredefinedStates();\n const missingStates = Object.fromEntries(\n Object.entries(cookbookStates).filter(\n ([name]) => existingStates[name] === undefined,\n ),\n );\n if (Object.keys(missingStates).length) configure({ states: missingStates });\n configured = true;\n}\n"],"mappings":";;;;;;AAKA,MAAM,sBAAsB;AAI5B,MAAM,yBAAyB,IAAI,IAAY,wBAAwB;AAEvE,SAAgB,yBACd,QACM;CACN,oBAAoB,kCAAkC,UAAU,CAAC;CACjE,oBAAoB,sDAAsC,IAAI,IAAI;AACpE;;AAGA,SAAgB,uBACd,MACA,YACQ;CACR,oBAAoB,qCAAqC,IAAI,IAAI;CACjE,MAAM,mBAAmB,oBACtB,kCAAkC;CACrC,OAAO,mBACH,YAAY,YAAY,gBAA0B,IAClD;AACN;;AAGA,SAAgB,uBACd,QACA,cACU;CACV,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,QAC9B,SACC,CAAC,oBAAoB,qCAAqC,IAAI,IAAI,KAClE,CAAC,aAAa,IAAI,IAAI,CAC1B;AACF;;AAUA,SAAgB,2BACd,QACoC;CACpC,IAAI,CAAC,QAAQ,OAAO,KAAA;CACpB,MAAM,UAAU,OAAO,QAAQ,MAAM,CAAC,CACnC,QACE,UACC,CAAC,uBAAuB,IAAI,MAAM,EAAE,KAAK,MAAM,OAAO,KAAA,CAC1D,CAAC,CACA,KAAK,CAAC,MAAM,WAAW,CAAC,wBAAwB,KAAK,KAAK,KAAK,CAAC;CACnE,OAAO,QAAQ,SACV,OAAO,YAAY,OAAO,IAC3B,KAAA;AACN;;;AC5DA,MAAa,iBAAiB;CAC5B,WAAW;CACX,YAAY;CACZ,UAAU;CACV,YAAY;CACZ,iBAAiB;CACjB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,mBAAmB;AACrB;AAEA,IAAI,aAAa;AACjB,IAAI;;AAGJ,SAAgB,0BAA0B;CAGxC,MAAM,UAAU,WAAW;CAC3B,IAAI,cAAc,sBAAsB,SAAS;CACjD,YAAU;EACR,SAAS,yBAAyB;EAClC,GAAG;EACH,OAAO;GAAE,GAAG;GAAa,GAAG,SAAS;EAAM;CAC7C,CAAC;CACD,oBAAoB;CAGpB,MAAM,iBAAiB,0BAA0B;CACjD,MAAM,gBAAgB,OAAO,YAC3B,OAAO,QAAQ,cAAc,CAAC,CAAC,QAC5B,CAAC,UAAU,eAAe,UAAU,KAAA,CACvC,CACF;CACA,IAAI,OAAO,KAAK,aAAa,CAAC,CAAC,QAAQ,YAAU,EAAE,QAAQ,cAAc,CAAC;CAC1E,aAAa;AACf"}