@grove-dev/starlight 0.6.1 → 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 (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -78
  3. package/components/custom/ContainerSection.astro +1 -1
  4. package/components/custom/LinkButton.astro +134 -89
  5. package/components/custom/dropdown/Dropdown.astro +5 -5
  6. package/components/custom/dropdown/DropdownContent.astro +66 -66
  7. package/components/custom/dropdown/DropdownItem.astro +14 -9
  8. package/components/custom/dropdown/DropdownLabel.astro +4 -4
  9. package/components/custom/dropdown/DropdownTrigger.astro +13 -13
  10. package/components/custom/dropdown/index.ts +14 -14
  11. package/components/overrides/Footer.astro +3 -3
  12. package/components/overrides/Header.astro +5 -6
  13. package/components/overrides/Hero.astro +20 -12
  14. package/components/overrides/PageFrame.astro +25 -9
  15. package/components/overrides/PageSidebar.astro +1 -0
  16. package/components/overrides/PageTitle.astro +3 -3
  17. package/components/overrides/Search.astro +6 -6
  18. package/components/overrides/Sidebar.astro +38 -1
  19. package/components/overrides/SocialIcons.astro +3 -1
  20. package/components/overrides/ThemeSelect.astro +4 -4
  21. package/components/overrides/TwoColumnContent.astro +1 -1
  22. package/components/overrides/parts/Drawer.astro +13 -7
  23. package/components/overrides/parts/NavBar.astro +12 -31
  24. package/components/overrides/parts/SidebarSublist.astro +75 -4
  25. package/components/overrides/parts/toc/TableOfContentsList.astro +4 -4
  26. package/components/overrides/parts/toc/starlight-toc.ts +96 -98
  27. package/core/config/docs-schema.ts +58 -0
  28. package/core/config/expresive-code.ts +49 -51
  29. package/core/config/override.ts +37 -33
  30. package/core/config/schemas.ts +62 -41
  31. package/core/config/vite.ts +14 -14
  32. package/core/i18n.ts +175 -0
  33. package/core/plugin.ts +45 -43
  34. package/core/sidebar.ts +22 -0
  35. package/global.d.ts +3 -3
  36. package/package.json +3 -19
  37. package/schema.ts +44 -13
  38. package/styles/base.css +883 -896
  39. package/styles/layers.css +1 -1
  40. package/styles/theme.css +62 -62
  41. package/user-components.ts +1 -2
  42. package/virtual.d.ts +28 -28
  43. package/THIRD_PARTY_LICENSES.md +0 -68
  44. package/components/custom/Card.astro +0 -118
@@ -1,48 +1,52 @@
1
1
  import type { HookParameters } from '@astrojs/starlight/types';
2
2
  import type { AstroIntegrationLogger } from 'astro';
3
+ import type { GroveStarlightConfig } from './schemas';
3
4
 
4
5
  type StarlightUserConfig = HookParameters<'config:setup'>['config'];
5
6
  type ComponentOverride = keyof NonNullable<StarlightUserConfig['components']>;
6
7
 
7
8
  export const COMPONENT_OVERRIDES: ComponentOverride[] = [
8
- 'ThemeSelect',
9
- 'PageFrame',
10
- 'Header',
11
- 'SiteTitle',
12
- 'Sidebar',
13
- 'TwoColumnContent',
14
- 'ContentPanel',
15
- 'PageTitle',
16
- 'MarkdownContent',
17
- 'Hero',
18
- 'Footer',
19
- 'SocialIcons',
20
- 'Pagination',
21
- 'Search',
22
- 'TableOfContents',
23
- 'PageSidebar',
9
+ 'ThemeSelect',
10
+ 'PageFrame',
11
+ 'Header',
12
+ 'SiteTitle',
13
+ 'Sidebar',
14
+ 'TwoColumnContent',
15
+ 'ContentPanel',
16
+ 'PageTitle',
17
+ 'MarkdownContent',
18
+ 'Hero',
19
+ 'Footer',
20
+ 'SocialIcons',
21
+ 'Pagination',
22
+ 'Search',
23
+ 'TableOfContents',
24
+ 'PageSidebar',
24
25
  ];
25
26
 
26
27
  export function override(
27
- starlightConfig: StarlightUserConfig,
28
- overrides: ComponentOverride[],
29
- logger: AstroIntegrationLogger
28
+ starlightConfig: StarlightUserConfig,
29
+ pluginConfig: GroveStarlightConfig,
30
+ overrides: ComponentOverride[],
31
+ logger: AstroIntegrationLogger,
30
32
  ): StarlightUserConfig['components'] {
31
- const components = { ...starlightConfig.components };
32
- for (const override of overrides) {
33
- if (starlightConfig.components?.[override] != null) {
34
- const fallback = `@grove-dev/starlight/components/overrides/${override}.astro`;
33
+ const components = { ...starlightConfig.components };
34
+ for (const override of overrides) {
35
+ if (starlightConfig.components?.[override] != null) {
36
+ const fallback = `@grove-dev/starlight/components/overrides/${override}.astro`;
35
37
 
36
- logger.warn(
37
- `A \`<${override}>\` component override is already defined in your Starlight configuration.`
38
- );
39
- logger.warn(
40
- `To use \`@grove-dev/starlight/components\`, either remove this override or manually render the content from \`${fallback}\`.`
41
- );
42
- continue;
43
- }
44
- components[override] = `@grove-dev/starlight/components/overrides/${override}.astro`;
38
+ if (pluginConfig.warnOverrides) {
39
+ logger.warn(
40
+ `A \`<${override}>\` component override is already defined in your Starlight configuration.`,
41
+ );
42
+ logger.warn(
43
+ `To use \`@grove-dev/starlight/components\`, either remove this override or manually render the content from \`${fallback}\`.`,
44
+ );
45
+ }
46
+ continue;
45
47
  }
48
+ components[override] = `@grove-dev/starlight/components/overrides/${override}.astro`;
49
+ }
46
50
 
47
- return components;
51
+ return components;
48
52
  }
@@ -3,55 +3,76 @@ import type { HTMLAttributes } from 'astro/types';
3
3
  import { z } from 'astro/zod';
4
4
 
5
5
  const linkHTMLAttributesSchema = z.record(
6
- z.string(),
7
- z.union([z.string(), z.number(), z.boolean(), z.undefined()])
6
+ z.string(),
7
+ z.union([z.string(), z.number(), z.boolean(), z.undefined()]),
8
8
  ) as z.Schema<Omit<HTMLAttributes<'a'>, keyof AstroBuiltinAttributes | 'children'>>;
9
9
 
10
10
  const LinkItemHTMLAttributesSchema = () => linkHTMLAttributesSchema.default({});
11
11
 
12
12
  export const linkSchema = z.object({
13
- /**
14
- * An optional badge to display next to the topic label.
15
- *
16
- * This option accepts the same configuration as the Starlight badge sidebar item configuration.
17
- * @see https://starlight.astro.build/guides/sidebar/#badges
18
- */
19
- badge: z.string().optional(),
20
- /**
21
- * The topic label visible at the top of the sidebar.
22
- *
23
- * The value can be a string, or for multilingual sites, an object with values for each different locale. When using
24
- * the object form, the keys must be BCP-47 tags (e.g. en, fr, or zh-CN).
25
- */
26
- label: z.union([z.string(), z.record(z.string(), z.string())]),
27
- /**
28
- * The link to the topic’s content which an be a relative link to local files or the full URL of an external page.
29
- *
30
- * For internal links, the link can either be a page included in the items array or a different page acting as the
31
- * topic’s landing page.
32
- */
33
- link: z.string(),
34
- /** HTML attributes to add to the link item. */
35
- attrs: LinkItemHTMLAttributesSchema().optional(),
13
+ /**
14
+ * An optional badge to display next to the topic label.
15
+ *
16
+ * This option accepts the same configuration as the Starlight badge sidebar item configuration.
17
+ * @see https://starlight.astro.build/guides/sidebar/#badges
18
+ */
19
+ badge: z.string().optional(),
20
+ /**
21
+ * The link label.
22
+ *
23
+ * - A string used as the default-locale label (pair with `translations` for other languages).
24
+ * - Or a locale map keyed by BCP-47 tags / locale paths (e.g. `en`, `es`).
25
+ *
26
+ * @see https://starlight.astro.build/guides/sidebar/#internationalization
27
+ */
28
+ label: z.union([z.string(), z.record(z.string(), z.string())]),
29
+ /**
30
+ * Optional labels for other languages when `label` is a string.
31
+ * Keys should be BCP-47 tags (e.g. `en`, `es`), matching Starlight sidebar translations.
32
+ *
33
+ * @see https://starlight.astro.build/guides/sidebar/#internationalization
34
+ */
35
+ translations: z.record(z.string(), z.string()).optional(),
36
+ /**
37
+ * The link to the topic’s content which an be a relative link to local files or the full URL of an external page.
38
+ *
39
+ * For internal links, the link can either be a page included in the items array or a different page acting as the
40
+ * topic’s landing page.
41
+ */
42
+ link: z.string(),
43
+ /** HTML attributes to add to the link item. */
44
+ attrs: LinkItemHTMLAttributesSchema().optional(),
36
45
  });
37
46
 
38
47
  export type Link = z.infer<typeof linkSchema>;
39
48
 
40
- export const LucodeStarlightConfigSchema = z.object({
41
- navLinks: z.array(linkSchema).optional(),
42
- docs: z
43
- .object({
44
- includeAiUtilities: z.boolean().optional().default(false),
45
- })
46
- .optional()
47
- .default({ includeAiUtilities: false }),
48
- footerText: z
49
- .string()
50
- .optional()
51
- .default(
52
- 'Inspired by the [shadcn/ui](https://ui.shadcn.com/) documentation theme and based on [starlight-theme-black](https://github.com/adrian-ub/starlight-theme-black). Ported to Astro Starlight by [lucas-labs](https://github.com/lucas-labs).'
53
- ),
49
+ export const GroveStarlightConfigSchema = z.object({
50
+ /** Array of navigation links for the header/nav bar. */
51
+ navLinks: z.array(linkSchema).optional(),
52
+ docs: z
53
+ .object({
54
+ includeAiUtilities: z.boolean().optional().default(false),
55
+ })
56
+ .optional()
57
+ .default({ includeAiUtilities: false }),
58
+ /**
59
+ * Whether to warn when a component override defined in your Starlight configuration prevents
60
+ * the theme from applying its own. Set to `false` to silence those warnings.
61
+ */
62
+ warnOverrides: z.boolean().optional().default(true),
63
+ /**
64
+ * Footer Markdown text. Can be a string, or for multilingual sites an object with values for
65
+ * each locale. Keys may be BCP-47 tags (e.g. `en`, `es`) or locale paths.
66
+ *
67
+ * @see https://starlight.astro.build/reference/configuration/#title
68
+ */
69
+ footerText: z
70
+ .union([z.string(), z.record(z.string(), z.string())])
71
+ .optional()
72
+ .default(
73
+ 'Inspired by the [shadcn/ui](https://ui.shadcn.com/) documentation theme and based on [starlight-theme-black](https://github.com/adrian-ub/starlight-theme-black). Originally forked from [lucas-labs/lucode-starlight-theme](https://github.com/lucas-labs/lucode-starlight-theme) and maintained by [grove](https://github.com/tortuvshin/grove).',
74
+ ),
54
75
  });
55
76
 
56
- export type LucodeStarlightUserConfig = z.input<typeof LucodeStarlightConfigSchema>;
57
- export type LucodeStarlightConfig = z.output<typeof LucodeStarlightConfigSchema>;
77
+ export type GroveStarlightUserConfig = z.input<typeof GroveStarlightConfigSchema>;
78
+ export type GroveStarlightConfig = z.output<typeof GroveStarlightConfigSchema>;
@@ -1,20 +1,20 @@
1
1
  import type { ViteUserConfig } from 'astro';
2
- import type { LucodeStarlightConfig } from './schemas';
2
+ import type { GroveStarlightConfig } from './schemas';
3
3
 
4
- export function vitePlugin(config: LucodeStarlightConfig): VitePlugin {
5
- const moduleId = 'virtual:lucode-starlight-config';
6
- const resolvedModuleId = `\0${moduleId}`;
7
- const moduleContent = `export default ${JSON.stringify(config)}`;
4
+ export function vitePlugin(config: GroveStarlightConfig): VitePlugin {
5
+ const moduleId = 'virtual:grove-starlight-config';
6
+ const resolvedModuleId = `\0${moduleId}`;
7
+ const moduleContent = `export default ${JSON.stringify(config)}`;
8
8
 
9
- return {
10
- name: 'vite-plugin-lucode-starlight',
11
- load(id) {
12
- return id === resolvedModuleId ? moduleContent : undefined;
13
- },
14
- resolveId(id) {
15
- return id === moduleId ? resolvedModuleId : undefined;
16
- },
17
- };
9
+ return {
10
+ name: 'vite-plugin-grove-starlight',
11
+ load(id) {
12
+ return id === resolvedModuleId ? moduleContent : undefined;
13
+ },
14
+ resolveId(id) {
15
+ return id === moduleId ? resolvedModuleId : undefined;
16
+ },
17
+ };
18
18
  }
19
19
 
20
20
  type VitePlugin = NonNullable<ViteUserConfig['plugins']>[number];
package/core/i18n.ts ADDED
@@ -0,0 +1,175 @@
1
+ export type LocaleLookup = {
2
+ /** BCP-47 tag from the active locale (`locales[x].lang`), e.g. `en`. */
3
+ lang?: string;
4
+ /** Locale path key (`Astro.currentLocale`), e.g. `en`. */
5
+ locale?: string;
6
+ /** Default locale BCP-47 tag or path used as fallback. */
7
+ defaultLang: string;
8
+ /** Default locale path key, e.g. `en`. */
9
+ defaultLocale?: string;
10
+ };
11
+
12
+ /**
13
+ * Pick a value from a locale dictionary.
14
+ *
15
+ * Tries exact then case-insensitive matches for active locale candidates first,
16
+ * then the same for fallback/default candidates. This covers Starlight setups
17
+ * where config keys are BCP-47 (`es-ES`) but `Astro.currentLocale` is the path
18
+ * (`es-es`), without letting the default locale shadow an active case-insensitive hit.
19
+ */
20
+ export function pickLocalized(
21
+ dictionary: Record<string, string> | undefined,
22
+ candidates: Array<string | undefined>,
23
+ fallbacks: Array<string | undefined> = [],
24
+ ): string | undefined {
25
+ if (!dictionary) {
26
+ return undefined;
27
+ }
28
+
29
+ const lowerMap = Object.fromEntries(
30
+ Object.entries(dictionary).map(([key, value]) => [key.toLowerCase(), value]),
31
+ );
32
+
33
+ const pickExact = (keys: Array<string | undefined>) => {
34
+ for (const key of keys) {
35
+ if (key && dictionary[key]) {
36
+ return dictionary[key];
37
+ }
38
+ }
39
+ return undefined;
40
+ };
41
+
42
+ const pickCaseInsensitive = (keys: Array<string | undefined>) => {
43
+ for (const key of keys) {
44
+ if (!key) {
45
+ continue;
46
+ }
47
+
48
+ const match = lowerMap[key.toLowerCase()];
49
+ if (match) {
50
+ return match;
51
+ }
52
+ }
53
+ return undefined;
54
+ };
55
+
56
+ return (
57
+ pickExact(candidates) ??
58
+ pickCaseInsensitive(candidates) ??
59
+ pickExact(fallbacks) ??
60
+ pickCaseInsensitive(fallbacks)
61
+ );
62
+ }
63
+
64
+ /** @deprecated Prefer `pickLocalized`. Kept for existing call sites/tests. */
65
+ export function pickLang(
66
+ dictionary: Record<string, string> | undefined,
67
+ lang: string,
68
+ ): string | undefined {
69
+ return pickLocalized(dictionary, [lang]);
70
+ }
71
+
72
+ function activeKeys({ lang, locale }: LocaleLookup): Array<string | undefined> {
73
+ return [lang, locale];
74
+ }
75
+
76
+ function fallbackKeys({ defaultLang, defaultLocale }: LocaleLookup): Array<string | undefined> {
77
+ return [defaultLang, defaultLocale];
78
+ }
79
+
80
+ /**
81
+ * Resolve a nav link label.
82
+ *
83
+ * Supports both APIs:
84
+ * - Starlight sidebar style: `label: string` + optional `translations`
85
+ * - Locale map style: `label: Record<BCP-47 | locale-path, string>`
86
+ */
87
+ export function resolveNavLabel(
88
+ label: string | Record<string, string>,
89
+ translations: Record<string, string> | undefined,
90
+ keys: LocaleLookup,
91
+ ): string {
92
+ const primary = activeKeys(keys);
93
+ const fallback = fallbackKeys(keys);
94
+
95
+ if (typeof label === 'string') {
96
+ return pickLocalized(translations, primary, fallback) || label;
97
+ }
98
+
99
+ const resolved = pickLocalized(label, primary, fallback);
100
+ if (resolved) {
101
+ return resolved;
102
+ }
103
+
104
+ throw new Error(
105
+ `Localized label must include a key for the default language "${keys.defaultLang}".`,
106
+ );
107
+ }
108
+
109
+ /**
110
+ * Resolve a sidebar-style label: `translations[lang] ?? label`.
111
+ * Accepts a LocaleLookup or a bare lang string for convenience.
112
+ */
113
+ export function resolveLabel(
114
+ label: string,
115
+ translations: Record<string, string> | undefined,
116
+ langOrKeys: string | LocaleLookup,
117
+ ): string {
118
+ if (typeof langOrKeys === 'string') {
119
+ return pickLocalized(translations, [langOrKeys]) || label;
120
+ }
121
+
122
+ return resolveNavLabel(label, translations, langOrKeys);
123
+ }
124
+
125
+ /**
126
+ * Resolve a title-style localized string (`string | Record<string, string>`).
127
+ * Prefers the active language/locale, then falls back to the default language.
128
+ */
129
+ export function resolveLocalizedString(
130
+ value: string | Record<string, string>,
131
+ langOrKeys: string | LocaleLookup,
132
+ defaultLang?: string,
133
+ ): string {
134
+ if (typeof value === 'string') {
135
+ return value;
136
+ }
137
+
138
+ const keys: LocaleLookup =
139
+ typeof langOrKeys === 'string'
140
+ ? { lang: langOrKeys, defaultLang: defaultLang ?? langOrKeys }
141
+ : langOrKeys;
142
+
143
+ const resolved = pickLocalized(value, activeKeys(keys), fallbackKeys(keys));
144
+ if (resolved) {
145
+ return resolved;
146
+ }
147
+
148
+ throw new Error(
149
+ `Localized string must include a key for the default language "${keys.defaultLang}".`,
150
+ );
151
+ }
152
+
153
+ /** Build a LocaleLookup from Starlight + Astro locale values. */
154
+ export function createLocaleLookup(options: {
155
+ lang?: string;
156
+ locale?: string;
157
+ defaultLang?: string;
158
+ defaultLocale?: string;
159
+ }): LocaleLookup {
160
+ const result: LocaleLookup = {
161
+ defaultLang: options.defaultLang || options.defaultLocale || 'en',
162
+ };
163
+
164
+ if (options.lang !== undefined) {
165
+ result.lang = options.lang;
166
+ }
167
+ if (options.locale !== undefined) {
168
+ result.locale = options.locale;
169
+ }
170
+ if (options.defaultLocale !== undefined) {
171
+ result.defaultLocale = options.defaultLocale;
172
+ }
173
+
174
+ return result;
175
+ }
package/core/plugin.ts CHANGED
@@ -1,56 +1,58 @@
1
1
  import type { StarlightPlugin } from '@astrojs/starlight/types';
2
- import { override, COMPONENT_OVERRIDES } from './config/override';
3
2
  import { expressiveCode } from './config/expresive-code';
4
- import { vitePlugin } from './config/vite';
3
+ import { COMPONENT_OVERRIDES, override } from './config/override';
5
4
  import {
6
- LucodeStarlightConfigSchema,
7
- type LucodeStarlightConfig,
8
- type LucodeStarlightUserConfig,
5
+ type GroveStarlightConfig,
6
+ GroveStarlightConfigSchema,
7
+ type GroveStarlightUserConfig,
9
8
  } from './config/schemas';
9
+ import { vitePlugin } from './config/vite';
10
10
 
11
- const parseConfig = (userConfig?: LucodeStarlightUserConfig): LucodeStarlightConfig => {
12
- const parsedConfig = LucodeStarlightConfigSchema.safeParse(userConfig ?? {});
11
+ const parseConfig = (userConfig?: GroveStarlightUserConfig): GroveStarlightConfig => {
12
+ const parsedConfig = GroveStarlightConfigSchema.safeParse(userConfig ?? {});
13
13
 
14
- if (!parsedConfig.success) {
15
- throw new Error(
16
- `The provided plugin configuration for @grove-dev/starlight is invalid.\n${parsedConfig.error.issues.map((issue) => issue.message).join('\n')}`
17
- );
18
- }
14
+ if (!parsedConfig.success) {
15
+ throw new Error(
16
+ `The provided plugin configuration for grove-starlight is invalid.\n${parsedConfig.error.issues.map((issue) => issue.message).join('\n')}`,
17
+ );
18
+ }
19
19
 
20
- return parsedConfig.data;
20
+ return parsedConfig.data;
21
21
  };
22
22
 
23
- const plugin = (userConfig?: LucodeStarlightUserConfig): StarlightPlugin =>
24
- ({
25
- name: '@grove-dev/starlight',
26
- hooks: {
27
- 'config:setup': ({ config, logger, updateConfig, addIntegration }) => {
28
- updateConfig({
29
- components: override(config, COMPONENT_OVERRIDES, logger),
30
- customCss: [
31
- ...(config.customCss ?? []),
32
- '@grove-dev/starlight/styles/layers',
33
- '@grove-dev/starlight/styles/theme',
34
- '@grove-dev/starlight/styles/base',
35
- ],
36
- expressiveCode: expressiveCode(config),
37
- });
23
+ const plugin = (userConfig: GroveStarlightUserConfig = {}): StarlightPlugin =>
24
+ ({
25
+ name: 'grove-starlight',
26
+ hooks: {
27
+ 'config:setup': ({ config, logger, updateConfig, addIntegration }) => {
28
+ const pluginConfig = parseConfig(userConfig);
29
+
30
+ updateConfig({
31
+ components: override(config, pluginConfig, COMPONENT_OVERRIDES, logger),
32
+ customCss: [
33
+ ...(config.customCss ?? []),
34
+ '@grove-dev/starlight/styles/layers',
35
+ '@grove-dev/starlight/styles/theme',
36
+ '@grove-dev/starlight/styles/base',
37
+ ],
38
+ expressiveCode: expressiveCode(config),
39
+ });
38
40
 
39
- addIntegration({
40
- name: '@grove-dev/starlight/integration',
41
- hooks: {
42
- 'astro:config:setup': ({ updateConfig }) => {
43
- updateConfig({
44
- vite: { plugins: [vitePlugin(parseConfig(userConfig))] },
45
- });
46
- },
47
- },
48
- });
41
+ addIntegration({
42
+ name: 'grove-starlight-integration',
43
+ hooks: {
44
+ 'astro:config:setup': ({ updateConfig }) => {
45
+ updateConfig({
46
+ vite: { plugins: [vitePlugin(pluginConfig)] },
47
+ });
49
48
  },
50
- // 'i18n:setup': function ({ injectTranslations }) {
51
- // injectTranslations(translations);
52
- // },
53
- },
54
- }) satisfies StarlightPlugin;
49
+ },
50
+ });
51
+ },
52
+ // 'i18n:setup': function ({ injectTranslations }) {
53
+ // injectTranslations(translations);
54
+ // },
55
+ },
56
+ }) satisfies StarlightPlugin;
55
57
 
56
58
  export { plugin };
@@ -0,0 +1,22 @@
1
+ import type { StarlightRouteData } from '@astrojs/starlight/route-data';
2
+
3
+ export type SidebarEntry = StarlightRouteData['sidebar'][number];
4
+ export type SidebarGroup = Extract<SidebarEntry, { type: 'group' }>;
5
+ export type SidebarLink = Extract<SidebarEntry, { type: 'link' }>;
6
+
7
+ /** Every link reachable from `entries`, at any depth. */
8
+ export function flattenSidebar(entries: SidebarEntry[]): SidebarLink[] {
9
+ return entries.flatMap((entry) =>
10
+ entry.type === 'group' ? flattenSidebar(entry.entries) : [entry],
11
+ );
12
+ }
13
+
14
+ /**
15
+ * Whether a group renders expanded.
16
+ *
17
+ * `collapsed` is the author's default, but a group holding the current page always opens, otherwise
18
+ * the reader would land on a page with no idea where they are in the tree.
19
+ */
20
+ export function isSidebarGroupOpen(group: SidebarGroup): boolean {
21
+ return !group.collapsed || flattenSidebar(group.entries).some((link) => link.isCurrent);
22
+ }
package/global.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export declare global {
2
- var StarlightThemeProvider: {
3
- updatePickers(theme?: string): void;
4
- };
2
+ var StarlightThemeProvider: {
3
+ updatePickers(theme?: string): void;
4
+ };
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grove-dev/starlight",
3
- "version": "0.6.1",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "description": "Grove's theme for Starlight (the Astro native documentation site generator)",
6
6
  "author": "grove-dev",
@@ -9,7 +9,7 @@
9
9
  "node": ">=22.12.0"
10
10
  },
11
11
  "readme": "README.md",
12
- "homepage": "https://grove.dev.mn/",
12
+ "homepage": "https://withgrove.dev/",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "https://github.com/tortuvshin/grove.git",
@@ -21,18 +21,6 @@
21
21
  "publishConfig": {
22
22
  "access": "public"
23
23
  },
24
- "files": [
25
- "components",
26
- "core",
27
- "styles",
28
- "global.d.ts",
29
- "index.ts",
30
- "schema.ts",
31
- "user-components.ts",
32
- "virtual.d.ts",
33
- "README.md",
34
- "THIRD_PARTY_LICENSES.md"
35
- ],
36
24
  "exports": {
37
25
  ".": "./index.ts",
38
26
  "./schema": "./schema.ts",
@@ -59,14 +47,10 @@
59
47
  "./package.json": "./package.json"
60
48
  },
61
49
  "peerDependencies": {
62
- "@astrojs/starlight": ">=0.38.3",
63
- "astro": ">=5.0.0"
50
+ "@astrojs/starlight": ">=0.41.4"
64
51
  },
65
52
  "dependencies": {
66
53
  "@pagefind/default-ui": "^1.5.2",
67
54
  "marked": "^18.0.2"
68
- },
69
- "scripts": {
70
- "test": "cd ../.. && pnpm exec vitest run --project starlight"
71
55
  }
72
56
  }