@astrojs/starlight 0.0.1

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 (47) hide show
  1. package/404.astro +51 -0
  2. package/CHANGELOG.md +7 -0
  3. package/LICENSE +21 -0
  4. package/README.md +28 -0
  5. package/components/ContentPanel.astro +25 -0
  6. package/components/EditLink.astro +23 -0
  7. package/components/FallbackContentNotice.astro +27 -0
  8. package/components/HeadSEO.astro +60 -0
  9. package/components/Header.astro +62 -0
  10. package/components/Icon.astro +36 -0
  11. package/components/Icons.ts +43 -0
  12. package/components/LanguageSelect.astro +51 -0
  13. package/components/LastUpdated.astro +41 -0
  14. package/components/MarkdownContent.astro +112 -0
  15. package/components/MobileMenuToggle.astro +89 -0
  16. package/components/PrevNextLinks.astro +77 -0
  17. package/components/RightSidebarPanel.astro +38 -0
  18. package/components/Search.astro +296 -0
  19. package/components/Select.astro +80 -0
  20. package/components/Sidebar.astro +34 -0
  21. package/components/SidebarSublist.astro +78 -0
  22. package/components/SkipLink.astro +18 -0
  23. package/components/TableOfContents/TableOfContentsList.astro +35 -0
  24. package/components/TableOfContents/generateToC.ts +66 -0
  25. package/components/TableOfContents.astro +17 -0
  26. package/components/ThemeProvider.astro +50 -0
  27. package/components/ThemeSelect.astro +88 -0
  28. package/index.astro +102 -0
  29. package/index.ts +104 -0
  30. package/integrations/asides.ts +164 -0
  31. package/layout/PageFrame.astro +88 -0
  32. package/layout/TwoColumnContent.astro +42 -0
  33. package/package.json +42 -0
  34. package/schema.ts +23 -0
  35. package/style/asides.css +49 -0
  36. package/style/props.css +197 -0
  37. package/style/reset.css +43 -0
  38. package/style/shiki.css +13 -0
  39. package/style/util.css +32 -0
  40. package/types.ts +1 -0
  41. package/utils/git.ts +96 -0
  42. package/utils/localizedUrl.ts +32 -0
  43. package/utils/navigation.ts +232 -0
  44. package/utils/routing.ts +109 -0
  45. package/utils/slugs.ts +91 -0
  46. package/utils/user-config.ts +250 -0
  47. package/virtual.d.ts +9 -0
@@ -0,0 +1,89 @@
1
+ ---
2
+ import Icon from './Icon.astro';
3
+ ---
4
+
5
+ <starlight-menu-button>
6
+ <button
7
+ aria-expanded="false"
8
+ aria-label="Menu"
9
+ aria-controls="starlight__sidebar"
10
+ class="md:hidden"
11
+ >
12
+ <Icon name="bars" />
13
+ </button>
14
+ </starlight-menu-button>
15
+
16
+ <script>
17
+ class StarlightMenuButton extends HTMLElement {
18
+ btn = this.querySelector('button')!;
19
+
20
+ constructor() {
21
+ super();
22
+ // Toggle `aria-expanded` state when a user clicks the button.
23
+ this.btn.addEventListener('click', () => this.toggleExpanded());
24
+
25
+ // Close the menu when a user presses the escape key.
26
+ const parentNav = this.closest('nav');
27
+ if (parentNav) {
28
+ parentNav.addEventListener('keyup', (e) => this.closeOnEscape(e));
29
+ }
30
+ }
31
+
32
+ setExpanded(expanded: boolean) {
33
+ this.setAttribute('aria-expanded', String(expanded));
34
+ document.body.toggleAttribute('data-mobile-menu-expanded', expanded);
35
+ }
36
+
37
+ toggleExpanded() {
38
+ this.setExpanded(this.getAttribute('aria-expanded') !== 'true');
39
+ }
40
+
41
+ closeOnEscape(e: KeyboardEvent) {
42
+ if (e.code === 'Escape') {
43
+ this.setExpanded(false);
44
+ this.btn.focus();
45
+ }
46
+ }
47
+ }
48
+
49
+ customElements.define('starlight-menu-button', StarlightMenuButton);
50
+ </script>
51
+
52
+ <style>
53
+ button {
54
+ position: fixed;
55
+ top: calc((var(--sl-nav-height) - var(--sl-menu-button-size)) / 2);
56
+ inset-inline-end: var(--sl-nav-pad-x);
57
+ z-index: var(--sl-z-index-navbar);
58
+ border: 0;
59
+ border-radius: 50%;
60
+ display: flex;
61
+ width: var(--sl-menu-button-size);
62
+ height: var(--sl-menu-button-size);
63
+ padding: 0.5rem;
64
+ background-color: var(--sl-color-white);
65
+ color: var(--sl-color-black);
66
+ box-shadow: var(--sl-shadow-md);
67
+ cursor: pointer;
68
+ }
69
+
70
+ [aria-expanded='true'] button {
71
+ background-color: var(--sl-color-gray-2);
72
+ box-shadow: none;
73
+ }
74
+
75
+ :global([data-theme='light']) button {
76
+ background-color: var(--sl-color-black);
77
+ color: var(--sl-color-white);
78
+ }
79
+
80
+ :global([data-theme='light']) [aria-expanded='true'] button {
81
+ background-color: var(--sl-color-gray-5);
82
+ }
83
+ </style>
84
+
85
+ <style is:global>
86
+ [data-mobile-menu-expanded] {
87
+ overflow: hidden;
88
+ }
89
+ </style>
@@ -0,0 +1,77 @@
1
+ ---
2
+ import type { Link } from '../utils/navigation';
3
+ import Icon from './Icon.astro';
4
+
5
+ interface Props {
6
+ prev: Link | undefined;
7
+ next: Link | undefined;
8
+ dir: 'ltr' | 'rtl';
9
+ }
10
+
11
+ const { prev, next, dir } = Astro.props;
12
+ const isRtl = dir === 'rtl';
13
+ ---
14
+
15
+ <div class="pagination-links" dir={dir}>
16
+ {
17
+ prev && (
18
+ <a href={prev.href} rel="prev">
19
+ <Icon name={isRtl ? 'right-arrow' : 'left-arrow'} size="1.5rem" />
20
+ <span>
21
+ Previous
22
+ <br />
23
+ <span class="link-title">{prev.label}</span>
24
+ </span>
25
+ </a>
26
+ )
27
+ }
28
+ {
29
+ next && (
30
+ <a href={next.href} rel="next">
31
+ <Icon name={isRtl ? 'left-arrow' : 'right-arrow'} size="1.5rem" />
32
+ <span>
33
+ Next
34
+ <br />
35
+ <span class="link-title">{next.label}</span>
36
+ </span>
37
+ </a>
38
+ )
39
+ }
40
+ </div>
41
+
42
+ <style>
43
+ .pagination-links {
44
+ display: flex;
45
+ flex-wrap: wrap;
46
+ gap: 1rem;
47
+ }
48
+
49
+ a {
50
+ display: flex;
51
+ align-items: center;
52
+ justify-content: start;
53
+ gap: 0.5rem;
54
+ width: 100%;
55
+ flex-basis: calc(50% - 0.5rem);
56
+ flex-grow: 1;
57
+ border: 1px solid var(--sl-color-gray-5);
58
+ border-radius: 0.5rem;
59
+ padding: 1rem;
60
+ text-decoration: none;
61
+ color: var(--sl-color-gray-2);
62
+ }
63
+ [rel='next'] {
64
+ justify-content: end;
65
+ text-align: end;
66
+ flex-direction: row-reverse;
67
+ }
68
+ a:hover {
69
+ border-color: var(--sl-color-gray-2);
70
+ }
71
+
72
+ .link-title {
73
+ color: var(--sl-color-white);
74
+ font-size: var(--sl-text-2xl);
75
+ line-height: var(--sl-line-height-headings);
76
+ }
77
+ </style>
@@ -0,0 +1,38 @@
1
+ <div class="right-sidebar-panel">
2
+ <div class="container">
3
+ <slot />
4
+ </div>
5
+ </div>
6
+
7
+ <style>
8
+ .right-sidebar-panel {
9
+ padding: 1rem var(--sl-sidebar-pad-x);
10
+ }
11
+ .right-sidebar-panel + .right-sidebar-panel {
12
+ border-top: 1px solid var(--sl-color-hairline);
13
+ }
14
+ .container {
15
+ width: var(--sl-sidebar-width);
16
+ }
17
+ .right-sidebar-panel :global(h2) {
18
+ color: var(--sl-color-white);
19
+ font-size: var(--sl-text-base);
20
+ font-weight: 600;
21
+ }
22
+ .right-sidebar-panel :global(a) {
23
+ display: block;
24
+ font-size: var(--sl-text-xs);
25
+ text-decoration: none;
26
+ color: var(--sl-color-gray-3);
27
+ }
28
+ .right-sidebar-panel :global(a:hover) {
29
+ color: var(--sl-color-white);
30
+ }
31
+ @media (min-width: 72rem) {
32
+ .container {
33
+ max-width: calc(
34
+ 100vw - var(--sl-content-width) - var(--sl-sidebar-width)
35
+ );
36
+ }
37
+ }
38
+ </style>
@@ -0,0 +1,296 @@
1
+ ---
2
+ import '@pagefind/default-ui/css/ui.css';
3
+ import Icon from './Icon.astro';
4
+ ---
5
+
6
+ <site-search>
7
+ <button data-open-modal disabled>
8
+ <Icon name="magnifier" label="Search" />
9
+ <span class="hidden md:block" aria-hidden="true">Search</span>
10
+ <Icon
11
+ name="forward-slash"
12
+ class="hidden md:block"
13
+ label="(Press / to search)"
14
+ />
15
+ </button>
16
+
17
+ <dialog style="padding:0" aria-label="Search the documentation">
18
+ <div class="dialog-frame">
19
+ <button data-close-modal class="flex md:hidden">Cancel</button>
20
+ {
21
+ import.meta.env.DEV ? (
22
+ <div style="margin: auto; text-align: center;">
23
+ <p>Search is only available in production builds.</p>
24
+ <p>Try building and previewing the site to test it out locally.</p>
25
+ </div>
26
+ ) : (
27
+ <div class="search-container">
28
+ <div id="starlight__search" />
29
+ </div>
30
+ )
31
+ }
32
+ </div>
33
+ </dialog>
34
+ </site-search>
35
+
36
+ <script>
37
+ class SiteSearch extends HTMLElement {
38
+ constructor() {
39
+ super();
40
+ const openBtn = this.querySelector<HTMLButtonElement>(
41
+ 'button[data-open-modal]'
42
+ )!;
43
+ const closeBtn = this.querySelector<HTMLButtonElement>(
44
+ 'button[data-close-modal]'
45
+ )!;
46
+ const dialog = this.querySelector('dialog')!;
47
+ const dialogFrame = this.querySelector('.dialog-frame')!;
48
+
49
+ /** Close the modal if a user clicks outside of the modal. */
50
+ const onWindowClick = (event: MouseEvent) => {
51
+ if (!dialogFrame.contains(event.target as Node)) closeModal();
52
+ };
53
+
54
+ const openModal = (event?: MouseEvent) => {
55
+ dialog.showModal();
56
+ this.querySelector('input')?.focus();
57
+ event?.stopPropagation();
58
+ window.addEventListener('click', onWindowClick);
59
+ };
60
+
61
+ const closeModal = () => {
62
+ dialog.close();
63
+ window.removeEventListener('click', onWindowClick);
64
+ };
65
+
66
+ openBtn.addEventListener('click', openModal);
67
+ openBtn.disabled = false;
68
+ closeBtn.addEventListener('click', closeModal);
69
+
70
+ // Listen for `/` and `cmd + k` keyboard shortcuts.
71
+ window.addEventListener('keydown', (e) => {
72
+ if (e.metaKey === true && e.key === 'k') {
73
+ dialog.open ? closeModal() : openModal();
74
+ e.preventDefault();
75
+ } else if (e.key === '/' && !dialog.open) {
76
+ openModal();
77
+ e.preventDefault();
78
+ }
79
+ });
80
+ }
81
+ }
82
+ customElements.define('site-search', SiteSearch);
83
+
84
+ window.addEventListener('DOMContentLoaded', () => {
85
+ if (import.meta.env.DEV) return;
86
+ const onIdle = window.requestIdleCallback || ((cb) => setTimeout(cb, 1));
87
+ onIdle(async () => {
88
+ const { PagefindUI } = await import('@pagefind/default-ui');
89
+ new PagefindUI({
90
+ element: '#starlight__search',
91
+ baseUrl: import.meta.env.BASE_URL,
92
+ showImages: false,
93
+ });
94
+ });
95
+ });
96
+ </script>
97
+
98
+ <style>
99
+ button[data-open-modal] {
100
+ display: flex;
101
+ align-items: center;
102
+ gap: 0.5rem;
103
+ border: 0;
104
+ background-color: transparent;
105
+ color: var(--sl-color-gray-1);
106
+ cursor: pointer;
107
+ height: 2.5rem;
108
+ font-size: var(--sl-text-xl);
109
+ }
110
+
111
+ @media (min-width: 50rem) {
112
+ button[data-open-modal] {
113
+ border: 1px solid var(--sl-color-gray-5);
114
+ border-radius: 0.5rem;
115
+ padding-inline-start: 0.75rem;
116
+ padding-inline-end: 1rem;
117
+ background-color: var(--sl-color-black);
118
+ color: var(--sl-color-gray-2);
119
+ font-size: var(--sl-text-sm);
120
+ width: 100%;
121
+ max-width: 22rem;
122
+ }
123
+ button[data-open-modal]:hover {
124
+ border-color: var(--sl-color-gray-2);
125
+ color: var(--sl-color-white);
126
+ }
127
+
128
+ button[data-open-modal] > :last-child {
129
+ margin-inline-start: auto;
130
+ }
131
+ }
132
+
133
+ dialog {
134
+ margin: 0;
135
+ background-color: var(--sl-color-gray-6);
136
+ border: 1px solid var(--sl-color-gray-5);
137
+ width: 100%;
138
+ max-width: 100%;
139
+ height: 100%;
140
+ max-height: 100%;
141
+ box-shadow: var(--sl-shadow-lg);
142
+ }
143
+ dialog[open] {
144
+ display: grid;
145
+ }
146
+
147
+ dialog::backdrop {
148
+ background-color: var(--sl-color-backdrop-overlay);
149
+ -webkit-backdrop-filter: blur(0.25rem);
150
+ backdrop-filter: blur(0.25rem);
151
+ }
152
+
153
+ .dialog-frame {
154
+ display: flex;
155
+ flex-direction: column;
156
+ gap: 1rem;
157
+ padding: 1.5rem;
158
+ }
159
+
160
+ button[data-close-modal] {
161
+ position: absolute;
162
+ z-index: 1;
163
+ display: flex;
164
+ align-items: center;
165
+ align-self: flex-end;
166
+ height: calc(64px * var(--pagefind-ui-scale));
167
+ padding: 0.25rem;
168
+ border: 0;
169
+ background: transparent;
170
+ cursor: pointer;
171
+ color: var(--sl-color-text-accent);
172
+ }
173
+
174
+ #starlight__search {
175
+ --pagefind-ui-primary: var(--sl-color-accent-light);
176
+ --pagefind-ui-text: var(--sl-color-gray-2);
177
+ --pagefind-ui-background: var(--sl-color-black);
178
+ --pagefind-ui-border: var(--sl-color-gray-5);
179
+ --pagefind-ui-border-width: 1px;
180
+ --sl-search-cancel-space: 5rem;
181
+ }
182
+
183
+ @media (min-width: 50rem) {
184
+ #starlight__search {
185
+ --sl-search-cancel-space: 0px;
186
+ }
187
+
188
+ dialog {
189
+ margin: 4rem auto auto;
190
+ border-radius: 0.5rem;
191
+ width: 90%;
192
+ max-width: 40rem;
193
+ height: max-content;
194
+ min-height: 15rem;
195
+ max-height: calc(100% - 8rem);
196
+ }
197
+
198
+ button[data-close-modal] {
199
+ display: none;
200
+ }
201
+ }
202
+ </style>
203
+
204
+ <style is:global>
205
+ #starlight__search .pagefind-ui__form::before {
206
+ --pagefind-ui-text: var(--sl-color-gray-1);
207
+ opacity: 1;
208
+ }
209
+
210
+ #starlight__search .pagefind-ui__search-input {
211
+ color: var(--sl-color-white);
212
+ font-weight: 400;
213
+ width: calc(100% - var(--sl-search-cancel-space));
214
+ }
215
+
216
+ #starlight__search input:focus {
217
+ --pagefind-ui-border: var(--sl-color-accent);
218
+ }
219
+
220
+ #starlight__search .pagefind-ui__search-clear {
221
+ inset-inline-end: var(--sl-search-cancel-space);
222
+ width: calc(60px * var(--pagefind-ui-scale));
223
+ padding: 0;
224
+ background-color: transparent;
225
+ overflow: hidden;
226
+ }
227
+ #starlight__search .pagefind-ui__search-clear:focus {
228
+ outline: 1px solid var(--sl-color-accent);
229
+ }
230
+ #starlight__search .pagefind-ui__search-clear::before {
231
+ content: '';
232
+ -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m13.41 12 6.3-6.29a1 1 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1 1 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 .33 1.64 1 1 0 0 0 1.09-.22l6.29-6.3 6.29 6.3a1 1 0 0 0 1.64-.33 1 1 0 0 0-.22-1.09L13.41 12Z'/%3E%3C/svg%3E")
233
+ center / 50% no-repeat;
234
+ mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m13.41 12 6.3-6.29a1 1 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1 1 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 .33 1.64 1 1 0 0 0 1.09-.22l6.29-6.3 6.29 6.3a1 1 0 0 0 1.64-.33 1 1 0 0 0-.22-1.09L13.41 12Z'/%3E%3C/svg%3E")
235
+ center / 50% no-repeat;
236
+ background-color: var(--sl-color-text-accent);
237
+ display: block;
238
+ width: 100%;
239
+ height: 100%;
240
+ }
241
+
242
+ #starlight__search .pagefind-ui__results > * + * {
243
+ margin-top: 0.5rem;
244
+ }
245
+ #starlight__search .pagefind-ui__result {
246
+ position: relative;
247
+ border: 0;
248
+ border-radius: 0.25rem;
249
+ padding: 1rem;
250
+ background-color: var(--sl-color-black);
251
+ }
252
+
253
+ #starlight__search .pagefind-ui__result:hover,
254
+ #starlight__search .pagefind-ui__result:focus-within {
255
+ outline: 1px solid var(--sl-color-accent-high);
256
+ }
257
+
258
+ #starlight__search .pagefind-ui__result:focus-within {
259
+ background-color: var(--sl-color-accent-low);
260
+ }
261
+
262
+ #starlight__search .pagefind-ui__result-thumb,
263
+ #starlight__search .pagefind-ui__result-inner {
264
+ margin-top: 0;
265
+ }
266
+
267
+ #starlight__search .pagefind-ui__result-link {
268
+ --pagefind-ui-text: var(--sl-color-white);
269
+ font-weight: 600;
270
+ }
271
+
272
+ #starlight__search .pagefind-ui__result-link:hover {
273
+ text-decoration: none;
274
+ }
275
+
276
+ #starlight__search .pagefind-ui__result-link::after {
277
+ content: '';
278
+ position: absolute;
279
+ inset: 0;
280
+ }
281
+
282
+ #starlight__search .pagefind-ui__result-excerpt {
283
+ font-size: var(--sl-text-body-sm);
284
+ }
285
+
286
+ #starlight__search mark {
287
+ color: var(--sl-color-white);
288
+ background-color: var(--sl-color-accent-low);
289
+ font-weight: 500;
290
+ padding: 0.1em 0.2em;
291
+ }
292
+
293
+ #starlight__search .pagefind-ui__result:focus-within mark {
294
+ text-decoration: underline;
295
+ }
296
+ </style>
@@ -0,0 +1,80 @@
1
+ ---
2
+ import Icon from './Icon.astro';
3
+
4
+ interface Props {
5
+ label: string;
6
+ value: string;
7
+ icon: Parameters<typeof Icon>[0]['name'];
8
+ width?: string;
9
+ options: Array<{
10
+ label: string;
11
+ value: string;
12
+ selected: boolean;
13
+ }>;
14
+ }
15
+ ---
16
+
17
+ <label style={`--sl-select-width: ${Astro.props.width}`}>
18
+ <span class="sr-only">{Astro.props.label}</span>
19
+ <Icon name={Astro.props.icon} class="icon label-icon" />
20
+ <select value={Astro.props.value}>
21
+ {
22
+ Astro.props.options.map(({ value, selected, label }) => (
23
+ <option value={value} selected={selected} set:html={label} />
24
+ ))
25
+ }
26
+ </select>
27
+ <Icon name="down-caret" class="icon caret" />
28
+ </label>
29
+
30
+ <style>
31
+ label {
32
+ --sl-label-icon-size: 0.875rem;
33
+ --sl-caret-size: 1.25rem;
34
+ position: relative;
35
+ display: flex;
36
+ align-items: center;
37
+ gap: 0.25rem;
38
+ color: var(--sl-color-gray-1);
39
+ }
40
+
41
+ label:hover {
42
+ color: var(--sl-color-gray-2);
43
+ }
44
+
45
+ .icon {
46
+ position: absolute;
47
+ top: 50%;
48
+ transform: translateY(-50%);
49
+ pointer-events: none;
50
+ }
51
+
52
+ .label-icon {
53
+ font-size: var(--sl-label-icon-size);
54
+ inset-inline-start: 0;
55
+ }
56
+
57
+ .caret {
58
+ font-size: var(--sl-caret-size);
59
+ inset-inline-end: 0;
60
+ }
61
+
62
+ select {
63
+ border: 0;
64
+ padding-block: 0.625rem;
65
+ padding-inline: calc(var(--sl-label-icon-size) + 0.25rem)
66
+ calc(var(--sl-caret-size) + 0.25rem);
67
+ width: var(--sl-select-width);
68
+ background-color: transparent;
69
+ text-overflow: ellipsis;
70
+ color: inherit;
71
+ cursor: pointer;
72
+ appearance: none;
73
+ }
74
+
75
+ @media (min-width: 50rem) {
76
+ select {
77
+ font-size: var(--sl-text-sm);
78
+ }
79
+ }
80
+ </style>
@@ -0,0 +1,34 @@
1
+ ---
2
+ import type { getSidebar } from '../utils/navigation';
3
+ import LanguageSelect from './LanguageSelect.astro';
4
+ import SidebarSublist from './SidebarSublist.astro';
5
+ import ThemeSelect from './ThemeSelect.astro';
6
+
7
+ interface Props {
8
+ sidebar: ReturnType<typeof getSidebar>;
9
+ locale: string | undefined;
10
+ }
11
+ ---
12
+
13
+ <div class="sidebar flex">
14
+ <SidebarSublist sublist={Astro.props.sidebar} />
15
+ <div class="mobile-preferences flex md:hidden">
16
+ <ThemeSelect />
17
+ <LanguageSelect locale={Astro.props.locale} />
18
+ </div>
19
+ </div>
20
+
21
+ <style>
22
+ .sidebar {
23
+ height: 100%;
24
+ padding: 1rem var(--sl-sidebar-pad-x);
25
+ flex-direction: column;
26
+ gap: 1rem;
27
+ }
28
+
29
+ .mobile-preferences {
30
+ justify-content: space-between;
31
+ border-top: 1px solid var(--sl-color-gray-6);
32
+ padding: 0.5rem 0;
33
+ }
34
+ </style>
@@ -0,0 +1,78 @@
1
+ ---
2
+ import type { SidebarEntry } from '../utils/navigation';
3
+
4
+ interface Props {
5
+ sublist: SidebarEntry[];
6
+ }
7
+ ---
8
+
9
+ <ul>
10
+ {
11
+ Astro.props.sublist.map((entry) => (
12
+ <li class:list={{ 'sidebar-group': entry.type === 'group' }}>
13
+ {entry.type === 'link' ? (
14
+ <a href={entry.href} aria-current={entry.isCurrent && 'true'}>
15
+ {entry.label}
16
+ </a>
17
+ ) : (
18
+ <>
19
+ <h2>{entry.label}</h2>
20
+ <Astro.self sublist={entry.entries} />
21
+ </>
22
+ )}
23
+ </li>
24
+ ))
25
+ }
26
+ </ul>
27
+
28
+ <style>
29
+ ul {
30
+ --sl-sidebar-item-padding-inline: 0.5rem;
31
+ list-style: none;
32
+ padding: 0;
33
+ }
34
+
35
+ h2 {
36
+ font-size: var(--sl-text-lg);
37
+ font-weight: 600;
38
+ color: var(--sl-color-white);
39
+ padding-inline: var(--sl-sidebar-item-padding-inline);
40
+ }
41
+
42
+ .sidebar-group + .sidebar-group {
43
+ margin-top: 0.75rem;
44
+ }
45
+
46
+ a {
47
+ display: block;
48
+ border-radius: 0.25rem;
49
+ text-decoration: none;
50
+ color: var(--sl-color-gray-2);
51
+ padding-inline: var(--sl-sidebar-item-padding-inline);
52
+ }
53
+
54
+ a:hover,
55
+ a:focus {
56
+ color: var(--sl-color-white);
57
+ }
58
+
59
+ [aria-current='true'],
60
+ [aria-current='true']:hover,
61
+ [aria-current='true']:focus {
62
+ font-weight: 600;
63
+ color: var(--sl-color-text-invert);
64
+ background-color: var(--sl-color-text-accent);
65
+ }
66
+
67
+ @media (min-width: 50rem) {
68
+ .sidebar-group + .sidebar-group {
69
+ margin-top: 0.5rem;
70
+ }
71
+ h2 {
72
+ font-size: var(--sl-text-base);
73
+ }
74
+ a {
75
+ font-size: var(--sl-text-xs);
76
+ }
77
+ }
78
+ </style>
@@ -0,0 +1,18 @@
1
+ <a href="#starlight__overview">Skip to content</a>
2
+
3
+ <style>
4
+ a {
5
+ position: fixed;
6
+ top: 0.75rem;
7
+ inset-inline-start: 0.75rem;
8
+ }
9
+ a:focus {
10
+ z-index: var(--sl-z-index-skiplink);
11
+ display: block;
12
+ padding: 0.5rem 1rem;
13
+ text-decoration: none;
14
+ color: var(--sl-color-text-invert);
15
+ background-color: var(--sl-color-text-accent);
16
+ box-shadow: var(--sl-shadow-lg);
17
+ }
18
+ </style>