@astrojs/starlight 0.33.1 → 0.34.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 (85) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/components/AnchorHeading.astro +53 -0
  3. package/components/Banner.astro +14 -12
  4. package/components/ContentNotice.astro +13 -11
  5. package/components/ContentPanel.astro +17 -15
  6. package/components/EditLink.astro +10 -8
  7. package/components/Footer.astro +30 -28
  8. package/components/Header.astro +54 -51
  9. package/components/Hero.astro +60 -58
  10. package/components/MobileMenuFooter.astro +19 -16
  11. package/components/MobileMenuToggle.astro +41 -37
  12. package/components/MobileTableOfContents.astro +71 -69
  13. package/components/Page.astro +8 -8
  14. package/components/PageFrame.astro +61 -57
  15. package/components/PageSidebar.astro +33 -31
  16. package/components/PageTitle.astro +8 -6
  17. package/components/Pagination.astro +38 -36
  18. package/components/Search.astro +277 -272
  19. package/components/Select.astro +50 -46
  20. package/components/SidebarPersister.astro +4 -2
  21. package/components/SidebarSublist.astro +78 -76
  22. package/components/SiteTitle.astro +17 -15
  23. package/components/SkipLink.astro +17 -15
  24. package/components/SocialIcons.astro +9 -7
  25. package/components/TableOfContents/TableOfContentsList.astro +49 -47
  26. package/components/TwoColumnContent.astro +32 -30
  27. package/index.ts +11 -4
  28. package/integrations/expressive-code/index.ts +2 -0
  29. package/integrations/heading-links.ts +104 -0
  30. package/integrations/virtual-user-config.ts +9 -0
  31. package/package.json +12 -7
  32. package/schemas/head.ts +2 -2
  33. package/schemas/i18n.ts +2 -0
  34. package/style/anchor-links.css +125 -0
  35. package/style/asides.css +46 -44
  36. package/style/layers.css +1 -0
  37. package/style/markdown.css +195 -189
  38. package/style/print.css +30 -35
  39. package/style/props.css +180 -178
  40. package/style/reset.css +42 -40
  41. package/style/util.css +51 -49
  42. package/translations/ar.json +2 -1
  43. package/translations/ca.json +2 -1
  44. package/translations/cs.json +2 -1
  45. package/translations/da.json +2 -1
  46. package/translations/de.json +2 -1
  47. package/translations/en.json +2 -1
  48. package/translations/es.json +2 -1
  49. package/translations/fa.json +2 -1
  50. package/translations/fr.json +2 -1
  51. package/translations/gl.json +2 -1
  52. package/translations/he.json +2 -1
  53. package/translations/hi.json +2 -1
  54. package/translations/id.json +2 -1
  55. package/translations/it.json +2 -1
  56. package/translations/ja.json +2 -1
  57. package/translations/ko.json +2 -1
  58. package/translations/lv.json +2 -1
  59. package/translations/nb.json +2 -1
  60. package/translations/nl.json +2 -1
  61. package/translations/pl.json +2 -1
  62. package/translations/pt.json +2 -1
  63. package/translations/ro.json +2 -1
  64. package/translations/ru.json +2 -1
  65. package/translations/sk.json +2 -1
  66. package/translations/sv.json +2 -1
  67. package/translations/tr.json +2 -1
  68. package/translations/uk.json +2 -1
  69. package/translations/vi.json +2 -1
  70. package/translations/zh-CN.json +2 -1
  71. package/translations/zh-TW.json +2 -1
  72. package/user-components/Badge.astro +118 -116
  73. package/user-components/Card.astro +44 -42
  74. package/user-components/CardGrid.astro +20 -18
  75. package/user-components/FileTree.astro +105 -103
  76. package/user-components/Icon.astro +7 -5
  77. package/user-components/LinkButton.astro +43 -41
  78. package/user-components/LinkCard.astro +45 -43
  79. package/user-components/Steps.astro +65 -61
  80. package/user-components/Tabs.astro +35 -33
  81. package/utils/head.ts +12 -4
  82. package/utils/starlight-page.ts +16 -19
  83. package/utils/user-config.ts +14 -0
  84. package/virtual-internal.d.ts +2 -0
  85. package/style/shiki.css +0 -13
@@ -98,43 +98,45 @@ if (isSynced) {
98
98
  </starlight-tabs>
99
99
 
100
100
  <style>
101
- starlight-tabs {
102
- display: block;
103
- }
101
+ @layer starlight.components {
102
+ starlight-tabs {
103
+ display: block;
104
+ }
104
105
 
105
- .tablist-wrapper {
106
- overflow-x: auto;
107
- }
106
+ .tablist-wrapper {
107
+ overflow-x: auto;
108
+ }
108
109
 
109
- [role='tablist'] {
110
- display: flex;
111
- list-style: none;
112
- border-bottom: 2px solid var(--sl-color-gray-5);
113
- padding: 0;
114
- }
110
+ [role='tablist'] {
111
+ display: flex;
112
+ list-style: none;
113
+ border-bottom: 2px solid var(--sl-color-gray-5);
114
+ padding: 0;
115
+ }
115
116
 
116
- .tab {
117
- margin-bottom: -2px;
118
- }
119
- .tab > [role='tab'] {
120
- display: flex;
121
- align-items: center;
122
- gap: 0.5rem;
123
- padding: 0 1.25rem;
124
- text-decoration: none;
125
- border-bottom: 2px solid var(--sl-color-gray-5);
126
- color: var(--sl-color-gray-3);
127
- outline-offset: var(--sl-outline-offset-inside);
128
- overflow-wrap: initial;
129
- }
130
- .tab [role='tab'][aria-selected='true'] {
131
- color: var(--sl-color-white);
132
- border-color: var(--sl-color-text-accent);
133
- font-weight: 600;
134
- }
117
+ .tab {
118
+ margin-bottom: -2px;
119
+ }
120
+ .tab > [role='tab'] {
121
+ display: flex;
122
+ align-items: center;
123
+ gap: 0.5rem;
124
+ padding: 0 1.25rem;
125
+ text-decoration: none;
126
+ border-bottom: 2px solid var(--sl-color-gray-5);
127
+ color: var(--sl-color-gray-3);
128
+ outline-offset: var(--sl-outline-offset-inside);
129
+ overflow-wrap: initial;
130
+ }
131
+ .tab [role='tab'][aria-selected='true'] {
132
+ color: var(--sl-color-white);
133
+ border-color: var(--sl-color-text-accent);
134
+ font-weight: 600;
135
+ }
135
136
 
136
- .tablist-wrapper ~ :global([role='tabpanel']) {
137
- margin-top: 1rem;
137
+ .tablist-wrapper ~ :global([role='tabpanel']) {
138
+ margin-top: 1rem;
139
+ }
138
140
  }
139
141
  </style>
140
142
 
package/utils/head.ts CHANGED
@@ -134,7 +134,9 @@ function hasTag(head: HeadConfig, entry: HeadConfig[number]): boolean {
134
134
  case 'meta':
135
135
  return hasOneOf(head, entry, ['name', 'property', 'http-equiv']);
136
136
  case 'link':
137
- return head.some(({ attrs }) => entry.attrs.rel === 'canonical' && attrs.rel === 'canonical');
137
+ return head.some(
138
+ ({ attrs }) => entry.attrs?.rel === 'canonical' && attrs?.rel === 'canonical'
139
+ );
138
140
  default:
139
141
  return false;
140
142
  }
@@ -148,7 +150,7 @@ function hasOneOf(head: HeadConfig, entry: HeadConfig[number], keys: string[]):
148
150
  const attr = getAttr(keys, entry);
149
151
  if (!attr) return false;
150
152
  const [key, val] = attr;
151
- return head.some(({ tag, attrs }) => tag === entry.tag && attrs[key] === val);
153
+ return head.some(({ tag, attrs }) => tag === entry.tag && attrs?.[key] === val);
152
154
  }
153
155
 
154
156
  /** Find the first matching key–value pair in a head entry’s attributes. */
@@ -158,7 +160,7 @@ function getAttr(
158
160
  ): [key: string, value: string | boolean] | undefined {
159
161
  let attr: [string, string | boolean] | undefined;
160
162
  for (const key of keys) {
161
- const val = entry.attrs[key];
163
+ const val = entry.attrs?.[key];
162
164
  if (val) {
163
165
  attr = [key, val];
164
166
  break;
@@ -186,6 +188,7 @@ function getImportance(entry: HeadConfig[number]) {
186
188
  // 1. Important meta tags.
187
189
  if (
188
190
  entry.tag === 'meta' &&
191
+ entry.attrs &&
189
192
  ('charset' in entry.attrs || 'http-equiv' in entry.attrs || entry.attrs.name === 'viewport')
190
193
  ) {
191
194
  return 100;
@@ -197,7 +200,12 @@ function getImportance(entry: HeadConfig[number]) {
197
200
  // The default favicon should be below any extra icons that the user may have set
198
201
  // because if several icons are equally appropriate, the last one is used and we
199
202
  // want to use the SVG icon when supported.
200
- if (entry.tag === 'link' && 'rel' in entry.attrs && entry.attrs.rel === 'shortcut icon') {
203
+ if (
204
+ entry.tag === 'link' &&
205
+ entry.attrs &&
206
+ 'rel' in entry.attrs &&
207
+ entry.attrs.rel === 'shortcut icon'
208
+ ) {
201
209
  return 70;
202
210
  }
203
211
  return 80;
@@ -1,5 +1,5 @@
1
1
  import { z } from 'astro/zod';
2
- import { type ContentConfig, type SchemaContext } from 'astro:content';
2
+ import { type ContentConfig, type ImageFunction, type SchemaContext } from 'astro:content';
3
3
  import project from 'virtual:starlight/project-context';
4
4
  import config from 'virtual:starlight/user-config';
5
5
  import { getCollectionPathFromRoot } from './collection';
@@ -179,25 +179,22 @@ export async function generateStarlightPageRouteData({
179
179
 
180
180
  /** Validates the Starlight page frontmatter properties from the props received by a Starlight page. */
181
181
  async function getStarlightPageFrontmatter(frontmatter: StarlightPageFrontmatter) {
182
- // This needs to be in sync with ImageMetadata.
183
- // https://github.com/withastro/astro/blob/cf993bc263b58502096f00d383266cd179f331af/packages/astro/src/assets/types.ts#L32
184
182
  const schema = await StarlightPageFrontmatterSchema({
185
- image: () =>
186
- z.object({
187
- src: z.string(),
188
- width: z.number(),
189
- height: z.number(),
190
- format: z.union([
191
- z.literal('png'),
192
- z.literal('jpg'),
193
- z.literal('jpeg'),
194
- z.literal('tiff'),
195
- z.literal('webp'),
196
- z.literal('gif'),
197
- z.literal('svg'),
198
- z.literal('avif'),
199
- ]),
200
- }),
183
+ image: (() =>
184
+ // Mock validator for ImageMetadata.
185
+ // https://github.com/withastro/astro/blob/cf993bc263b58502096f00d383266cd179f331af/packages/astro/src/assets/types.ts#L32
186
+ // It uses a custom validation approach because imported SVGs have a type of `function` as
187
+ // well as containing the metadata properties and this ensures we handle those correctly.
188
+ z.custom(
189
+ (value) =>
190
+ value &&
191
+ (typeof value === 'function' || typeof value === 'object') &&
192
+ 'src' in value &&
193
+ 'width' in value &&
194
+ 'height' in value &&
195
+ 'format' in value,
196
+ 'Invalid image passed to `<StarlightPage>` component. Expected imported `ImageMetadata` object.'
197
+ )) as ImageFunction,
201
198
  });
202
199
 
203
200
  // Starting with Astro 4.14.0, a frontmatter schema that contains collection references will
@@ -244,6 +244,20 @@ const UserConfigSchema = z.object({
244
244
  }
245
245
  })
246
246
  .describe('Add middleware to process Starlight’s route data for each page.'),
247
+
248
+ /** Configure features that impact Starlight’s Markdown processing. */
249
+ markdown: z
250
+ .object({
251
+ /** Define whether headings in content should be rendered with clickable anchor links. Default: `true`. */
252
+ headingLinks: z
253
+ .boolean()
254
+ .default(true)
255
+ .describe(
256
+ 'Define whether headings in content should be rendered with clickable anchor links. Default: `true`.'
257
+ ),
258
+ })
259
+ .default({})
260
+ .describe('Configure features that impact Starlight’s Markdown processing.'),
247
261
  });
248
262
 
249
263
  export const StarlightConfigSchema = UserConfigSchema.strict()
@@ -4,6 +4,8 @@ declare module 'virtual:starlight/git-info' {
4
4
 
5
5
  declare module 'virtual:starlight/user-css' {}
6
6
 
7
+ declare module 'virtual:starlight/optional-css' {}
8
+
7
9
  declare module 'virtual:starlight/user-images' {
8
10
  type ImageMetadata = import('astro').ImageMetadata;
9
11
  export const logos: {
package/style/shiki.css DELETED
@@ -1,13 +0,0 @@
1
- :root {
2
- --astro-code-foreground: var(--sl-color-white);
3
- --astro-code-background: var(--sl-color-gray-6);
4
- --astro-code-token-constant: var(--sl-color-blue-high);
5
- --astro-code-token-string: var(--sl-color-green-high);
6
- --astro-code-token-comment: var(--sl-color-gray-2);
7
- --astro-code-token-keyword: var(--sl-color-purple-high);
8
- --astro-code-token-parameter: var(--sl-color-red-high);
9
- --astro-code-token-function: var(--sl-color-red-high);
10
- --astro-code-token-string-expression: var(--sl-color-green-high);
11
- --astro-code-token-punctuation: var(--sl-color-gray-2);
12
- --astro-code-token-link: var(--sl-color-blue-high);
13
- }