@astrojs/starlight 0.30.0 → 0.30.2

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,19 @@
1
1
  # @astrojs/starlight
2
2
 
3
+ ## 0.30.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#2702](https://github.com/withastro/starlight/pull/2702) [`02d16f3`](https://github.com/withastro/starlight/commit/02d16f3638db609501897c5e3647cc20eb5ec142) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Fixes an issue with autogenerated sidebars when using Starlight with Astro's new Content Layer API with directories containing spaces or special characters.
8
+
9
+ - [#2704](https://github.com/withastro/starlight/pull/2704) [`fd16470`](https://github.com/withastro/starlight/commit/fd164704b25ec5c000a2765eb0930b87e9a4e61e) Thanks [@delucis](https://github.com/delucis)! - Fixes display of focus indicator around site title
10
+
11
+ ## 0.30.1
12
+
13
+ ### Patch Changes
14
+
15
+ - [#2688](https://github.com/withastro/starlight/pull/2688) [`5c6996c`](https://github.com/withastro/starlight/commit/5c6996cd248e9da735a14e7fcaf638b51f2796bc) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Fixes an issue with autogenerated sidebars when using Starlight with Astro's new Content Layer API where group names would be sluggified.
16
+
3
17
  ## 0.30.0
4
18
 
5
19
  ### Minor Changes
@@ -41,7 +41,10 @@ const shouldRenderSearch =
41
41
 
42
42
  .title-wrapper {
43
43
  /* Prevent long titles overflowing and covering the search and menu buttons on narrow viewports. */
44
- overflow: hidden;
44
+ overflow: clip;
45
+ /* Avoid clipping focus ring around link inside title wrapper. */
46
+ padding: 0.25rem;
47
+ margin: -0.25rem;
45
48
  }
46
49
 
47
50
  .right-group,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/starlight",
3
- "version": "0.30.0",
3
+ "version": "0.30.2",
4
4
  "description": "Build beautiful, high-performance documentation websites with Astro",
5
5
  "keywords": [
6
6
  "docs",
@@ -1,5 +1,6 @@
1
1
  import { AstroError } from 'astro/errors';
2
2
  import config from 'virtual:starlight/user-config';
3
+ import project from 'virtual:starlight/project-context';
3
4
  import type { Badge, I18nBadge, I18nBadgeConfig } from '../schemas/badge';
4
5
  import type { PrevNextLinkConfig } from '../schemas/prevNextLink';
5
6
  import type {
@@ -14,14 +15,17 @@ import { formatPath } from './format-path';
14
15
  import { BuiltInDefaultLocale, pickLang } from './i18n';
15
16
  import { ensureLeadingSlash, ensureTrailingSlash, stripLeadingAndTrailingSlashes } from './path';
16
17
  import { getLocaleRoutes, routes, type Route } from './routing';
17
- import { localeToLang, slugToPathname } from './slugs';
18
+ import { localeToLang, localizedId, slugToPathname } from './slugs';
18
19
  import type { StarlightConfig } from './user-config';
20
+ import { getCollectionPathFromRoot } from './collection';
19
21
 
20
22
  const DirKey = Symbol('DirKey');
21
23
  const SlugKey = Symbol('SlugKey');
22
24
 
23
25
  const neverPathFormatter = createPathFormatter({ trailingSlash: 'never' });
24
26
 
27
+ const docsCollectionPathFromRoot = getCollectionPathFromRoot('docs', project);
28
+
25
29
  export interface Link {
26
30
  type: 'link';
27
31
  label: string;
@@ -101,14 +105,16 @@ function groupFromAutogenerateConfig(
101
105
  ): Group {
102
106
  const { collapsed: subgroupCollapsed, directory } = item.autogenerate;
103
107
  const localeDir = locale ? locale + '/' + directory : directory;
104
- const dirDocs = routes.filter(
105
- (doc) =>
108
+ const dirDocs = routes.filter((doc) => {
109
+ const filePathFromContentDir = getRoutePathRelativeToCollectionRoot(doc, locale);
110
+ return (
106
111
  // Match against `foo.md` or `foo/index.md`.
107
- stripExtension(doc.id) === localeDir ||
112
+ stripExtension(filePathFromContentDir) === localeDir ||
108
113
  // Match against `foo/anything/else.md`.
109
- doc.id.startsWith(localeDir + '/')
110
- );
111
- const tree = treeify(dirDocs, localeDir);
114
+ filePathFromContentDir.startsWith(localeDir + '/')
115
+ );
116
+ });
117
+ const tree = treeify(dirDocs, locale, localeDir);
112
118
  const label = pickLang(item.translations, localeToLang(locale)) || item.label;
113
119
  return {
114
120
  type: 'group',
@@ -205,8 +211,8 @@ function pathsMatch(pathA: string, pathB: string) {
205
211
  function getBreadcrumbs(path: string, baseDir: string): string[] {
206
212
  // Strip extension from path.
207
213
  const pathWithoutExt = stripExtension(path);
208
- // Index paths will match `baseDir` but we still need to consider them as a single segment.
209
- if (pathWithoutExt === baseDir) return [path];
214
+ // Index paths will match `baseDir` and don’t include breadcrumbs.
215
+ if (pathWithoutExt === baseDir) return [];
210
216
  // Ensure base directory ends in a trailing slash.
211
217
  baseDir = ensureTrailingSlash(baseDir);
212
218
  // Strip base directory from path if present.
@@ -217,17 +223,27 @@ function getBreadcrumbs(path: string, baseDir: string): string[] {
217
223
  return relativePath.split('/');
218
224
  }
219
225
 
226
+ /** Return the path of a route relative to the root of the collection, which is equivalent to legacy IDs. */
227
+ function getRoutePathRelativeToCollectionRoot(route: Route, locale: string | undefined) {
228
+ return project.legacyCollections
229
+ ? route.id
230
+ : // For collections with a loader, use a localized filePath relative to the collection
231
+ localizedId(route.entry.filePath.replace(`${docsCollectionPathFromRoot}/`, ''), locale);
232
+ }
233
+
220
234
  /** Turn a flat array of routes into a tree structure. */
221
- function treeify(routes: Route[], baseDir: string): Dir {
235
+ function treeify(routes: Route[], locale: string | undefined, baseDir: string): Dir {
222
236
  const treeRoot: Dir = makeDir(baseDir);
223
237
  routes
224
238
  // Remove any entries that should be hidden
225
239
  .filter((doc) => !doc.entry.data.sidebar.hidden)
240
+ // Compute the path of each entry from the root of the collection ahead of time.
241
+ .map((doc) => [getRoutePathRelativeToCollectionRoot(doc, locale), doc] as const)
226
242
  // Sort by depth, to build the tree depth first.
227
- .sort((a, b) => b.id.split('/').length - a.id.split('/').length)
243
+ .sort(([a], [b]) => b.split('/').length - a.split('/').length)
228
244
  // Build the tree
229
- .forEach((doc) => {
230
- const parts = getBreadcrumbs(doc.id, baseDir);
245
+ .forEach(([filePathFromContentDir, doc]) => {
246
+ const parts = getBreadcrumbs(filePathFromContentDir, baseDir);
231
247
  let currentNode = treeRoot;
232
248
 
233
249
  parts.forEach((part, index) => {
@@ -374,7 +390,7 @@ function getIntermediateSidebarFromConfig(
374
390
  if (sidebarConfig) {
375
391
  return sidebarConfig.map((group) => configItemToEntry(group, pathname, locale, routes));
376
392
  } else {
377
- const tree = treeify(routes, locale || '');
393
+ const tree = treeify(routes, locale, locale || '');
378
394
  return sidebarFromDir(tree, pathname, locale, false);
379
395
  }
380
396
  }
package/utils/slugs.ts CHANGED
@@ -82,7 +82,8 @@ export function localizedSlug(slug: string, locale: string | undefined): string
82
82
  }
83
83
 
84
84
  /**
85
- * Convert a legacy collection entry ID to a different locale.
85
+ * Convert a legacy collection entry ID or filePath relative to the collection root to a different
86
+ * locale.
86
87
  * For example, passing an ID of `en/home.md` and a locale of `fr` results in `fr/home.md`.
87
88
  * An undefined locale is treated as the root locale, resulting in `home.md`.
88
89
  * @param id A collection entry ID