@astrojs/starlight 0.5.6 → 0.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.
Files changed (76) hide show
  1. package/404.astro +17 -17
  2. package/CHANGELOG.md +40 -2
  3. package/components/CallToAction.astro +32 -35
  4. package/components/ContentPanel.astro +18 -18
  5. package/components/EditLink.astro +23 -23
  6. package/components/FallbackContentNotice.astro +16 -18
  7. package/components/Footer.astro +28 -34
  8. package/components/HeadSEO.astro +69 -75
  9. package/components/Header.astro +47 -51
  10. package/components/Hero.astro +108 -121
  11. package/components/Icons.ts +73 -71
  12. package/components/LanguageSelect.astro +31 -31
  13. package/components/LastUpdated.astro +16 -18
  14. package/components/MarkdownContent.astro +105 -117
  15. package/components/MobileMenuToggle.astro +80 -80
  16. package/components/PrevNextLinks.astro +60 -60
  17. package/components/RightSidebar.astro +17 -17
  18. package/components/RightSidebarPanel.astro +41 -41
  19. package/components/Search.astro +293 -306
  20. package/components/Select.astro +64 -65
  21. package/components/Sidebar.astro +23 -23
  22. package/components/SidebarSublist.astro +96 -95
  23. package/components/SiteTitle.astro +65 -63
  24. package/components/SkipLink.astro +17 -17
  25. package/components/SocialIcons.astro +36 -34
  26. package/components/TableOfContents/MobileTableOfContents.astro +124 -124
  27. package/components/TableOfContents/TableOfContentsList.astro +64 -69
  28. package/components/TableOfContents/generateToC.ts +41 -43
  29. package/components/TableOfContents/starlight-toc.ts +84 -90
  30. package/components/TableOfContents.astro +8 -8
  31. package/components/ThemeProvider.astro +28 -32
  32. package/components/ThemeSelect.astro +66 -71
  33. package/global.d.ts +3 -3
  34. package/index.astro +1 -1
  35. package/index.ts +52 -59
  36. package/integrations/asides.ts +109 -111
  37. package/integrations/sitemap.ts +10 -13
  38. package/integrations/virtual-user-config.ts +37 -37
  39. package/layout/Page.astro +84 -72
  40. package/layout/PageFrame.astro +67 -69
  41. package/layout/TwoColumnContent.astro +40 -42
  42. package/package.json +2 -2
  43. package/schema.ts +126 -113
  44. package/schemas/favicon.ts +40 -0
  45. package/schemas/head.ts +12 -23
  46. package/schemas/i18n.ts +146 -160
  47. package/schemas/logo.ts +22 -22
  48. package/schemas/prevNextLink.ts +14 -14
  49. package/schemas/tableOfContents.ts +14 -18
  50. package/style/asides.css +27 -27
  51. package/style/props.css +168 -172
  52. package/style/reset.css +13 -13
  53. package/style/shiki.css +11 -11
  54. package/style/util.css +30 -30
  55. package/translations/fr.json +21 -21
  56. package/translations/index.ts +4 -4
  57. package/translations/it.json +20 -20
  58. package/translations/tr.json +1 -1
  59. package/translations/zh.json +0 -1
  60. package/user-components/Card.astro +50 -54
  61. package/user-components/CardGrid.astro +21 -21
  62. package/user-components/Icon.astro +19 -21
  63. package/user-components/TabItem.astro +3 -3
  64. package/user-components/Tabs.astro +113 -117
  65. package/user-components/rehype-tabs.ts +72 -72
  66. package/utils/base.ts +6 -6
  67. package/utils/git.ts +55 -55
  68. package/utils/head.ts +56 -54
  69. package/utils/i18n.ts +3 -3
  70. package/utils/localizedUrl.ts +25 -25
  71. package/utils/navigation.ts +225 -203
  72. package/utils/routing.ts +74 -85
  73. package/utils/slugs.ts +41 -51
  74. package/utils/translations.ts +26 -32
  75. package/utils/user-config.ts +278 -278
  76. package/virtual.d.ts +8 -8
@@ -1,103 +1,97 @@
1
1
  export class StarlightTOC extends HTMLElement {
2
- private _current = this.querySelector(
3
- 'a[aria-current="true"]'
4
- ) as HTMLAnchorElement | null;
5
- private minH = parseInt(this.dataset.minH || '2', 10);
6
- private maxH = parseInt(this.dataset.maxH || '3', 10);
2
+ private _current = this.querySelector('a[aria-current="true"]') as HTMLAnchorElement | null;
3
+ private minH = parseInt(this.dataset.minH || '2', 10);
4
+ private maxH = parseInt(this.dataset.maxH || '3', 10);
7
5
 
8
- protected set current(link: HTMLAnchorElement) {
9
- if (link === this._current) return;
10
- if (this._current) this._current.removeAttribute('aria-current');
11
- link.setAttribute('aria-current', 'true');
12
- this._current = link;
13
- }
6
+ protected set current(link: HTMLAnchorElement) {
7
+ if (link === this._current) return;
8
+ if (this._current) this._current.removeAttribute('aria-current');
9
+ link.setAttribute('aria-current', 'true');
10
+ this._current = link;
11
+ }
14
12
 
15
- constructor({ smallViewport = false } = {}) {
16
- super();
13
+ constructor({ smallViewport = false } = {}) {
14
+ super();
17
15
 
18
- /** All the links in the table of contents. */
19
- const links = [...this.querySelectorAll('a')];
16
+ /** All the links in the table of contents. */
17
+ const links = [...this.querySelectorAll('a')];
20
18
 
21
- /** Test if an element is a table-of-contents heading. */
22
- const isHeading = (el: Element): el is HTMLHeadingElement => {
23
- if (el instanceof HTMLHeadingElement) {
24
- // Special case for page title h1
25
- if ('pageTitle' in el.dataset) return true;
26
- // Check the heading level is within the user-configured limits for the ToC
27
- const level = el.tagName[1];
28
- if (level) {
29
- const int = parseInt(level, 10);
30
- if (int >= this.minH && int <= this.maxH) return true;
31
- }
32
- }
33
- return false;
34
- };
19
+ /** Test if an element is a table-of-contents heading. */
20
+ const isHeading = (el: Element): el is HTMLHeadingElement => {
21
+ if (el instanceof HTMLHeadingElement) {
22
+ // Special case for page title h1
23
+ if ('pageTitle' in el.dataset) return true;
24
+ // Check the heading level is within the user-configured limits for the ToC
25
+ const level = el.tagName[1];
26
+ if (level) {
27
+ const int = parseInt(level, 10);
28
+ if (int >= this.minH && int <= this.maxH) return true;
29
+ }
30
+ }
31
+ return false;
32
+ };
35
33
 
36
- /** Walk up the DOM to find the nearest heading. */
37
- const getElementHeading = (
38
- el: Element | null
39
- ): HTMLHeadingElement | null => {
40
- if (!el) return null;
41
- const origin = el;
42
- while (el) {
43
- if (isHeading(el)) return el;
44
- // Assign the previous sibling’s last, most deeply nested child to el.
45
- el = el.previousElementSibling;
46
- while (el?.lastElementChild) {
47
- el = el.lastElementChild;
48
- }
49
- // Look for headings amongst siblings.
50
- const h = getElementHeading(el);
51
- if (h) return h;
52
- }
53
- // Walk back up the parent.
54
- return getElementHeading(origin.parentElement);
55
- };
34
+ /** Walk up the DOM to find the nearest heading. */
35
+ const getElementHeading = (el: Element | null): HTMLHeadingElement | null => {
36
+ if (!el) return null;
37
+ const origin = el;
38
+ while (el) {
39
+ if (isHeading(el)) return el;
40
+ // Assign the previous sibling’s last, most deeply nested child to el.
41
+ el = el.previousElementSibling;
42
+ while (el?.lastElementChild) {
43
+ el = el.lastElementChild;
44
+ }
45
+ // Look for headings amongst siblings.
46
+ const h = getElementHeading(el);
47
+ if (h) return h;
48
+ }
49
+ // Walk back up the parent.
50
+ return getElementHeading(origin.parentElement);
51
+ };
56
52
 
57
- /** Handle intersections and set the current link to the heading for the current intersection. */
58
- const setCurrent: IntersectionObserverCallback = (entries) => {
59
- for (const { isIntersecting, target } of entries) {
60
- if (!isIntersecting) continue;
61
- const heading = getElementHeading(target);
62
- if (!heading) continue;
63
- const link = links.find((link) => link.hash === '#' + encodeURIComponent(heading.id));
64
- if (link) {
65
- this.current = link;
66
- break;
67
- }
68
- }
69
- };
53
+ /** Handle intersections and set the current link to the heading for the current intersection. */
54
+ const setCurrent: IntersectionObserverCallback = (entries) => {
55
+ for (const { isIntersecting, target } of entries) {
56
+ if (!isIntersecting) continue;
57
+ const heading = getElementHeading(target);
58
+ if (!heading) continue;
59
+ const link = links.find((link) => link.hash === '#' + encodeURIComponent(heading.id));
60
+ if (link) {
61
+ this.current = link;
62
+ break;
63
+ }
64
+ }
65
+ };
70
66
 
71
- // Observe elements with an `id` (most likely headings) and their siblings.
72
- // Also observe direct children of `.content` to include elements before
73
- // the first heading.
74
- const toObserve = document.querySelectorAll(
75
- 'main [id], main [id] ~ *, main .content > *'
76
- );
77
- /** Start intersections at nav height + 2rem padding. */
78
- const top = (smallViewport ? 104 : 64) + 32;
79
- /** End intersections 1.5rem later. */
80
- const bottom = top + 24;
67
+ // Observe elements with an `id` (most likely headings) and their siblings.
68
+ // Also observe direct children of `.content` to include elements before
69
+ // the first heading.
70
+ const toObserve = document.querySelectorAll('main [id], main [id] ~ *, main .content > *');
71
+ /** Start intersections at nav height + 2rem padding. */
72
+ const top = (smallViewport ? 104 : 64) + 32;
73
+ /** End intersections 1.5rem later. */
74
+ const bottom = top + 24;
81
75
 
82
- let observer: IntersectionObserver | undefined;
83
- function observe() {
84
- if (observer) observer.disconnect();
85
- const height = document.documentElement.clientHeight;
86
- const rootMargin = `-${top}px 0% ${bottom - height}px`;
87
- observer = new IntersectionObserver(setCurrent, { rootMargin });
88
- toObserve.forEach((h) => observer!.observe(h));
89
- }
90
- observe();
76
+ let observer: IntersectionObserver | undefined;
77
+ function observe() {
78
+ if (observer) observer.disconnect();
79
+ const height = document.documentElement.clientHeight;
80
+ const rootMargin = `-${top}px 0% ${bottom - height}px`;
81
+ observer = new IntersectionObserver(setCurrent, { rootMargin });
82
+ toObserve.forEach((h) => observer!.observe(h));
83
+ }
84
+ observe();
91
85
 
92
- const onIdle = window.requestIdleCallback || ((cb) => setTimeout(cb, 1));
93
- let timeout: NodeJS.Timeout;
94
- window.addEventListener('resize', () => {
95
- // Disable intersection observer while window is resizing.
96
- if (observer) observer.disconnect();
97
- clearTimeout(timeout);
98
- timeout = setTimeout(() => onIdle(observe), 200);
99
- });
100
- }
86
+ const onIdle = window.requestIdleCallback || ((cb) => setTimeout(cb, 1));
87
+ let timeout: NodeJS.Timeout;
88
+ window.addEventListener('resize', () => {
89
+ // Disable intersection observer while window is resizing.
90
+ if (observer) observer.disconnect();
91
+ clearTimeout(timeout);
92
+ timeout = setTimeout(() => onIdle(observe), 200);
93
+ });
94
+ }
101
95
  }
102
96
 
103
97
  customElements.define('starlight-toc', StarlightTOC);
@@ -4,10 +4,10 @@ import TableOfContentsList from './TableOfContents/TableOfContentsList.astro';
4
4
  import type { TocItem } from './TableOfContents/generateToC';
5
5
 
6
6
  interface Props {
7
- toc: TocItem[];
8
- locale: string | undefined;
9
- maxHeadingLevel: number;
10
- minHeadingLevel: number;
7
+ toc: TocItem[];
8
+ locale: string | undefined;
9
+ maxHeadingLevel: number;
10
+ minHeadingLevel: number;
11
11
  }
12
12
 
13
13
  const { locale, toc, maxHeadingLevel, minHeadingLevel } = Astro.props;
@@ -15,10 +15,10 @@ const t = useTranslations(locale);
15
15
  ---
16
16
 
17
17
  <starlight-toc data-min-h={minHeadingLevel} data-max-h={maxHeadingLevel}>
18
- <nav aria-labelledby="starlight__on-this-page">
19
- <h2 id="starlight__on-this-page">{t('tableOfContents.onThisPage')}</h2>
20
- <TableOfContentsList {toc} />
21
- </nav>
18
+ <nav aria-labelledby="starlight__on-this-page">
19
+ <h2 id="starlight__on-this-page">{t('tableOfContents.onThisPage')}</h2>
20
+ <TableOfContentsList {toc} />
21
+ </nav>
22
22
  </starlight-toc>
23
23
 
24
24
  <script src="./TableOfContents/starlight-toc"></script>
@@ -4,39 +4,35 @@ import Icon from '../user-components/Icon.astro';
4
4
 
5
5
  {/* This is intentionally inlined to avoid FOUC. */}
6
6
  <script is:inline>
7
- window.StarlightThemeProvider = (() => {
8
- const storedTheme =
9
- typeof localStorage !== 'undefined' &&
10
- localStorage.getItem('starlight-theme');
11
- const theme =
12
- storedTheme ||
13
- (window.matchMedia('(prefers-color-scheme: light)').matches
14
- ? 'light'
15
- : 'dark');
16
- document.documentElement.dataset.theme =
17
- theme === 'light' ? 'light' : 'dark';
18
- return {
19
- updatePickers(theme = storedTheme || 'auto') {
20
- document.querySelectorAll('starlight-theme-select').forEach((picker) => {
21
- const select = picker.querySelector('select');
22
- if (select) select.value = theme;
23
- /** @type {HTMLTemplateElement | null} */
24
- const tmpl = document.querySelector(`#theme-icons`);
25
- const newIcon = tmpl && tmpl.content.querySelector('.' + theme);
26
- if (newIcon) {
27
- const oldIcon = picker.querySelector('svg.label-icon');
28
- if (oldIcon) {
29
- oldIcon.replaceChildren(...newIcon.cloneNode(true).childNodes);
30
- }
31
- }
32
- });
33
- },
34
- };
35
- })();
7
+ window.StarlightThemeProvider = (() => {
8
+ const storedTheme =
9
+ typeof localStorage !== 'undefined' && localStorage.getItem('starlight-theme');
10
+ const theme =
11
+ storedTheme ||
12
+ (window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark');
13
+ document.documentElement.dataset.theme = theme === 'light' ? 'light' : 'dark';
14
+ return {
15
+ updatePickers(theme = storedTheme || 'auto') {
16
+ document.querySelectorAll('starlight-theme-select').forEach((picker) => {
17
+ const select = picker.querySelector('select');
18
+ if (select) select.value = theme;
19
+ /** @type {HTMLTemplateElement | null} */
20
+ const tmpl = document.querySelector(`#theme-icons`);
21
+ const newIcon = tmpl && tmpl.content.querySelector('.' + theme);
22
+ if (newIcon) {
23
+ const oldIcon = picker.querySelector('svg.label-icon');
24
+ if (oldIcon) {
25
+ oldIcon.replaceChildren(...newIcon.cloneNode(true).childNodes);
26
+ }
27
+ }
28
+ });
29
+ },
30
+ };
31
+ })();
36
32
  </script>
37
33
 
38
34
  <template id="theme-icons">
39
- <Icon name="sun" class="light" />
40
- <Icon name="moon" class="dark" />
41
- <Icon name="laptop" class="auto" />
35
+ <Icon name="sun" class="light" />
36
+ <Icon name="moon" class="dark" />
37
+ <Icon name="laptop" class="auto" />
42
38
  </template>
@@ -3,96 +3,91 @@ import { useTranslations } from '../utils/translations';
3
3
  import Select from './Select.astro';
4
4
 
5
5
  interface Props {
6
- locale: string | undefined;
6
+ locale: string | undefined;
7
7
  }
8
8
 
9
9
  const t = useTranslations(Astro.props.locale);
10
10
  ---
11
11
 
12
12
  <starlight-theme-select>
13
- {
14
- /* TODO: Can we give this select a width that works well for each language’s strings? */
15
- }
16
- <Select
17
- icon="laptop"
18
- label={t('themeSelect.accessibleLabel')}
19
- value="auto"
20
- options={[
21
- { label: t('themeSelect.dark'), selected: false, value: 'dark' },
22
- { label: t('themeSelect.light'), selected: false, value: 'light' },
23
- { label: t('themeSelect.auto'), selected: true, value: 'auto' },
24
- ]}
25
- width="6.25em"
26
- />
13
+ {/* TODO: Can we give this select a width that works well for each language’s strings? */}
14
+ <Select
15
+ icon="laptop"
16
+ label={t('themeSelect.accessibleLabel')}
17
+ value="auto"
18
+ options={[
19
+ { label: t('themeSelect.dark'), selected: false, value: 'dark' },
20
+ { label: t('themeSelect.light'), selected: false, value: 'light' },
21
+ { label: t('themeSelect.auto'), selected: true, value: 'auto' },
22
+ ]}
23
+ width="6.25em"
24
+ />
27
25
  </starlight-theme-select>
28
26
 
29
27
  {/* Inlined to avoid FOUC. Uses global scope from `ThemeProvider.astro` */}
30
28
  <script is:inline>
31
- StarlightThemeProvider.updatePickers();
29
+ StarlightThemeProvider.updatePickers();
32
30
  </script>
33
31
 
34
32
  <script>
35
- type Theme = 'auto' | 'dark' | 'light';
33
+ type Theme = 'auto' | 'dark' | 'light';
36
34
 
37
- class StarlightThemeSelect extends HTMLElement {
38
- /** Key in `localStorage` to store color theme preference at. */
39
- #key = 'starlight-theme';
35
+ class StarlightThemeSelect extends HTMLElement {
36
+ /** Key in `localStorage` to store color theme preference at. */
37
+ #key = 'starlight-theme';
40
38
 
41
- constructor() {
42
- super();
43
- this.#onThemeChange(this.#loadTheme());
44
- const select = this.querySelector('select');
45
- if (select) {
46
- select.addEventListener('change', (e) => {
47
- if (e.currentTarget instanceof HTMLSelectElement) {
48
- this.#onThemeChange(this.#parseTheme(e.currentTarget.value));
49
- }
50
- });
51
- }
52
- }
39
+ constructor() {
40
+ super();
41
+ this.#onThemeChange(this.#loadTheme());
42
+ const select = this.querySelector('select');
43
+ if (select) {
44
+ select.addEventListener('change', (e) => {
45
+ if (e.currentTarget instanceof HTMLSelectElement) {
46
+ this.#onThemeChange(this.#parseTheme(e.currentTarget.value));
47
+ }
48
+ });
49
+ }
50
+ }
53
51
 
54
- /** Get a typesafe theme string from any JS value (unknown values are coerced to `'auto'`). */
55
- #parseTheme(theme: unknown): Theme {
56
- if (theme === 'auto' || theme === 'dark' || theme === 'light') {
57
- return theme;
58
- } else {
59
- return 'auto';
60
- }
61
- }
52
+ /** Get a typesafe theme string from any JS value (unknown values are coerced to `'auto'`). */
53
+ #parseTheme(theme: unknown): Theme {
54
+ if (theme === 'auto' || theme === 'dark' || theme === 'light') {
55
+ return theme;
56
+ } else {
57
+ return 'auto';
58
+ }
59
+ }
62
60
 
63
- /** Get the preferred system color scheme. */
64
- #getPreferredColorScheme(): Theme {
65
- return matchMedia('(prefers-color-scheme: light)').matches
66
- ? 'light'
67
- : 'dark';
68
- }
61
+ /** Get the preferred system color scheme. */
62
+ #getPreferredColorScheme(): Theme {
63
+ return matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
64
+ }
69
65
 
70
- /** Update select menu UI, document theme, and local storage state. */
71
- #onThemeChange(theme: Theme): void {
72
- StarlightThemeProvider.updatePickers(theme);
73
- document.documentElement.dataset.theme =
74
- theme === 'auto' ? this.#getPreferredColorScheme() : theme;
75
- this.#storeTheme(theme);
76
- }
66
+ /** Update select menu UI, document theme, and local storage state. */
67
+ #onThemeChange(theme: Theme): void {
68
+ StarlightThemeProvider.updatePickers(theme);
69
+ document.documentElement.dataset.theme =
70
+ theme === 'auto' ? this.#getPreferredColorScheme() : theme;
71
+ this.#storeTheme(theme);
72
+ }
77
73
 
78
- /** Store the user’s preference in `localStorage`. */
79
- #storeTheme(theme: Theme): void {
80
- if (typeof localStorage !== 'undefined') {
81
- if (theme === 'light' || theme === 'dark') {
82
- localStorage.setItem(this.#key, theme);
83
- } else {
84
- localStorage.removeItem(this.#key);
85
- }
86
- }
87
- }
74
+ /** Store the user’s preference in `localStorage`. */
75
+ #storeTheme(theme: Theme): void {
76
+ if (typeof localStorage !== 'undefined') {
77
+ if (theme === 'light' || theme === 'dark') {
78
+ localStorage.setItem(this.#key, theme);
79
+ } else {
80
+ localStorage.removeItem(this.#key);
81
+ }
82
+ }
83
+ }
88
84
 
89
- /** Load the user’s preference from `localStorage`. */
90
- #loadTheme(): Theme {
91
- const theme =
92
- typeof localStorage !== 'undefined' && localStorage.getItem(this.#key);
93
- return this.#parseTheme(theme);
94
- }
95
- }
85
+ /** Load the user’s preference from `localStorage`. */
86
+ #loadTheme(): Theme {
87
+ const theme = typeof localStorage !== 'undefined' && localStorage.getItem(this.#key);
88
+ return this.#parseTheme(theme);
89
+ }
90
+ }
96
91
 
97
- customElements.define('starlight-theme-select', StarlightThemeSelect);
92
+ customElements.define('starlight-theme-select', StarlightThemeSelect);
98
93
  </script>
package/global.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  declare global {
2
- var StarlightThemeProvider: {
3
- updatePickers(theme?: string): void;
4
- };
2
+ var StarlightThemeProvider: {
3
+ updatePickers(theme?: string): void;
4
+ };
5
5
  }
package/index.astro CHANGED
@@ -5,7 +5,7 @@ import { paths } from './utils/routing';
5
5
  import Page from './layout/Page.astro';
6
6
 
7
7
  export async function getStaticPaths() {
8
- return paths;
8
+ return paths;
9
9
  }
10
10
 
11
11
  type Props = InferGetStaticPropsType<typeof getStaticPaths>;
package/index.ts CHANGED
@@ -7,69 +7,62 @@ import { starlightAsides } from './integrations/asides';
7
7
  import { starlightSitemap } from './integrations/sitemap';
8
8
  import { vitePluginStarlightUserConfig } from './integrations/virtual-user-config';
9
9
  import { errorMap } from './utils/error-map';
10
- import {
11
- StarlightConfigSchema,
12
- StarlightUserConfig,
13
- } from './utils/user-config';
10
+ import { StarlightConfigSchema, StarlightUserConfig } from './utils/user-config';
14
11
 
15
- export default function StarlightIntegration(
16
- opts: StarlightUserConfig
17
- ): AstroIntegration[] {
18
- const parsedConfig = StarlightConfigSchema.safeParse(opts, { errorMap });
12
+ export default function StarlightIntegration(opts: StarlightUserConfig): AstroIntegration[] {
13
+ const parsedConfig = StarlightConfigSchema.safeParse(opts, { errorMap });
19
14
 
20
- if (!parsedConfig.success) {
21
- throw new Error(
22
- 'Invalid config passed to starlight integration\n' +
23
- parsedConfig.error.issues.map((i) => i.message).join('\n')
24
- );
25
- }
15
+ if (!parsedConfig.success) {
16
+ throw new Error(
17
+ 'Invalid config passed to starlight integration\n' +
18
+ parsedConfig.error.issues.map((i) => i.message).join('\n')
19
+ );
20
+ }
26
21
 
27
- const userConfig = parsedConfig.data;
22
+ const userConfig = parsedConfig.data;
28
23
 
29
- const Starlight: AstroIntegration = {
30
- name: '@astrojs/starlight',
31
- hooks: {
32
- 'astro:config:setup': ({ config, injectRoute, updateConfig }) => {
33
- injectRoute({
34
- pattern: '404',
35
- entryPoint: '@astrojs/starlight/404.astro',
36
- });
37
- injectRoute({
38
- pattern: '[...slug]',
39
- entryPoint: '@astrojs/starlight/index.astro',
40
- });
41
- const newConfig: AstroUserConfig = {
42
- vite: {
43
- plugins: [vitePluginStarlightUserConfig(userConfig, config)],
44
- },
45
- markdown: {
46
- remarkPlugins: [...starlightAsides()],
47
- shikiConfig:
48
- // Configure Shiki theme if the user is using the default github-dark theme.
49
- config.markdown.shikiConfig.theme !== 'github-dark'
50
- ? {}
51
- : { theme: 'css-variables' },
52
- },
53
- build: { inlineStylesheets: 'auto' },
54
- experimental: { assets: true, inlineStylesheets: 'auto' },
55
- };
56
- updateConfig(newConfig);
57
- },
24
+ const Starlight: AstroIntegration = {
25
+ name: '@astrojs/starlight',
26
+ hooks: {
27
+ 'astro:config:setup': ({ config, injectRoute, updateConfig }) => {
28
+ injectRoute({
29
+ pattern: '404',
30
+ entryPoint: '@astrojs/starlight/404.astro',
31
+ });
32
+ injectRoute({
33
+ pattern: '[...slug]',
34
+ entryPoint: '@astrojs/starlight/index.astro',
35
+ });
36
+ const newConfig: AstroUserConfig = {
37
+ vite: {
38
+ plugins: [vitePluginStarlightUserConfig(userConfig, config)],
39
+ },
40
+ markdown: {
41
+ remarkPlugins: [...starlightAsides()],
42
+ shikiConfig:
43
+ // Configure Shiki theme if the user is using the default github-dark theme.
44
+ config.markdown.shikiConfig.theme !== 'github-dark' ? {} : { theme: 'css-variables' },
45
+ },
46
+ build: { inlineStylesheets: 'auto' },
47
+ experimental: { assets: true, inlineStylesheets: 'auto' },
48
+ };
49
+ updateConfig(newConfig);
50
+ },
58
51
 
59
- 'astro:build:done': ({ dir }) => {
60
- const targetDir = fileURLToPath(dir);
61
- const cwd = dirname(fileURLToPath(import.meta.url));
62
- const relativeDir = relative(cwd, targetDir);
63
- return new Promise<void>((resolve) => {
64
- spawn('npx', ['-y', 'pagefind', '--source', relativeDir], {
65
- stdio: 'inherit',
66
- shell: true,
67
- cwd,
68
- }).on('close', () => resolve());
69
- });
70
- },
71
- },
72
- };
52
+ 'astro:build:done': ({ dir }) => {
53
+ const targetDir = fileURLToPath(dir);
54
+ const cwd = dirname(fileURLToPath(import.meta.url));
55
+ const relativeDir = relative(cwd, targetDir);
56
+ return new Promise<void>((resolve) => {
57
+ spawn('npx', ['-y', 'pagefind', '--source', relativeDir], {
58
+ stdio: 'inherit',
59
+ shell: true,
60
+ cwd,
61
+ }).on('close', () => resolve());
62
+ });
63
+ },
64
+ },
65
+ };
73
66
 
74
- return [starlightSitemap(userConfig), Starlight, mdx()];
67
+ return [starlightSitemap(userConfig), Starlight, mdx()];
75
68
  }