@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
package/styles/layers.css CHANGED
@@ -1 +1 @@
1
- @layer starlight, lucode;
1
+ @layer starlight, grove;
package/styles/theme.css CHANGED
@@ -1,67 +1,67 @@
1
- @layer lucode {
2
- :root[data-theme='dark'] {
3
- /* starlight gray scale */
4
- --foreground: oklch(98.5% 0 0); /* neutral-50 */
5
- --gray-1: oklch(98.5% 0 0); /* neutral-50 */
6
- --gray-2: oklch(87% 0 0); /* neutral-300 */
7
- --gray-3: oklch(70.8% 0 0); /* neutral-400 */
8
- --gray-4: oklch(55.6% 0 0); /* neutral-500 */
9
- --gray-5: oklch(37.1% 0 0); /* neutral-700 */
10
- --gray-6: oklch(26.9% 0 0); /* neutral-800 */
11
- --gray-7: oklch(20.5% 0 0); /* neutral-900 */
12
- --background: oklch(14.5% 0 0); /* neutral-950 */
1
+ @layer grove {
2
+ :root[data-theme="dark"] {
3
+ /* starlight gray scale */
4
+ --foreground: oklch(98.5% 0 0); /* neutral-50 */
5
+ --gray-1: oklch(98.5% 0 0); /* neutral-50 */
6
+ --gray-2: oklch(87% 0 0); /* neutral-300 */
7
+ --gray-3: oklch(70.8% 0 0); /* neutral-400 */
8
+ --gray-4: oklch(55.6% 0 0); /* neutral-500 */
9
+ --gray-5: oklch(37.1% 0 0); /* neutral-700 */
10
+ --gray-6: oklch(26.9% 0 0); /* neutral-800 */
11
+ --gray-7: oklch(20.5% 0 0); /* neutral-900 */
12
+ --background: oklch(14.5% 0 0); /* neutral-950 */
13
13
 
14
- /* colors */
15
- --orange-low: oklch(40.8% 0.123 38.172);
16
- --orange: oklch(83.7% 0.128 66.29);
17
- --orange-high: oklch(90.1% 0.076 70.697);
18
- --green-low: oklch(26.6% 0.065 152.934);
19
- --green: oklch(78% 0.19 152);
20
- --green-high: oklch(87.1% 0.15 154.449);
21
- --blue-low: oklch(29.3% 0.066 243.157);
22
- --blue: oklch(70.7% 0.165 254.624);
23
- --blue-high: oklch(82.8% 0.111 230.318);
24
- --purple-low: oklch(29.1% 0.149 302.717);
25
- --purple: oklch(71.4% 0.203 305.504);
26
- --purple-high: oklch(82.7% 0.119 306.383);
27
- --red-low: oklch(25.8% 0.092 26.042);
28
- --red: oklch(70.4% 0.191 22.216);
29
- --red-high: oklch(80.8% 0.114 19.571);
30
- }
14
+ /* colors */
15
+ --orange-low: oklch(40.8% 0.123 38.172);
16
+ --orange: oklch(83.7% 0.128 66.29);
17
+ --orange-high: oklch(90.1% 0.076 70.697);
18
+ --green-low: oklch(26.6% 0.065 152.934);
19
+ --green: oklch(79.2% 0.209 151.711);
20
+ --green-high: oklch(87.1% 0.15 154.449);
21
+ --blue-low: oklch(29.3% 0.066 243.157);
22
+ --blue: oklch(70.7% 0.165 254.624);
23
+ --blue-high: oklch(82.8% 0.111 230.318);
24
+ --purple-low: oklch(29.1% 0.149 302.717);
25
+ --purple: oklch(71.4% 0.203 305.504);
26
+ --purple-high: oklch(82.7% 0.119 306.383);
27
+ --red-low: oklch(25.8% 0.092 26.042);
28
+ --red: oklch(70.4% 0.191 22.216);
29
+ --red-high: oklch(80.8% 0.114 19.571);
30
+ }
31
31
 
32
- :root[data-theme='light'] {
33
- /* starlight gray scale */
34
- --foreground: oklch(14.5% 0 0); /* neutral-950 */
35
- --gray-1: oklch(20.5% 0 0); /* neutral-900 */
36
- --gray-2: oklch(26.9% 0 0); /* neutral-800 */
37
- --gray-3: oklch(37.1% 0 0); /* neutral-700 */
38
- --gray-4: oklch(55.6% 0 0); /* neutral-500 */
39
- --gray-5: oklch(70.8% 0 0); /* neutral-400 */
40
- --gray-6: oklch(87% 0 0); /* neutral-300 */
41
- --gray-7: oklch(97% 0 0); /* neutral-100 */
42
- --background: oklch(100% 0 0); /* white */
32
+ :root[data-theme="light"] {
33
+ /* starlight gray scale */
34
+ --foreground: oklch(14.5% 0 0); /* neutral-950 */
35
+ --gray-1: oklch(20.5% 0 0); /* neutral-900 */
36
+ --gray-2: oklch(26.9% 0 0); /* neutral-800 */
37
+ --gray-3: oklch(37.1% 0 0); /* neutral-700 */
38
+ --gray-4: oklch(55.6% 0 0); /* neutral-500 */
39
+ --gray-5: oklch(70.8% 0 0); /* neutral-400 */
40
+ --gray-6: oklch(87% 0 0); /* neutral-300 */
41
+ --gray-7: oklch(97% 0 0); /* neutral-100 */
42
+ --background: oklch(100% 0 0); /* white */
43
43
 
44
- /* colors */
45
- --orange-low: oklch(98% 0.016 73.684);
46
- --orange: oklch(70.5% 0.213 47.604);
47
- --orange-high: oklch(55.3% 0.195 38.402);
48
- --green-low: oklch(98.2% 0.018 155.826);
49
- --green: oklch(72.3% 0.219 149.579);
50
- --green-high: oklch(52.7% 0.154 150.069);
51
- --blue-low: oklch(97% 0.014 254.604);
52
- --blue: oklch(68.5% 0.169 237.323);
53
- --blue-high: oklch(48.8% 0.243 264.376);
54
- --purple-low: oklch(97.7% 0.014 308.299);
55
- --purple: oklch(62.7% 0.265 303.9);
56
- --purple-high: oklch(49.6% 0.265 301.924);
57
- --red-low: oklch(97.1% 0.013 17.38);
58
- --red: oklch(63.7% 0.237 25.331);
59
- --red-high: oklch(50.5% 0.213 27.518);
44
+ /* colors */
45
+ --orange-low: oklch(98% 0.016 73.684);
46
+ --orange: oklch(70.5% 0.213 47.604);
47
+ --orange-high: oklch(55.3% 0.195 38.402);
48
+ --green-low: oklch(98.2% 0.018 155.826);
49
+ --green: oklch(72.3% 0.219 149.579);
50
+ --green-high: oklch(52.7% 0.154 150.069);
51
+ --blue-low: oklch(97% 0.014 254.604);
52
+ --blue: oklch(68.5% 0.169 237.323);
53
+ --blue-high: oklch(48.8% 0.243 264.376);
54
+ --purple-low: oklch(97.7% 0.014 308.299);
55
+ --purple: oklch(62.7% 0.265 303.9);
56
+ --purple-high: oklch(49.6% 0.265 301.924);
57
+ --red-low: oklch(97.1% 0.013 17.38);
58
+ --red: oklch(63.7% 0.237 25.331);
59
+ --red-high: oklch(50.5% 0.213 27.518);
60
60
 
61
- /* light overrides */
62
- --accent: var(--gray-7);
63
- --secondary: var(--gray-7);
64
- --muted-foreground: var(--gray-4);
65
- --popover-background: var(--background);
66
- }
61
+ /* light overrides */
62
+ --accent: var(--gray-7);
63
+ --secondary: var(--gray-7);
64
+ --muted-foreground: var(--gray-4);
65
+ --popover-background: var(--background);
66
+ }
67
67
  }
@@ -1,4 +1,3 @@
1
- export { default as Card } from './components/custom/Card.astro';
2
1
  export { default as ContainerSection } from './components/custom/ContainerSection.astro';
3
- export { default as LinkButton } from './components/custom/LinkButton.astro';
4
2
  export { default as Dropdown } from './components/custom/dropdown';
3
+ export { default as LinkButton } from './components/custom/LinkButton.astro';
package/virtual.d.ts CHANGED
@@ -1,51 +1,51 @@
1
- declare module 'virtual:lucode-starlight-config' {
2
- const LucodeStarlightConfig: import('./core/config/schemas').LucodeStarlightConfig;
3
- export default LucodeStarlightConfig;
1
+ declare module 'virtual:grove-starlight-config' {
2
+ const GroveStarlightConfig: import('./core/config/schemas').GroveStarlightConfig;
3
+ export default GroveStarlightConfig;
4
4
  }
5
5
 
6
6
  declare module 'virtual:starlight/user-config' {
7
- const Config: import('@astrojs/starlight/types').StarlightConfig;
8
- export default Config;
7
+ const Config: import('@astrojs/starlight/types').StarlightConfig;
8
+ export default Config;
9
9
  }
10
10
 
11
11
  declare module 'virtual:starlight/user-images' {
12
- type ImageMetadata = import('astro').ImageMetadata;
13
- export const logos: {
14
- dark?: ImageMetadata;
15
- light?: ImageMetadata;
16
- };
12
+ type ImageMetadata = import('astro').ImageMetadata;
13
+ export const logos: {
14
+ dark?: ImageMetadata;
15
+ light?: ImageMetadata;
16
+ };
17
17
  }
18
18
 
19
19
  declare module 'virtual:starlight/pagefind-config' {
20
- export const pagefindUserConfig: Partial<
21
- Extract<import('@astrojs/starlight/types').StarlightConfig['pagefind'], object>
22
- >;
20
+ export const pagefindUserConfig: Partial<
21
+ Extract<import('@astrojs/starlight/types').StarlightConfig['pagefind'], object>
22
+ >;
23
23
  }
24
24
 
25
25
  declare module 'virtual:starlight/project-context' {
26
- const ProjectContext: {
27
- root: string;
28
- srcDir: string;
29
- trailingSlash: import('astro').AstroConfig['trailingSlash'];
30
- build: {
31
- format: import('astro').AstroConfig['build']['format'];
32
- };
33
- legacyCollections: boolean;
26
+ const ProjectContext: {
27
+ root: string;
28
+ srcDir: string;
29
+ trailingSlash: import('astro').AstroConfig['trailingSlash'];
30
+ build: {
31
+ format: import('astro').AstroConfig['build']['format'];
34
32
  };
35
- export default ProjectContext;
33
+ legacyCollections: boolean;
34
+ };
35
+ export default ProjectContext;
36
36
  }
37
37
 
38
38
  declare module 'virtual:starlight/components/LastUpdated' {
39
- const LastUpdated: typeof import('@astrojs/starlight/components/LastUpdated.astro').default;
40
- export default LastUpdated;
39
+ const LastUpdated: typeof import('@astrojs/starlight/components/LastUpdated.astro').default;
40
+ export default LastUpdated;
41
41
  }
42
42
 
43
43
  declare module 'virtual:starlight/components/Pagination' {
44
- const Pagination: typeof import('@astrojs/starlight/components/Pagination.astro').default;
45
- export default Pagination;
44
+ const Pagination: typeof import('@astrojs/starlight/components/Pagination.astro').default;
45
+ export default Pagination;
46
46
  }
47
47
 
48
48
  declare module 'virtual:starlight/components/EditLink' {
49
- const EditLink: typeof import('@astrojs/starlight/components/EditLink.astro').default;
50
- export default EditLink;
49
+ const EditLink: typeof import('@astrojs/starlight/components/EditLink.astro').default;
50
+ export default EditLink;
51
51
  }
@@ -1,68 +0,0 @@
1
- # Third-party attributions — `@grove-dev/starlight`
2
-
3
- This package incorporates design and code from upstream projects. The
4
- contributions are credited below; reproduction of the upstream license
5
- texts follows the attribution block. The Grove project ships
6
- `@grove-dev/starlight` under the same MIT license that the rest of the
7
- monorepo uses; the third-party license texts below are reproduced here
8
- to satisfy the upstream attribution requirements.
9
-
10
- > **⚠️ TODO(decision): license compatibility check.**
11
- > The audit and the project's own README credit the upstream work as
12
- > "lucode / lucas-labs" and reference
13
- > `https://github.com/lucas-labs/@grove-dev/starlight-theme`. Before the
14
- > first publish of `@grove-dev/starlight` to npm, the project owner
15
- > must:
16
- >
17
- > 1. Confirm the exact upstream repo URL (the `lucas-labs/...` path
18
- > in the README is a placeholder; the real upstream is
19
- > `lucode-labs/lucode` or similar — verify on GitHub).
20
- > 2. Verify the upstream license (MIT? Apache-2.0? something else?)
21
- > and confirm it is compatible with the Grove monorepo's MIT
22
- > distribution.
23
- > 3. If compatible, replace the `<!-- TODO LICENSE TEXT -->` block
24
- > below with the verbatim upstream license text (most MIT projects
25
- > use the standard MIT text — the canonical version is at
26
- > <https://opensource.org/licenses/MIT>).
27
- > 4. If not compatible, either obtain a written license grant from
28
- > the upstream maintainer OR replace the derivative design with
29
- > original work before publishing.
30
- >
31
- > Tracking issue:
32
- > <https://github.com/tortuvshin/grove/issues/new?title=starlight%3A+verify+third-party+license+compatibility>
33
-
34
- ## Upstream credits
35
-
36
- The design and component overrides in this package derive from:
37
-
38
- - **[lucode](https://github.com/lucas-labs/@grove-dev/starlight-theme)** by the
39
- **lucas-labs** organization (also referenced as "Lucode" in the
40
- package's `user-components.ts` and component overrides). The theme
41
- recreates the design of [shadcn/ui](https://ui.shadcn.com/) (MIT)
42
- for use inside Astro Starlight, with custom overrides for the
43
- header, sidebar, page frame, hero, footer, search, table of
44
- contents, pagination, and Markdown content. See the package
45
- `README.md` (the "Attribution" and "Usage" sections) for the
46
- in-code pointers.
47
- - **[adrian-ub/starlight-theme-black](https://github.com/adrian-ub/starlight-theme-black)**
48
- — the earlier shadcn/ui-inspired Starlight theme that
49
- `lucas-labs/@grove-dev/starlight-theme` was based on (per the
50
- upstream README).
51
- - **[shadcn/ui](https://ui.shadcn.com/)** — the original design
52
- language that the upstream work and this package both target.
53
-
54
- ## Upstream license
55
-
56
- <!-- TODO LICENSE TEXT: paste the verbatim upstream license (typically
57
- the standard MIT text with copyright line) here once the license
58
- compatibility check above is complete. Until then this section is
59
- intentionally empty so the file can ship without misrepresenting the
60
- upstream license. -->
61
-
62
- ## License for this package
63
-
64
- `@grove-dev/starlight` is distributed under the **MIT License** — see
65
- [`../core/LICENSE`](../../LICENSE) at the monorepo root for the
66
- canonical text. The third-party attributions above are reproduced for
67
- compliance with the upstream license terms; they do not change the
68
- license of the rest of the package.
@@ -1,118 +0,0 @@
1
- ---
2
- /**
3
- * Starlight `<Card>` override that adds an optional `href` prop.
4
- *
5
- * The upstream `Card.astro` in `@astrojs/starlight@0.40` only accepts
6
- * `icon` and `title`, so a `<Card title="..." href="...">` call silently
7
- * dropped the link and rendered a non-clickable `<article>`. We wrap the
8
- * inner content in an `<a>` when `href` is present so the entire card
9
- * surface is interactive (the same affordance the `LinkCard` component
10
- * uses, but with our visual `Card` styling).
11
- *
12
- * Visual styles are identical to upstream — only the structure gains a
13
- * single `<a>` wrapper when `href` is set.
14
- */
15
- import { Icon } from '@astrojs/starlight/components';
16
- import type { StarlightIcon } from '@astrojs/starlight/components-internals/Icons';
17
-
18
- interface Props {
19
- icon?: StarlightIcon;
20
- title: string;
21
- href?: string;
22
- }
23
-
24
- const { icon, title, href } = Astro.props;
25
- ---
26
-
27
- <article class="card sl-flex">
28
- <p class="title sl-flex">
29
- {icon && <Icon name={icon} class="icon" size="1.333em" />}
30
- <span>{title}</span>
31
- </p>
32
- <div class="body">
33
- {href ? <a {href} class="sl-card-link"><slot /></a> : <slot />}
34
- </div>
35
- </article>
36
-
37
- <style>
38
- @layer starlight.components {
39
- .card {
40
- --sl-card-border: var(--sl-color-purple);
41
- --sl-card-bg: var(--sl-color-purple-low);
42
- border: 1px solid var(--sl-color-gray-5);
43
- background-color: var(--sl-color-black);
44
- padding: clamp(1rem, calc(0.125rem + 3vw), 2.5rem);
45
- flex-direction: column;
46
- gap: clamp(0.5rem, calc(0.125rem + 1vw), 1rem);
47
- transition: border-color 0.15s ease, transform 0.15s ease;
48
- }
49
- .card:nth-child(4n + 1) {
50
- --sl-card-border: var(--sl-color-orange);
51
- --sl-card-bg: var(--sl-color-orange-low);
52
- }
53
- .card:nth-child(4n + 3) {
54
- --sl-card-border: var(--sl-color-green);
55
- --sl-card-bg: var(--sl-color-green-low);
56
- }
57
- .card:nth-child(4n + 4) {
58
- --sl-card-border: var(--sl-color-red);
59
- --sl-card-bg: var(--sl-color-red-low);
60
- }
61
- .card:nth-child(4n + 5) {
62
- --sl-card-border: var(--sl-color-blue);
63
- --sl-card-bg: var(--sl-color-blue-low);
64
- }
65
- .title {
66
- font-weight: 600;
67
- font-size: var(--sl-text-h4);
68
- color: var(--sl-color-white);
69
- line-height: var(--sl-line-height-headings);
70
- gap: 1rem;
71
- align-items: center;
72
- }
73
- .card .icon {
74
- border: 1px solid var(--sl-card-border);
75
- background-color: var(--sl-card-bg);
76
- padding: 0.2em;
77
- border-radius: 0.25rem;
78
- flex-shrink: 0;
79
- }
80
- .card .body {
81
- margin: 0;
82
- font-size: clamp(var(--sl-text-sm), calc(0.5rem + 1vw), var(--sl-text-body));
83
- }
84
- .card .body .sl-card-link {
85
- /* The link is invisible text-decoration-wise; the card itself
86
- * is the click target thanks to the ::before pseudo-element
87
- * below. Display:contents lets the link wrap the body text
88
- * without breaking the flex/grid layout. */
89
- display: contents;
90
- color: inherit;
91
- }
92
- .card:has(.sl-card-link) {
93
- position: relative;
94
- cursor: pointer;
95
- }
96
- .card:has(.sl-card-link):hover {
97
- border-color: var(--sl-color-gray-2);
98
- }
99
- .card:has(.sl-card-link):hover .title {
100
- color: var(--sl-color-accent-high);
101
- }
102
- /* a11y: a transparent overlay makes the whole card clickable
103
- * without changing layout. Same trick Starlight's LinkCard uses. */
104
- .card:has(.sl-card-link) .sl-card-link::before {
105
- content: '';
106
- position: absolute;
107
- inset: 0;
108
- border-radius: inherit;
109
- }
110
- /* Focus-visible ring anchored to the card surface so keyboard
111
- * users see a clear focus indicator (otherwise the transparent
112
- * overlay hides the default link outline). */
113
- .card:has(.sl-card-link:focus-visible) {
114
- outline: 2px solid var(--sl-color-accent);
115
- outline-offset: 2px;
116
- }
117
- }
118
- </style>