@grove-dev/starlight 0.7.0 → 0.8.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 (34) hide show
  1. package/components/custom/ContainerSection.astro +1 -1
  2. package/components/custom/LinkButton.astro +7 -7
  3. package/components/custom/dropdown/Dropdown.astro +5 -5
  4. package/components/custom/dropdown/DropdownContent.astro +26 -26
  5. package/components/custom/dropdown/DropdownItem.astro +8 -8
  6. package/components/custom/dropdown/DropdownLabel.astro +4 -4
  7. package/components/custom/dropdown/DropdownTrigger.astro +12 -12
  8. package/components/custom/dropdown/index.ts +14 -14
  9. package/components/overrides/Footer.astro +3 -3
  10. package/components/overrides/Header.astro +5 -6
  11. package/components/overrides/Hero.astro +17 -17
  12. package/components/overrides/PageFrame.astro +11 -11
  13. package/components/overrides/PageTitle.astro +3 -3
  14. package/components/overrides/Search.astro +6 -6
  15. package/components/overrides/parts/Drawer.astro +5 -5
  16. package/components/overrides/parts/NavBar.astro +5 -5
  17. package/components/overrides/parts/SidebarSublist.astro +2 -2
  18. package/components/overrides/parts/toc/TableOfContentsList.astro +4 -4
  19. package/components/overrides/parts/toc/starlight-toc.ts +96 -98
  20. package/core/config/docs-schema.ts +20 -20
  21. package/core/config/expresive-code.ts +49 -51
  22. package/core/config/override.ts +36 -36
  23. package/core/config/schemas.ts +59 -59
  24. package/core/config/vite.ts +12 -12
  25. package/core/i18n.ts +113 -113
  26. package/core/plugin.ts +42 -42
  27. package/core/sidebar.ts +4 -4
  28. package/global.d.ts +3 -3
  29. package/package.json +1 -1
  30. package/schema.ts +39 -39
  31. package/styles/base.css +866 -907
  32. package/styles/theme.css +61 -61
  33. package/user-components.ts +1 -1
  34. package/virtual.d.ts +27 -27
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  type Props = {
3
- width?: 'sm' | 'md' | 'lg' | 'xl';
3
+ width?: 'sm' | 'md' | 'lg' | 'xl';
4
4
  };
5
5
 
6
6
  const { width = 'lg' } = Astro.props;
@@ -10,22 +10,22 @@ export type ButtonVariant = 'default' | 'link' | 'secondary' | 'outline' | 'ghos
10
10
  export type LegacyButtonVariant = 'primary' | 'minimal';
11
11
 
12
12
  const LEGACY_VARIANTS = {
13
- primary: 'default',
14
- minimal: 'ghost',
13
+ primary: 'default',
14
+ minimal: 'ghost',
15
15
  } as const satisfies Record<LegacyButtonVariant, ButtonVariant>;
16
16
 
17
17
  type Props = (Omit<HTMLAttributes<'a'>, 'href'> | HTMLAttributes<'button'>) & {
18
- /** Renders an `<a>` when set, a `<button>` otherwise. */
19
- href?: string | URL | null | undefined;
20
- variant?: ButtonVariant | LegacyButtonVariant;
21
- size?: '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'icon-sm' | 'icon-md' | 'icon-lg';
18
+ /** Renders an `<a>` when set, a `<button>` otherwise. */
19
+ href?: string | URL | null | undefined;
20
+ variant?: ButtonVariant | LegacyButtonVariant;
21
+ size?: '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'icon-sm' | 'icon-md' | 'icon-lg';
22
22
  };
23
23
 
24
24
  const { class: className, variant = 'default', size = 'md', ...attrs } = Astro.props;
25
25
 
26
26
  // Normalise so the stylesheet only ever has to know about the canonical variant names.
27
27
  const resolvedVariant: ButtonVariant =
28
- LEGACY_VARIANTS[variant as LegacyButtonVariant] ?? (variant as ButtonVariant);
28
+ LEGACY_VARIANTS[variant as LegacyButtonVariant] ?? (variant as ButtonVariant);
29
29
 
30
30
  const Tag = attrs.href ? 'a' : 'button';
31
31
  ---
@@ -2,11 +2,11 @@
2
2
  import type { HTMLAttributes } from 'astro/types';
3
3
 
4
4
  type Props = HTMLAttributes<'div'> & {
5
- /** When true, the dropdown will open on hover in addition to click */
6
- openOnHover?: boolean;
7
- /** Time in milliseconds to wait before closing when hover open is enabled (defaults to 200) */
8
- closeDelay?: number;
9
- children: any;
5
+ /** When true, the dropdown will open on hover in addition to click */
6
+ openOnHover?: boolean;
7
+ /** Time in milliseconds to wait before closing when hover open is enabled (defaults to 200) */
8
+ closeDelay?: number;
9
+ children: any;
10
10
  };
11
11
 
12
12
  const { class: className, openOnHover = false, closeDelay = 200, ...rest } = Astro.props;
@@ -2,35 +2,35 @@
2
2
  import type { HTMLAttributes } from 'astro/types';
3
3
 
4
4
  type Props = HTMLAttributes<'div'> & {
5
- /**
6
- * Side of the dropdown
7
- * @default bottom
8
- */
9
- side?: 'top' | 'bottom' | 'left' | 'right';
10
- /**
11
- * Alignment of the dropdown
12
- * @default start
13
- */
14
- align?: 'start' | 'center' | 'end';
15
- /**
16
- * Offset distance in pixels
17
- * @default 4
18
- */
19
- sideOffset?: number;
20
- /**
21
- * Open and close animation duration in milliseconds
22
- * @default 150
23
- */
24
- animationDuration?: number;
5
+ /**
6
+ * Side of the dropdown
7
+ * @default bottom
8
+ */
9
+ side?: 'top' | 'bottom' | 'left' | 'right';
10
+ /**
11
+ * Alignment of the dropdown
12
+ * @default start
13
+ */
14
+ align?: 'start' | 'center' | 'end';
15
+ /**
16
+ * Offset distance in pixels
17
+ * @default 4
18
+ */
19
+ sideOffset?: number;
20
+ /**
21
+ * Open and close animation duration in milliseconds
22
+ * @default 150
23
+ */
24
+ animationDuration?: number;
25
25
  };
26
26
 
27
27
  const {
28
- class: className,
29
- side = 'bottom',
30
- align = 'start',
31
- sideOffset = 4,
32
- animationDuration = 150,
33
- ...rest
28
+ class: className,
29
+ side = 'bottom',
30
+ align = 'start',
31
+ sideOffset = 4,
32
+ animationDuration = 150,
33
+ ...rest
34
34
  } = Astro.props;
35
35
  ---
36
36
 
@@ -2,14 +2,14 @@
2
2
  import type { HTMLTag, Polymorphic } from 'astro/types';
3
3
 
4
4
  type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }> & {
5
- /**
6
- * Whether the item is inset (has left padding)
7
- */
8
- inset?: boolean;
9
- /**
10
- * Whether the item is disabled
11
- */
12
- disabled?: boolean;
5
+ /**
6
+ * Whether the item is inset (has left padding)
7
+ */
8
+ inset?: boolean;
9
+ /**
10
+ * Whether the item is disabled
11
+ */
12
+ disabled?: boolean;
13
13
  };
14
14
 
15
15
  const { class: className, inset = false, disabled = false, as: Tag = 'div', ...rest } = Astro.props;
@@ -2,10 +2,10 @@
2
2
  import type { HTMLAttributes } from 'astro/types';
3
3
 
4
4
  type Props = HTMLAttributes<'div'> & {
5
- /**
6
- * Whether the label is inset (has left padding)
7
- */
8
- inset?: boolean;
5
+ /**
6
+ * Whether the label is inset (has left padding)
7
+ */
8
+ inset?: boolean;
9
9
  };
10
10
 
11
11
  const { class: className, inset = false, ...rest } = Astro.props;
@@ -3,27 +3,27 @@ import type { HTMLAttributes } from 'astro/types';
3
3
  import LinkButton, { type ButtonVariant, type LegacyButtonVariant } from '../LinkButton.astro';
4
4
 
5
5
  type Props = Omit<HTMLAttributes<'button'>, 'role' | 'type'> & {
6
- /**
7
- * When true, the component will render its child element with a simple wrapper instead of a button component
8
- */
9
- asChild?: boolean;
6
+ /**
7
+ * When true, the component will render its child element with a simple wrapper instead of a button component
8
+ */
9
+ asChild?: boolean;
10
10
 
11
- variant?: ButtonVariant | LegacyButtonVariant;
12
- size?: '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'icon-sm' | 'icon-md' | 'icon-lg';
11
+ variant?: ButtonVariant | LegacyButtonVariant;
12
+ size?: '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'icon-sm' | 'icon-md' | 'icon-lg';
13
13
  };
14
14
 
15
15
  const {
16
- class: className,
17
- variant = 'secondary',
18
- size = 'sm',
19
- asChild = false,
20
- ...rest
16
+ class: className,
17
+ variant = 'secondary',
18
+ size = 'sm',
19
+ asChild = false,
20
+ ...rest
21
21
  } = Astro.props;
22
22
 
23
23
  // Get the first child element if asChild is true
24
24
  let hasChildren = false;
25
25
  if (Astro.slots.has('default')) {
26
- hasChildren = true;
26
+ hasChildren = true;
27
27
  }
28
28
  ---
29
29
 
@@ -9,21 +9,21 @@ import DropdownShortcut from './DropdownShortcut.astro';
9
9
  import DropdownTrigger from './DropdownTrigger.astro';
10
10
 
11
11
  export {
12
- Dropdown,
13
- DropdownContent,
14
- DropdownItem,
15
- DropdownLabel,
16
- DropdownSeparator,
17
- DropdownShortcut,
18
- DropdownTrigger,
12
+ Dropdown,
13
+ DropdownContent,
14
+ DropdownItem,
15
+ DropdownLabel,
16
+ DropdownSeparator,
17
+ DropdownShortcut,
18
+ DropdownTrigger,
19
19
  };
20
20
 
21
21
  export default {
22
- Root: Dropdown,
23
- Trigger: DropdownTrigger,
24
- Content: DropdownContent,
25
- Item: DropdownItem,
26
- Label: DropdownLabel,
27
- Separator: DropdownSeparator,
28
- Shortcut: DropdownShortcut,
22
+ Root: Dropdown,
23
+ Trigger: DropdownTrigger,
24
+ Content: DropdownContent,
25
+ Item: DropdownItem,
26
+ Label: DropdownLabel,
27
+ Separator: DropdownSeparator,
28
+ Shortcut: DropdownShortcut,
29
29
  };
@@ -5,9 +5,9 @@ import Pagination from 'virtual:starlight/components/Pagination';
5
5
  import config from 'virtual:starlight/user-config';
6
6
 
7
7
  const {
8
- entry: {
9
- data: { template },
10
- },
8
+ entry: {
9
+ data: { template },
10
+ },
11
11
  } = Astro.locals.starlightRoute;
12
12
 
13
13
  const { lastUpdated: showLastUpdated, editLink } = config;
@@ -1,17 +1,16 @@
1
1
  ---
2
2
  import config from 'virtual:starlight/user-config';
3
+ import LanguageSelect from '@astrojs/starlight/components/LanguageSelect.astro';
4
+ import MobileMenuToggle from './parts/MobileMenuToggle.astro';
5
+ import NavBar from './parts/NavBar.astro';
3
6
  import Search from './Search.astro';
7
+ import SiteTitle from './SiteTitle.astro';
4
8
  import SocialIcons from './SocialIcons.astro';
5
- import LanguageSelect from '@astrojs/starlight/components/LanguageSelect.astro';
6
-
7
9
  import ThemeSelect from './ThemeSelect.astro';
8
- import SiteTitle from './SiteTitle.astro';
9
- import NavBar from './parts/NavBar.astro';
10
- import MobileMenuToggle from './parts/MobileMenuToggle.astro';
11
10
 
12
11
  /** render the `Search` component if Pagefind is enabled or the default search component has been overridden. */
13
12
  const shouldRenderSearch =
14
- config.pagefind || config.components.Search !== '@astrojs/starlight/components/Search.astro';
13
+ config.pagefind || config.components.Search !== '@astrojs/starlight/components/Search.astro';
15
14
  ---
16
15
 
17
16
  <MobileMenuToggle />
@@ -1,6 +1,6 @@
1
1
  ---
2
- import { Icon } from '@astrojs/starlight/components';
3
2
  import { Image } from 'astro:assets';
3
+ import { Icon } from '@astrojs/starlight/components';
4
4
  import { PAGE_TITLE_ID } from '../../core/config/constants';
5
5
  import { warnAboutMissingDocsSchemaOnce } from '../../core/config/docs-schema';
6
6
  import ContainerSection from '../custom/ContainerSection.astro';
@@ -11,11 +11,11 @@ const { data } = Astro.locals.starlightRoute.entry;
11
11
  warnAboutMissingDocsSchemaOnce(data.hero);
12
12
 
13
13
  const {
14
- title = data.title,
15
- tagline: heroTagline,
16
- image,
17
- announcement,
18
- actions = [],
14
+ title = data.title,
15
+ tagline: heroTagline,
16
+ image,
17
+ announcement,
18
+ actions = [],
19
19
  } = data.hero || {};
20
20
 
21
21
  // Falls back on an empty tagline too, not just a missing one.
@@ -23,9 +23,9 @@ const tagline = heroTagline || data.description;
23
23
 
24
24
  const hasImage = !!image;
25
25
  const imageAttrs = {
26
- loading: 'eager' as const,
27
- decoding: 'async' as const,
28
- alt: image?.alt || '',
26
+ loading: 'eager' as const,
27
+ decoding: 'async' as const,
28
+ alt: image?.alt || '',
29
29
  };
30
30
 
31
31
  let darkImage: ImageMetadata | undefined;
@@ -33,14 +33,14 @@ let lightImage: ImageMetadata | undefined;
33
33
  let rawHtml: string | undefined;
34
34
 
35
35
  if (image) {
36
- if ('file' in image) {
37
- darkImage = image.file;
38
- } else if ('dark' in image) {
39
- darkImage = image.dark;
40
- lightImage = image.light;
41
- } else {
42
- rawHtml = image.html;
43
- }
36
+ if ('file' in image) {
37
+ darkImage = image.file;
38
+ } else if ('dark' in image) {
39
+ darkImage = image.dark;
40
+ lightImage = image.light;
41
+ } else {
42
+ rawHtml = image.html;
43
+ }
44
44
  }
45
45
  ---
46
46
 
@@ -1,29 +1,29 @@
1
1
  ---
2
- import { AstroError } from 'astro/errors';
3
- import { marked } from 'marked';
4
2
  import userConfig from 'virtual:grove-starlight-config';
5
3
  import starlightConfig from 'virtual:starlight/user-config';
4
+ import { AstroError } from 'astro/errors';
5
+ import { marked } from 'marked';
6
6
  import { createLocaleLookup, resolveLocalizedString } from '../../core/i18n';
7
7
  import Drawer from './parts/Drawer.astro';
8
8
 
9
9
  const { hasSidebar, lang, locale } = Astro.locals.starlightRoute;
10
10
 
11
11
  const localeKeys = createLocaleLookup({
12
- lang,
13
- locale: Astro.currentLocale ?? locale,
14
- defaultLang: starlightConfig.defaultLocale?.lang,
15
- defaultLocale: starlightConfig.defaultLocale?.locale,
12
+ lang,
13
+ locale: Astro.currentLocale ?? locale,
14
+ defaultLang: starlightConfig.defaultLocale?.lang,
15
+ defaultLocale: starlightConfig.defaultLocale?.locale,
16
16
  });
17
17
 
18
18
  let footerText: string;
19
19
 
20
20
  try {
21
- footerText = resolveLocalizedString(userConfig.footerText, localeKeys);
21
+ footerText = resolveLocalizedString(userConfig.footerText, localeKeys);
22
22
  } catch (error) {
23
- throw new AstroError(
24
- error instanceof Error ? error.message : 'Invalid footerText localization.',
25
- 'Update the Grove config so footerText includes a key for the default language.'
26
- );
23
+ throw new AstroError(
24
+ error instanceof Error ? error.message : 'Invalid footerText localization.',
25
+ 'Update the Grove config so footerText includes a key for the default language.',
26
+ );
27
27
  }
28
28
  ---
29
29
 
@@ -1,13 +1,13 @@
1
1
  ---
2
+ import userConfig from 'virtual:grove-starlight-config';
2
3
  import { Icon } from '@astrojs/starlight/components';
3
4
  import { PAGE_TITLE_ID } from '../../core/config/constants';
4
- import userConfig from 'virtual:grove-starlight-config';
5
5
  import { Dropdown, DropdownContent, DropdownItem, DropdownTrigger } from '../custom/dropdown';
6
6
  import LinkButton from '../custom/LinkButton.astro';
7
7
 
8
8
  const {
9
- entry: { data },
10
- pagination: { prev, next },
9
+ entry: { data },
10
+ pagination: { prev, next },
11
11
  } = Astro.locals.starlightRoute;
12
12
 
13
13
  const { title, description } = data;
@@ -3,12 +3,12 @@ import '@pagefind/default-ui/css/ui.css';
3
3
  import project from 'virtual:starlight/project-context';
4
4
 
5
5
  const pagefindTranslations = {
6
- placeholder: Astro.locals.t('search.label'),
7
- ...Object.fromEntries(
8
- Object.entries(Astro.locals.t.all())
9
- .filter(([key]) => key.startsWith('pagefind.'))
10
- .map(([key, value]) => [key.replace('pagefind.', ''), value])
11
- ),
6
+ placeholder: Astro.locals.t('search.label'),
7
+ ...Object.fromEntries(
8
+ Object.entries(Astro.locals.t.all())
9
+ .filter(([key]) => key.startsWith('pagefind.'))
10
+ .map(([key, value]) => [key.replace('pagefind.', ''), value]),
11
+ ),
12
12
  };
13
13
 
14
14
  const dataAttributes: DOMStringMap = { 'data-translations': JSON.stringify(pagefindTranslations) };
@@ -1,7 +1,7 @@
1
1
  ---
2
+ import { getRelativeLocaleUrl } from 'astro:i18n';
2
3
  import userConfig from 'virtual:grove-starlight-config';
3
4
  import starlightConfig from 'virtual:starlight/user-config';
4
- import { getRelativeLocaleUrl } from 'astro:i18n';
5
5
  import { createLocaleLookup, resolveNavLabel } from '../../../core/i18n';
6
6
 
7
7
  const { sidebar, lang, locale } = Astro.locals.starlightRoute;
@@ -9,10 +9,10 @@ const { sidebar, lang, locale } = Astro.locals.starlightRoute;
9
9
  const currentPath = Astro.url.pathname;
10
10
 
11
11
  const localeKeys = createLocaleLookup({
12
- lang,
13
- locale: Astro.currentLocale ?? locale,
14
- defaultLang: starlightConfig.defaultLocale?.lang,
15
- defaultLocale: starlightConfig.defaultLocale?.locale,
12
+ lang,
13
+ locale: Astro.currentLocale ?? locale,
14
+ defaultLang: starlightConfig.defaultLocale?.lang,
15
+ defaultLocale: starlightConfig.defaultLocale?.locale,
16
16
  });
17
17
  ---
18
18
 
@@ -1,7 +1,7 @@
1
1
  ---
2
+ import { getRelativeLocaleUrl } from 'astro:i18n';
2
3
  import userConfig from 'virtual:grove-starlight-config';
3
4
  import starlightConfig from 'virtual:starlight/user-config';
4
- import { getRelativeLocaleUrl } from 'astro:i18n';
5
5
  import { createLocaleLookup, resolveNavLabel } from '../../../core/i18n';
6
6
 
7
7
  const currentPath = Astro.url.pathname;
@@ -9,10 +9,10 @@ const currentPath = Astro.url.pathname;
9
9
  const { lang, locale } = Astro.locals.starlightRoute;
10
10
 
11
11
  const localeKeys = createLocaleLookup({
12
- lang,
13
- locale: Astro.currentLocale ?? locale,
14
- defaultLang: starlightConfig.defaultLocale?.lang,
15
- defaultLocale: starlightConfig.defaultLocale?.locale,
12
+ lang,
13
+ locale: Astro.currentLocale ?? locale,
14
+ defaultLang: starlightConfig.defaultLocale?.lang,
15
+ defaultLocale: starlightConfig.defaultLocale?.locale,
16
16
  });
17
17
  ---
18
18
 
@@ -5,8 +5,8 @@ import type { StarlightRouteData } from '@astrojs/starlight/route-data';
5
5
  import { isSidebarGroupOpen } from '../../../core/sidebar';
6
6
 
7
7
  interface Props {
8
- sublist: StarlightRouteData['sidebar'];
9
- nested?: boolean;
8
+ sublist: StarlightRouteData['sidebar'];
9
+ nested?: boolean;
10
10
  }
11
11
 
12
12
  const { sublist, nested = false } = Astro.props;
@@ -2,13 +2,13 @@
2
2
  import type { MarkdownHeading } from 'astro';
3
3
 
4
4
  interface TocItem extends MarkdownHeading {
5
- children: TocItem[];
5
+ children: TocItem[];
6
6
  }
7
7
 
8
8
  interface Props {
9
- toc: TocItem[];
10
- depth?: number;
11
- isMobile?: boolean;
9
+ toc: TocItem[];
10
+ depth?: number;
11
+ isMobile?: boolean;
12
12
  }
13
13
 
14
14
  const { toc, depth = 0 } = Astro.props;