@astrojs/starlight 0.9.0 → 0.10.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @astrojs/starlight
2
2
 
3
+ ## 0.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#692](https://github.com/withastro/starlight/pull/692) [`2a58e1a`](https://github.com/withastro/starlight/commit/2a58e1aa068d01833a0ab9e74e4b46cccaee1775) Thanks [@delucis](https://github.com/delucis)! - Upgrade Pagefind to v1 and display page headings in search results
8
+
9
+ ### Patch Changes
10
+
11
+ - [#708](https://github.com/withastro/starlight/pull/708) [`136cfb1`](https://github.com/withastro/starlight/commit/136cfb180f22db116cfdb62fd93d21daff596946) Thanks [@julien-deramond](https://github.com/julien-deramond)! - Fix main content column width for pages without a table of contents
12
+
13
+ - [#682](https://github.com/withastro/starlight/pull/682) [`660a5f5`](https://github.com/withastro/starlight/commit/660a5f57adf0340de21df3e364aada38255bb06c) Thanks [@vedmalex](https://github.com/vedmalex)! - Add Russian language support
14
+
15
+ ## 0.9.1
16
+
17
+ ### Patch Changes
18
+
19
+ - [#647](https://github.com/withastro/starlight/pull/647) [`ea57726`](https://github.com/withastro/starlight/commit/ea5772655274a3900310cb700836fdd2f6dba7cd) Thanks [@bgmort](https://github.com/bgmort)! - Fix translated 404 pages not being excluded from search results
20
+
21
+ - [#667](https://github.com/withastro/starlight/pull/667) [`9828f73`](https://github.com/withastro/starlight/commit/9828f739b73e2f377c1450b9e11f0914722ee440) Thanks [@delucis](https://github.com/delucis)! - Break inline `<code>` across lines to avoid overflow
22
+
23
+ - [#642](https://github.com/withastro/starlight/pull/642) [`e623d92`](https://github.com/withastro/starlight/commit/e623d92c2fddc0ff5fe83d2554266885d683a906) Thanks [@fk](https://github.com/fk)! - Don't hard-code nav height in table of contents highlighting script
24
+
25
+ - [#676](https://github.com/withastro/starlight/pull/676) [`6419006`](https://github.com/withastro/starlight/commit/641900615aa9a9a128d6934e65a57ba89e503cfd) Thanks [@vedmalex](https://github.com/vedmalex)! - Upgrade and pin Pagefind to latest beta release.
26
+
27
+ - [#647](https://github.com/withastro/starlight/pull/647) [`ea57726`](https://github.com/withastro/starlight/commit/ea5772655274a3900310cb700836fdd2f6dba7cd) Thanks [@bgmort](https://github.com/bgmort)! - Add frontmatter option to exclude a page from Pagefind search results
28
+
3
29
  ## 0.9.0
4
30
 
5
31
  ### Minor Changes
@@ -58,25 +58,28 @@ const pagefindTranslations = {
58
58
  const dialog = this.querySelector('dialog')!;
59
59
  const dialogFrame = this.querySelector('.dialog-frame')!;
60
60
 
61
- /** Close the modal if a user clicks outside of the modal. */
62
- const onWindowClick = (event: MouseEvent) => {
61
+ /** Close the modal if a user clicks on a link or outside of the modal. */
62
+ const onClick = (event: MouseEvent) => {
63
+ const isLink = 'href' in (event.target || {});
63
64
  if (
64
- document.body.contains(event.target as Node) &&
65
- !dialogFrame.contains(event.target as Node)
66
- )
65
+ isLink ||
66
+ (document.body.contains(event.target as Node) &&
67
+ !dialogFrame.contains(event.target as Node))
68
+ ) {
67
69
  closeModal();
70
+ }
68
71
  };
69
72
 
70
73
  const openModal = (event?: MouseEvent) => {
71
74
  dialog.showModal();
72
75
  this.querySelector('input')?.focus();
73
76
  event?.stopPropagation();
74
- window.addEventListener('click', onWindowClick);
77
+ window.addEventListener('click', onClick);
75
78
  };
76
79
 
77
80
  const closeModal = () => {
78
81
  dialog.close();
79
- window.removeEventListener('click', onWindowClick);
82
+ window.removeEventListener('click', onClick);
80
83
  };
81
84
 
82
85
  openBtn.addEventListener('click', openModal);
@@ -110,9 +113,10 @@ const pagefindTranslations = {
110
113
  new PagefindUI({
111
114
  element: '#starlight__search',
112
115
  baseUrl: import.meta.env.BASE_URL,
113
- bundlePath: import.meta.env.BASE_URL.replace(/\/$/, '') + '/_pagefind/',
116
+ bundlePath: import.meta.env.BASE_URL.replace(/\/$/, '') + '/pagefind/',
114
117
  showImages: false,
115
118
  translations,
119
+ showSubResults: true,
116
120
  });
117
121
  });
118
122
  });
@@ -179,7 +183,7 @@ const pagefindTranslations = {
179
183
  .dialog-frame {
180
184
  flex-direction: column;
181
185
  gap: 1rem;
182
- padding: 1.5rem;
186
+ padding: 1rem;
183
187
  }
184
188
 
185
189
  button[data-close-modal] {
@@ -218,10 +222,31 @@ const pagefindTranslations = {
218
222
  min-height: 15rem;
219
223
  max-height: calc(100% - 8rem);
220
224
  }
225
+
226
+ .dialog-frame {
227
+ padding: 1.5rem;
228
+ }
221
229
  }
222
230
  </style>
223
231
 
224
232
  <style is:global>
233
+ #starlight__search {
234
+ --sl-search-result-spacing: calc(1.25rem * var(--pagefind-ui-scale));
235
+ --sl-search-result-pad-inline-start: calc(3.75rem * var(--pagefind-ui-scale));
236
+ --sl-search-result-pad-inline-end: calc(1.25rem * var(--pagefind-ui-scale));
237
+ --sl-search-result-pad-block: calc(0.9375rem * var(--pagefind-ui-scale));
238
+ --sl-search-result-nested-pad-block: calc(0.625rem * var(--pagefind-ui-scale));
239
+ --sl-search-corners: calc(0.3125rem * var(--pagefind-ui-scale));
240
+ --sl-search-page-icon-size: calc(1.875rem * var(--pagefind-ui-scale));
241
+ --sl-search-page-icon-inline-start: calc(
242
+ (var(--sl-search-result-pad-inline-start) - var(--sl-search-page-icon-size)) / 2
243
+ );
244
+ --sl-search-tree-diagram-size: calc(2.5rem * var(--pagefind-ui-scale));
245
+ --sl-search-tree-diagram-inline-start: calc(
246
+ (var(--sl-search-result-pad-inline-start) - var(--sl-search-tree-diagram-size)) / 2
247
+ );
248
+ }
249
+
225
250
  #starlight__search .pagefind-ui__form::before {
226
251
  --pagefind-ui-text: var(--sl-color-gray-1);
227
252
  opacity: 1;
@@ -260,22 +285,36 @@ const pagefindTranslations = {
260
285
  }
261
286
 
262
287
  #starlight__search .pagefind-ui__results > * + * {
263
- margin-top: 0.5rem;
288
+ margin-top: var(--sl-search-result-spacing);
264
289
  }
265
290
  #starlight__search .pagefind-ui__result {
266
- position: relative;
267
291
  border: 0;
268
- border-radius: 0.25rem;
269
- padding: 1rem;
292
+ padding: 0;
293
+ }
294
+
295
+ #starlight__search .pagefind-ui__result-nested {
296
+ position: relative;
297
+ padding: var(--sl-search-result-nested-pad-block) var(--sl-search-result-pad-inline-end);
298
+ padding-inline-start: var(--sl-search-result-pad-inline-start);
299
+ }
300
+
301
+ #starlight__search .pagefind-ui__result-title:not(:where(.pagefind-ui__result-nested *)),
302
+ #starlight__search .pagefind-ui__result-nested {
303
+ position: relative;
270
304
  background-color: var(--sl-color-black);
271
305
  }
272
306
 
273
- #starlight__search .pagefind-ui__result:hover,
274
- #starlight__search .pagefind-ui__result:focus-within {
307
+ #starlight__search .pagefind-ui__result-title:not(:where(.pagefind-ui__result-nested *)):hover,
308
+ #starlight__search
309
+ .pagefind-ui__result-title:not(:where(.pagefind-ui__result-nested *)):focus-within,
310
+ #starlight__search .pagefind-ui__result-nested:hover,
311
+ #starlight__search .pagefind-ui__result-nested:focus-within {
275
312
  outline: 1px solid var(--sl-color-accent-high);
276
313
  }
277
314
 
278
- #starlight__search .pagefind-ui__result:focus-within {
315
+ #starlight__search
316
+ .pagefind-ui__result-title:not(:where(.pagefind-ui__result-nested *)):focus-within,
317
+ #starlight__search .pagefind-ui__result-nested:focus-within {
279
318
  background-color: var(--sl-color-accent-low);
280
319
  }
281
320
 
@@ -284,7 +323,37 @@ const pagefindTranslations = {
284
323
  margin-top: 0;
285
324
  }
286
325
 
326
+ #starlight__search .pagefind-ui__result-inner > :first-child {
327
+ border-radius: var(--sl-search-corners) var(--sl-search-corners) 0 0;
328
+ }
329
+ #starlight__search .pagefind-ui__result-inner > :last-child {
330
+ border-radius: 0 0 var(--sl-search-corners) var(--sl-search-corners);
331
+ }
332
+
333
+ #starlight__search .pagefind-ui__result-inner > .pagefind-ui__result-title {
334
+ padding: var(--sl-search-result-pad-block) var(--sl-search-result-pad-inline-end);
335
+ padding-inline-start: var(--sl-search-result-pad-inline-start);
336
+ }
337
+ #starlight__search .pagefind-ui__result-inner > .pagefind-ui__result-title::before {
338
+ content: '';
339
+ position: absolute;
340
+ inset-block: 0;
341
+ inset-inline-start: var(--sl-search-page-icon-inline-start);
342
+ width: var(--sl-search-page-icon-size);
343
+ background: var(--sl-color-gray-3);
344
+ -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='currentColor' viewBox='0 0 24 24'%3E%3Cpath d='M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3V8l-6-6a1 1 0 0 0-1 0H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V9Zm-6-4 3 3h-2a1 1 0 0 1-1-1V5Zm4 14a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z'/%3E%3C/svg%3E")
345
+ center no-repeat;
346
+ mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='currentColor' viewBox='0 0 24 24'%3E%3Cpath d='M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3V8l-6-6a1 1 0 0 0-1 0H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V9Zm-6-4 3 3h-2a1 1 0 0 1-1-1V5Zm4 14a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z'/%3E%3C/svg%3E")
347
+ center no-repeat;
348
+ }
349
+
350
+ #starlight__search .pagefind-ui__result-inner {
351
+ align-items: stretch;
352
+ gap: 1px;
353
+ }
354
+
287
355
  #starlight__search .pagefind-ui__result-link {
356
+ position: unset;
288
357
  --pagefind-ui-text: var(--sl-color-white);
289
358
  font-weight: 600;
290
359
  }
@@ -293,6 +362,27 @@ const pagefindTranslations = {
293
362
  text-decoration: none;
294
363
  }
295
364
 
365
+ #starlight__search .pagefind-ui__result-nested .pagefind-ui__result-link::before {
366
+ content: unset;
367
+ }
368
+
369
+ #starlight__search .pagefind-ui__result-nested::before {
370
+ content: '';
371
+ position: absolute;
372
+ inset-block: 0;
373
+ inset-inline-start: var(--sl-search-tree-diagram-inline-start);
374
+ width: var(--sl-search-tree-diagram-size);
375
+ background: var(--sl-color-gray-4);
376
+ -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m6-988H8'/%3E%3C/svg%3E")
377
+ 0% 0% / 100% no-repeat;
378
+ mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m6-988H8'/%3E%3C/svg%3E")
379
+ 0% 0% / 100% no-repeat;
380
+ }
381
+ #starlight__search .pagefind-ui__result-nested:last-child::before {
382
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 16 16'%3E%3Cpath d='M8 0v12m6 0H8'/%3E%3C/svg%3E");
383
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 16 16'%3E%3Cpath d='M8 0v12m6 0H8'/%3E%3C/svg%3E");
384
+ }
385
+
296
386
  #starlight__search .pagefind-ui__result-link::after {
297
387
  content: '';
298
388
  position: absolute;
@@ -300,18 +390,13 @@ const pagefindTranslations = {
300
390
  }
301
391
 
302
392
  #starlight__search .pagefind-ui__result-excerpt {
303
- font-size: var(--sl-text-body-sm);
393
+ font-size: calc(1rem * var(--pagefind-ui-scale));
304
394
  word-break: break-word;
305
395
  }
306
396
 
307
397
  #starlight__search mark {
308
- color: var(--sl-color-white);
309
- background-color: var(--sl-color-accent-low);
310
- font-weight: 500;
311
- padding: 0.1em 0.2em;
312
- }
313
-
314
- #starlight__search .pagefind-ui__result:focus-within mark {
315
- text-decoration: underline;
398
+ color: var(--sl-color-gray-2);
399
+ background-color: transparent;
400
+ font-weight: 600;
316
401
  }
317
402
  </style>
@@ -122,7 +122,7 @@ const t = useTranslations(locale);
122
122
  }
123
123
 
124
124
  constructor() {
125
- super({ smallViewport: true });
125
+ super();
126
126
  const details = this.querySelector('details');
127
127
  if (!details) return;
128
128
  const closeToC = () => {
@@ -10,7 +10,7 @@ export class StarlightTOC extends HTMLElement {
10
10
  this._current = link;
11
11
  }
12
12
 
13
- constructor({ smallViewport = false } = {}) {
13
+ constructor() {
14
14
  super();
15
15
 
16
16
  /** All the links in the table of contents. */
@@ -68,19 +68,13 @@ export class StarlightTOC extends HTMLElement {
68
68
  // Also observe direct children of `.content` to include elements before
69
69
  // the first heading.
70
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;
75
71
 
76
72
  let observer: IntersectionObserver | undefined;
77
- function observe() {
73
+ const observe = () => {
78
74
  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 });
75
+ observer = new IntersectionObserver(setCurrent, { rootMargin: this.getRootMargin() });
82
76
  toObserve.forEach((h) => observer!.observe(h));
83
- }
77
+ };
84
78
  observe();
85
79
 
86
80
  const onIdle = window.requestIdleCallback || ((cb) => setTimeout(cb, 1));
@@ -92,6 +86,18 @@ export class StarlightTOC extends HTMLElement {
92
86
  timeout = setTimeout(() => onIdle(observe), 200);
93
87
  });
94
88
  }
89
+
90
+ private getRootMargin(): `-${number}px 0% ${number}px` {
91
+ const navBarHeight = document.querySelector('header')?.getBoundingClientRect().height || 0;
92
+ // `<summary>` only exists in mobile ToC, so will fall back to 0 in large viewport component.
93
+ const mobileTocHeight = this.querySelector('summary')?.getBoundingClientRect().height || 0;
94
+ /** Start intersections at nav height + 2rem padding. */
95
+ const top = navBarHeight + mobileTocHeight + 32;
96
+ /** End intersections 1.5rem later. */
97
+ const bottom = top + 24;
98
+ const height = document.documentElement.clientHeight;
99
+ return `-${top}px 0% ${bottom - height}px`;
100
+ }
95
101
  }
96
102
 
97
103
  customElements.define('starlight-toc', StarlightTOC);
package/index.ts CHANGED
@@ -68,7 +68,7 @@ export default function StarlightIntegration(opts: StarlightUserConfig): AstroIn
68
68
  const cwd = dirname(fileURLToPath(import.meta.url));
69
69
  const relativeDir = relative(cwd, targetDir);
70
70
  return new Promise<void>((resolve) => {
71
- spawn('npx', ['-y', 'pagefind', '--source', relativeDir], {
71
+ spawn('npx', ['-y', 'pagefind', '--site', relativeDir], {
72
72
  stdio: 'inherit',
73
73
  shell: true,
74
74
  cwd,
package/layout/Page.astro CHANGED
@@ -45,6 +45,8 @@ const tocConfig = !hasSidebar
45
45
  : config.tableOfContents;
46
46
  const hasToC = Boolean(tocConfig);
47
47
  const hasHero = Boolean(entry.data.hero);
48
+ const pagefindEnabled =
49
+ entry.slug !== '404' && !entry.slug.endsWith('/404') && entry.data.pagefind !== false;
48
50
  ---
49
51
 
50
52
  <html
@@ -91,7 +93,7 @@ const hasHero = Boolean(entry.data.hero);
91
93
  {hasSidebar && <Sidebar slot="sidebar" {sidebar} {locale} />}
92
94
  <TwoColumnContent {hasToC}>
93
95
  <RightSidebar slot="right-sidebar" {headings} {locale} {tocConfig} />
94
- <main data-pagefind-body={entry.slug !== '404'} lang={entryMeta.lang} dir={entryMeta.dir}>
96
+ <main data-pagefind-body={pagefindEnabled} lang={entryMeta.lang} dir={entryMeta.dir}>
95
97
  {/* TODO: Revisit how this logic flows. */}
96
98
  {entry.data.banner && <Banner {...entry.data.banner} />}
97
99
  {
@@ -46,7 +46,7 @@ interface Props {
46
46
  width: 100%;
47
47
  }
48
48
 
49
- :global([data-has-sidebar]) .main-pane {
49
+ :global([data-has-sidebar][data-has-toc]) .main-pane {
50
50
  --sl-content-margin-inline: auto 0;
51
51
 
52
52
  order: 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/starlight",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Build beautiful, high-performance documentation websites with Astro",
5
5
  "keywords": [
6
6
  "docs",
@@ -39,13 +39,13 @@
39
39
  "dependencies": {
40
40
  "@astrojs/mdx": "^1.0.0",
41
41
  "@astrojs/sitemap": "^3.0.0",
42
- "@pagefind/default-ui": "^1.0.0-alpha.5",
42
+ "@pagefind/default-ui": "^1.0.2",
43
43
  "@types/mdast": "^3.0.11",
44
44
  "bcp-47": "^2.1.0",
45
45
  "execa": "^7.1.1",
46
46
  "hast-util-select": "^5.0.5",
47
47
  "hastscript": "^7.2.0",
48
- "pagefind": "^1.0.0-alpha.5",
48
+ "pagefind": "^1.0.2",
49
49
  "rehype": "^12.0.1",
50
50
  "remark-directive": "^2.0.1",
51
51
  "unified": "^10.1.2",
package/schema.ts CHANGED
@@ -165,5 +165,8 @@ export function docsSchema() {
165
165
  content: z.string(),
166
166
  })
167
167
  .optional(),
168
+
169
+ /** Pagefind indexing for this page - set to false to disable. */
170
+ pagefind: z.boolean().default(true),
168
171
  });
169
172
  }
package/style/reset.css CHANGED
@@ -38,7 +38,8 @@ h2,
38
38
  h3,
39
39
  h4,
40
40
  h5,
41
- h6 {
41
+ h6,
42
+ code {
42
43
  overflow-wrap: break-word;
43
44
  }
44
45
 
@@ -16,11 +16,12 @@ import nb from './nb.json';
16
16
  import zh from './zh.json';
17
17
  import ko from './ko.json';
18
18
  import sv from './sv.json';
19
+ import ru from './ru.json';
19
20
 
20
21
  const { parse } = builtinI18nSchema();
21
22
 
22
23
  export default Object.fromEntries(
23
- Object.entries({ cs, en, es, de, ja, pt, fa, fr, it, nl, da, tr, ar, nb, zh, ko, sv }).map(
24
+ Object.entries({ cs, en, es, de, ja, pt, fa, fr, it, nl, da, tr, ar, nb, zh, ko, sv, ru }).map(
24
25
  ([key, dict]) => [key, parse(dict)]
25
26
  )
26
27
  );
@@ -0,0 +1,22 @@
1
+ {
2
+ "skipLink.label": "Пропустить до содержимого",
3
+ "search.label": "Поиск",
4
+ "search.shortcutLabel": "(Нажмите / для Поиска)",
5
+ "search.cancelLabel": "Отменить",
6
+ "search.devWarning": "Поиск доступен только в производственных сборках. \nПопробуйте выполнить сборку и просмотреть сайт, чтобы протестировать его локально.",
7
+ "themeSelect.accessibleLabel": "Выберите тему",
8
+ "themeSelect.dark": "Темная",
9
+ "themeSelect.light": "Светлая",
10
+ "themeSelect.auto": "Авто",
11
+ "languageSelect.accessibleLabel": "Выберите язык",
12
+ "menuButton.accessibleLabel": "Меню",
13
+ "sidebarNav.accessibleLabel": "Основное",
14
+ "tableOfContents.onThisPage": "На странице",
15
+ "tableOfContents.overview": "Обзор",
16
+ "i18n.untranslatedContent": "Этот содержимое пока не доступно на вашем языке.",
17
+ "page.editLink": "Редактировать странице",
18
+ "page.lastUpdated": "Последнее обновление:",
19
+ "page.previousLink": "Предыдущая",
20
+ "page.nextLink": "Следующая",
21
+ "404.text": "Страница не найдена. Проверьтье URL или используйте поиск по сайту"
22
+ }