@astrojs/starlight 0.31.0 → 0.32.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 (69) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/components/Banner.astro +1 -3
  3. package/components/ContentNotice.astro +2 -2
  4. package/components/ContentPanel.astro +0 -4
  5. package/components/DraftContentNotice.astro +0 -1
  6. package/components/EditLink.astro +1 -2
  7. package/components/FallbackContentNotice.astro +0 -1
  8. package/components/Footer.astro +3 -5
  9. package/components/Head.astro +1 -2
  10. package/components/Header.astro +5 -6
  11. package/components/Hero.astro +1 -2
  12. package/components/Icons.ts +2 -0
  13. package/components/LanguageSelect.astro +2 -3
  14. package/components/LastUpdated.astro +1 -3
  15. package/components/MarkdownContent.astro +0 -1
  16. package/components/MobileMenuFooter.astro +3 -4
  17. package/components/MobileMenuToggle.astro +0 -1
  18. package/components/MobileTableOfContents.astro +1 -2
  19. package/components/Page.astro +32 -32
  20. package/components/PageFrame.astro +2 -3
  21. package/components/PageSidebar.astro +3 -5
  22. package/components/PageTitle.astro +1 -2
  23. package/components/Pagination.astro +1 -2
  24. package/components/Search.astro +17 -3
  25. package/components/Sidebar.astro +3 -5
  26. package/components/SidebarPersister.astro +1 -2
  27. package/components/SidebarSublist.astro +2 -1
  28. package/components/SiteTitle.astro +1 -2
  29. package/components/SkipLink.astro +0 -1
  30. package/components/SocialIcons.astro +0 -1
  31. package/components/StarlightPage.astro +7 -3
  32. package/components/TableOfContents.astro +1 -2
  33. package/components/ThemeProvider.astro +0 -1
  34. package/components/ThemeSelect.astro +0 -1
  35. package/components/TwoColumnContent.astro +1 -5
  36. package/index.ts +7 -9
  37. package/integrations/asides.ts +4 -7
  38. package/integrations/expressive-code/index.ts +15 -10
  39. package/integrations/shared/{pathToLocale.ts → absolutePathToLang.ts} +7 -5
  40. package/integrations/virtual-user-config.ts +27 -0
  41. package/locals.d.ts +26 -0
  42. package/locals.ts +36 -2
  43. package/package.json +5 -3
  44. package/props.ts +13 -1
  45. package/route-data.ts +11 -0
  46. package/routes/common.astro +5 -11
  47. package/routes/ssr/index.astro +1 -1
  48. package/routes/static/404.astro +1 -41
  49. package/routes/static/index.astro +1 -4
  50. package/schemas/hero.ts +2 -3
  51. package/schemas/pagefind.ts +97 -33
  52. package/types.ts +2 -0
  53. package/user-components/Card.astro +2 -2
  54. package/user-components/Icon.astro +2 -2
  55. package/user-components/LinkButton.astro +2 -2
  56. package/user-components/TabItem.astro +2 -2
  57. package/user-components/rehype-file-tree.ts +2 -2
  58. package/user-components/rehype-tabs.ts +3 -3
  59. package/utils/i18n.ts +0 -20
  60. package/utils/navigation.ts +19 -36
  61. package/utils/plugins.ts +316 -141
  62. package/utils/{route-data.ts → routing/data.ts} +56 -30
  63. package/utils/{routing.ts → routing/index.ts} +6 -44
  64. package/utils/routing/middleware.ts +81 -0
  65. package/utils/routing/types.ts +96 -0
  66. package/utils/slugs.ts +2 -10
  67. package/utils/starlight-page.ts +2 -10
  68. package/utils/user-config.ts +8 -0
  69. package/virtual-internal.d.ts +4 -0
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from 'astro/types';
3
- import { Icons } from '../components/Icons';
3
+ import type { StarlightIcon } from '../components/Icons';
4
4
  import Icon from './Icon.astro';
5
5
 
6
6
  interface Props extends Omit<HTMLAttributes<'a'>, 'href'> {
7
7
  href: string | URL;
8
- icon?: keyof typeof Icons | undefined;
8
+ icon?: StarlightIcon | undefined;
9
9
  iconPlacement?: 'start' | 'end' | undefined;
10
10
  variant?: 'primary' | 'secondary' | 'minimal';
11
11
  }
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  import { TabItemTagname } from './rehype-tabs';
3
- import type { Icons } from '../components/Icons';
3
+ import type { StarlightIcon } from '../components/Icons';
4
4
 
5
5
  interface Props {
6
- icon?: keyof typeof Icons;
6
+ icon?: StarlightIcon;
7
7
  label: string;
8
8
  }
9
9
 
@@ -6,7 +6,7 @@ import { fromHtml } from 'hast-util-from-html';
6
6
  import { toString } from 'hast-util-to-string';
7
7
  import { rehype } from 'rehype';
8
8
  import { CONTINUE, SKIP, visit } from 'unist-util-visit';
9
- import { Icons } from '../components/Icons';
9
+ import { Icons, type StarlightIcon } from '../components/Icons';
10
10
  import { definitions } from './file-tree-icons';
11
11
 
12
12
  declare module 'vfile' {
@@ -160,7 +160,7 @@ function getFileIcon(fileName: string) {
160
160
  const name = getFileIconName(fileName);
161
161
  if (!name) return defaultFileIcon;
162
162
  if (name in Icons) {
163
- const path = Icons[name as keyof typeof Icons];
163
+ const path = Icons[name as StarlightIcon];
164
164
  return makeSVGIcon(path);
165
165
  }
166
166
  return defaultFileIcon;
@@ -2,13 +2,13 @@ import type { Element } from 'hast';
2
2
  import { select } from 'hast-util-select';
3
3
  import { rehype } from 'rehype';
4
4
  import { CONTINUE, SKIP, visit } from 'unist-util-visit';
5
- import { Icons } from '../components/Icons';
5
+ import type { StarlightIcon } from '../components/Icons';
6
6
 
7
7
  interface Panel {
8
8
  panelId: string;
9
9
  tabId: string;
10
10
  label: string;
11
- icon?: keyof typeof Icons;
11
+ icon?: StarlightIcon;
12
12
  }
13
13
 
14
14
  declare module 'vfile' {
@@ -67,7 +67,7 @@ const tabsProcessor = rehype()
67
67
  ...ids,
68
68
  label: String(dataLabel),
69
69
  };
70
- if (dataIcon) panel.icon = String(dataIcon) as keyof typeof Icons;
70
+ if (dataIcon) panel.icon = String(dataIcon) as StarlightIcon;
71
71
  file.data.panels?.push(panel);
72
72
 
73
73
  // Remove `<TabItem>` props
package/utils/i18n.ts CHANGED
@@ -2,26 +2,6 @@ import type { AstroConfig } from 'astro';
2
2
  import { AstroError } from 'astro/errors';
3
3
  import type { StarlightConfig } from './user-config';
4
4
 
5
- /**
6
- * A proxy object that throws an error when a user tries to access the deprecated `labels` prop in
7
- * a component override.
8
- *
9
- * @todo Remove in a future release once people have updated — no later than v1.
10
- */
11
- export const DeprecatedLabelsPropProxy = new Proxy<Record<string, never>>(
12
- {},
13
- {
14
- get(_, key) {
15
- const label = String(key);
16
- throw new AstroError(
17
- `The \`labels\` prop in component overrides has been removed.`,
18
- `Replace \`Astro.props.labels["${label}"]\` with \`Astro.locals.t("${label}")\` instead.\n` +
19
- 'For more information see https://starlight.astro.build/guides/i18n/#using-ui-translations'
20
- );
21
- },
22
- }
23
- );
24
-
25
5
  /**
26
6
  * A list of well-known right-to-left languages used as a fallback when determining the text
27
7
  * direction of a locale is not supported by the `Intl.Locale` API in the current environment.
@@ -1,6 +1,6 @@
1
1
  import { AstroError } from 'astro/errors';
2
- import config from 'virtual:starlight/user-config';
3
2
  import project from 'virtual:starlight/project-context';
3
+ import config from 'virtual:starlight/user-config';
4
4
  import type { Badge, I18nBadge, I18nBadgeConfig } from '../schemas/badge';
5
5
  import type { PrevNextLinkConfig } from '../schemas/prevNextLink';
6
6
  import type {
@@ -10,6 +10,7 @@ import type {
10
10
  SidebarItem,
11
11
  SidebarLinkItem,
12
12
  } from '../schemas/sidebar';
13
+ import { getCollectionPathFromRoot } from './collection';
13
14
  import { createPathFormatter } from './createPathFormatter';
14
15
  import { formatPath } from './format-path';
15
16
  import { BuiltInDefaultLocale, pickLang } from './i18n';
@@ -19,10 +20,16 @@ import {
19
20
  stripExtension,
20
21
  stripLeadingAndTrailingSlashes,
21
22
  } from './path';
22
- import { getLocaleRoutes, routes, type Route } from './routing';
23
+ import { getLocaleRoutes, routes } from './routing';
24
+ import type {
25
+ SidebarGroup,
26
+ SidebarLink,
27
+ PaginationLinks,
28
+ Route,
29
+ SidebarEntry,
30
+ } from './routing/types';
23
31
  import { localeToLang, localizedId, slugToPathname } from './slugs';
24
32
  import type { StarlightConfig } from './user-config';
25
- import { getCollectionPathFromRoot } from './collection';
26
33
 
27
34
  const DirKey = Symbol('DirKey');
28
35
  const SlugKey = Symbol('SlugKey');
@@ -31,25 +38,6 @@ const neverPathFormatter = createPathFormatter({ trailingSlash: 'never' });
31
38
 
32
39
  const docsCollectionPathFromRoot = getCollectionPathFromRoot('docs', project);
33
40
 
34
- export interface Link {
35
- type: 'link';
36
- label: string;
37
- href: string;
38
- isCurrent: boolean;
39
- badge: Badge | undefined;
40
- attrs: LinkHTMLAttributes;
41
- }
42
-
43
- interface Group {
44
- type: 'group';
45
- label: string;
46
- entries: (Link | Group)[];
47
- collapsed: boolean;
48
- badge: Badge | undefined;
49
- }
50
-
51
- export type SidebarEntry = Link | Group;
52
-
53
41
  /**
54
42
  * A representation of the route structure. For each object entry:
55
43
  * if it’s a folder, the key is the directory name, and value is the directory
@@ -107,7 +95,7 @@ function groupFromAutogenerateConfig(
107
95
  locale: string | undefined,
108
96
  routes: Route[],
109
97
  currentPathname: string
110
- ): Group {
98
+ ): SidebarGroup {
111
99
  const { collapsed: subgroupCollapsed, directory } = item.autogenerate;
112
100
  const localeDir = locale ? locale + '/' + directory : directory;
113
101
  const dirDocs = routes.filter((doc) => {
@@ -186,7 +174,7 @@ function makeSidebarLink(
186
174
  label: string,
187
175
  badge?: Badge,
188
176
  attrs?: LinkHTMLAttributes
189
- ): Link {
177
+ ): SidebarLink {
190
178
  if (!isAbsolute(href)) {
191
179
  href = formatPath(href);
192
180
  }
@@ -203,7 +191,7 @@ function makeLink({
203
191
  href: string;
204
192
  badge?: Badge | undefined;
205
193
  attrs?: LinkHTMLAttributes | undefined;
206
- }): Link {
194
+ }): SidebarLink {
207
195
  return { type: 'link', ...opts, badge, isCurrent: false, attrs };
208
196
  }
209
197
 
@@ -275,7 +263,7 @@ function treeify(routes: Route[], locale: string | undefined, baseDir: string):
275
263
  }
276
264
 
277
265
  /** Create a link entry for a given content collection entry. */
278
- function linkFromRoute(route: Route): Link {
266
+ function linkFromRoute(route: Route): SidebarLink {
279
267
  return makeSidebarLink(
280
268
  slugToPathname(route.slug),
281
269
  route.entry.data.sidebar.label || route.entry.data.title,
@@ -315,7 +303,7 @@ function groupFromDir(
315
303
  currentPathname: string,
316
304
  locale: string | undefined,
317
305
  collapsed: boolean
318
- ): Group {
306
+ ): SidebarGroup {
319
307
  const entries = sortDirEntries(Object.entries(dir)).map(([key, dirOrRoute]) =>
320
308
  dirToItem(dirOrRoute, `${fullPath}/${key}`, key, currentPathname, locale, collapsed)
321
309
  );
@@ -451,7 +439,7 @@ function recursivelyBuildSidebarIdentity(sidebar: SidebarEntry[]): string {
451
439
  }
452
440
 
453
441
  /** Turn the nested tree structure of a sidebar into a flat list of all the links. */
454
- export function flattenSidebar(sidebar: SidebarEntry[]): Link[] {
442
+ export function flattenSidebar(sidebar: SidebarEntry[]): SidebarLink[] {
455
443
  return sidebar.flatMap((entry) =>
456
444
  entry.type === 'group' ? flattenSidebar(entry.entries) : entry
457
445
  );
@@ -465,12 +453,7 @@ export function getPrevNextLinks(
465
453
  prev?: PrevNextLinkConfig;
466
454
  next?: PrevNextLinkConfig;
467
455
  }
468
- ): {
469
- /** Link to previous page in the sidebar. */
470
- prev: Link | undefined;
471
- /** Link to next page in the sidebar. */
472
- next: Link | undefined;
473
- } {
456
+ ): PaginationLinks {
474
457
  const entries = flattenSidebar(sidebar);
475
458
  const currentIndex = entries.findIndex((entry) => entry.isCurrent);
476
459
  const prev = applyPrevNextLinkConfig(entries[currentIndex - 1], paginationEnabled, config.prev);
@@ -484,10 +467,10 @@ export function getPrevNextLinks(
484
467
 
485
468
  /** Apply a prev/next link config to a navigation link. */
486
469
  function applyPrevNextLinkConfig(
487
- link: Link | undefined,
470
+ link: SidebarLink | undefined,
488
471
  paginationEnabled: boolean,
489
472
  config: PrevNextLinkConfig | undefined
490
- ): Link | undefined {
473
+ ): SidebarLink | undefined {
491
474
  // Explicitly remove the link.
492
475
  if (config === false) return undefined;
493
476
  // Use the generated link if any.