@astrojs/starlight 0.16.0 → 0.17.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,13 @@
1
1
  # @astrojs/starlight
2
2
 
3
+ ## 0.17.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1389](https://github.com/withastro/starlight/pull/1389) [`21b3620`](https://github.com/withastro/starlight/commit/21b36201aa1e01c8395d0f24b2fa4e32b90550bb) Thanks [@connor-baer](https://github.com/connor-baer)! - Adds new `disable404Route` config option to disable injection of Astro’s default 404 route
8
+
9
+ - [#1395](https://github.com/withastro/starlight/pull/1395) [`ce05dfb`](https://github.com/withastro/starlight/commit/ce05dfb4b1e9b90fad057d5d4328e4445f986b3b) Thanks [@hippotastic](https://github.com/hippotastic)! - Adds a new [`<Code>` component](https://starlight.astro.build/guides/components/#code) to render dynamic code strings with Expressive Code
10
+
3
11
  ## 0.16.0
4
12
 
5
13
  ### Minor Changes
package/components.ts CHANGED
@@ -4,3 +4,4 @@ export { default as Icon } from './user-components/Icon.astro';
4
4
  export { default as Tabs } from './user-components/Tabs.astro';
5
5
  export { default as TabItem } from './user-components/TabItem.astro';
6
6
  export { default as LinkCard } from './user-components/LinkCard.astro';
7
+ export { Code } from 'astro-expressive-code/components';
package/index.ts CHANGED
@@ -39,10 +39,12 @@ export default function StarlightIntegration({
39
39
 
40
40
  const useTranslations = createTranslationSystemFromFs(starlightConfig, config);
41
41
 
42
- injectRoute({
43
- pattern: '404',
44
- entrypoint: '@astrojs/starlight/404.astro',
45
- });
42
+ if (!userConfig.disable404Route) {
43
+ injectRoute({
44
+ pattern: '404',
45
+ entrypoint: '@astrojs/starlight/404.astro',
46
+ });
47
+ }
46
48
  injectRoute({
47
49
  pattern: '[...slug]',
48
50
  entrypoint: '@astrojs/starlight/index.astro',
@@ -51,9 +53,7 @@ export default function StarlightIntegration({
51
53
  // config or by a plugin.
52
54
  const allIntegrations = [...config.integrations, ...integrations];
53
55
  if (!allIntegrations.find(({ name }) => name === 'astro-expressive-code')) {
54
- integrations.push(
55
- ...starlightExpressiveCode({ starlightConfig, astroConfig: config, useTranslations })
56
- );
56
+ integrations.push(...starlightExpressiveCode({ starlightConfig, useTranslations }));
57
57
  }
58
58
  if (!allIntegrations.find(({ name }) => name === '@astrojs/sitemap')) {
59
59
  integrations.push(starlightSitemap(starlightConfig));
@@ -34,3 +34,5 @@
34
34
  */
35
35
 
36
36
  export * from 'astro-expressive-code';
37
+
38
+ export { getStarlightEcConfigPreprocessor } from './index';
@@ -2,8 +2,9 @@ import {
2
2
  astroExpressiveCode,
3
3
  type AstroExpressiveCodeOptions,
4
4
  addClassName,
5
+ type CustomConfigPreprocessors,
5
6
  } from 'astro-expressive-code';
6
- import type { AstroConfig, AstroIntegration } from 'astro';
7
+ import type { AstroIntegration } from 'astro';
7
8
  import type { StarlightConfig } from '../../types';
8
9
  import type { createTranslationSystemFromFs } from '../../utils/translations-fs';
9
10
  import { pathToLocale } from '../shared/pathToLocale';
@@ -60,56 +61,59 @@ export type StarlightExpressiveCodeOptions = Omit<AstroExpressiveCodeOptions, 't
60
61
  useStarlightUiThemeColors?: boolean | undefined;
61
62
  };
62
63
 
63
- export const starlightExpressiveCode = ({
64
- astroConfig,
64
+ type StarlightEcIntegrationOptions = {
65
+ starlightConfig: StarlightConfig;
66
+ useTranslations?: ReturnType<typeof createTranslationSystemFromFs> | undefined;
67
+ };
68
+
69
+ /**
70
+ * Create an Expressive Code configuration preprocessor based on Starlight config.
71
+ * Used internally to set up Expressive Code and by the `<Code>` component.
72
+ */
73
+ export function getStarlightEcConfigPreprocessor({
65
74
  starlightConfig,
66
75
  useTranslations,
67
- }: {
68
- astroConfig: Pick<AstroConfig, 'root' | 'srcDir'>;
69
- starlightConfig: StarlightConfig;
70
- useTranslations: ReturnType<typeof createTranslationSystemFromFs>;
71
- }): AstroIntegration[] => {
72
- const { locales, expressiveCode } = starlightConfig;
73
- if (expressiveCode === false) return [];
74
- const config: StarlightExpressiveCodeOptions =
75
- typeof expressiveCode === 'object' ? expressiveCode : {};
76
+ }: StarlightEcIntegrationOptions): CustomConfigPreprocessors['preprocessAstroIntegrationConfig'] {
77
+ return (input): AstroExpressiveCodeOptions => {
78
+ const astroConfig = input.astroConfig;
79
+ const ecConfig = input.ecConfig as StarlightExpressiveCodeOptions;
80
+ const { locales } = starlightConfig;
76
81
 
77
- const {
78
- themes: themesInput,
79
- customizeTheme,
80
- styleOverrides: { textMarkers: textMarkersStyleOverrides, ...otherStyleOverrides } = {},
81
- useStarlightDarkModeSwitch,
82
- useStarlightUiThemeColors = config.themes === undefined,
83
- plugins = [],
84
- ...rest
85
- } = config;
82
+ const {
83
+ themes: themesInput,
84
+ customizeTheme,
85
+ styleOverrides: { textMarkers: textMarkersStyleOverrides, ...otherStyleOverrides } = {},
86
+ useStarlightDarkModeSwitch,
87
+ useStarlightUiThemeColors = ecConfig.themes === undefined,
88
+ plugins = [],
89
+ ...rest
90
+ } = ecConfig;
86
91
 
87
- // Handle the `themes` option
88
- const themes = preprocessThemes(themesInput);
89
- if (useStarlightUiThemeColors === true && themes.length < 2) {
90
- console.warn(
91
- `*** Warning: Using the config option "useStarlightUiThemeColors: true" ` +
92
- `with a single theme is not recommended. For better color contrast, ` +
93
- `please provide at least one dark and one light theme.\n`
94
- );
95
- }
92
+ // Handle the `themes` option
93
+ const themes = preprocessThemes(themesInput);
94
+ if (useStarlightUiThemeColors === true && themes.length < 2) {
95
+ console.warn(
96
+ `*** Warning: Using the config option "useStarlightUiThemeColors: true" ` +
97
+ `with a single theme is not recommended. For better color contrast, ` +
98
+ `please provide at least one dark and one light theme.\n`
99
+ );
100
+ }
96
101
 
97
- // Add the `not-content` class to all rendered blocks to prevent them from being affected
98
- // by Starlight's default content styles
99
- plugins.push({
100
- name: 'Starlight Plugin',
101
- hooks: {
102
- postprocessRenderedBlock: ({ renderData }) => {
103
- addClassName(renderData.blockAst, 'not-content');
102
+ // Add the `not-content` class to all rendered blocks to prevent them from being affected
103
+ // by Starlight's default content styles
104
+ plugins.push({
105
+ name: 'Starlight Plugin',
106
+ hooks: {
107
+ postprocessRenderedBlock: ({ renderData }) => {
108
+ addClassName(renderData.blockAst, 'not-content');
109
+ },
104
110
  },
105
- },
106
- });
111
+ });
107
112
 
108
- // Add Expressive Code UI translations (if any) for all defined locales
109
- addTranslations(locales, useTranslations);
113
+ // Add Expressive Code UI translations (if any) for all defined locales
114
+ if (useTranslations) addTranslations(locales, useTranslations);
110
115
 
111
- return [
112
- astroExpressiveCode({
116
+ return {
113
117
  themes,
114
118
  customizeTheme: (theme) => {
115
119
  if (useStarlightUiThemeColors) {
@@ -151,6 +155,36 @@ export const starlightExpressiveCode = ({
151
155
  getBlockLocale: ({ file }) => pathToLocale(file.path, { starlightConfig, astroConfig }),
152
156
  plugins,
153
157
  ...rest,
158
+ };
159
+ };
160
+ }
161
+
162
+ export const starlightExpressiveCode = ({
163
+ starlightConfig,
164
+ useTranslations,
165
+ }: StarlightEcIntegrationOptions): AstroIntegration[] => {
166
+ if (starlightConfig.expressiveCode === false) return [];
167
+
168
+ const configArgs =
169
+ typeof starlightConfig.expressiveCode === 'object'
170
+ ? (starlightConfig.expressiveCode as AstroExpressiveCodeOptions)
171
+ : {};
172
+ return [
173
+ astroExpressiveCode({
174
+ ...configArgs,
175
+ customConfigPreprocessors: {
176
+ preprocessAstroIntegrationConfig: getStarlightEcConfigPreprocessor({
177
+ starlightConfig,
178
+ useTranslations,
179
+ }),
180
+ preprocessComponentConfig: `
181
+ import starlightConfig from 'virtual:starlight/user-config'
182
+ import { useTranslations } from '@astrojs/starlight/internal'
183
+ import { getStarlightEcConfigPreprocessor } from '@astrojs/starlight/expressive-code'
184
+
185
+ export default getStarlightEcConfigPreprocessor({ starlightConfig, useTranslations })
186
+ `,
187
+ },
154
188
  }),
155
189
  ];
156
190
  };
@@ -1,5 +1,6 @@
1
- import fs from 'node:fs';
2
1
  import { ExpressiveCodeTheme, type ThemeObjectOrShikiThemeName } from 'astro-expressive-code';
2
+ import nightOwlDark from './themes/night-owl-dark.jsonc?raw';
3
+ import nightOwlLight from './themes/night-owl-light.jsonc?raw';
3
4
 
4
5
  export type BundledThemeName = 'starlight-dark' | 'starlight-light';
5
6
 
@@ -20,13 +21,8 @@ export function preprocessThemes(
20
21
  return themes.map((theme) => {
21
22
  // If the current entry is the name of a bundled theme, load it
22
23
  if (theme === 'starlight-dark' || theme === 'starlight-light') {
23
- const bundledThemeFile =
24
- theme === 'starlight-dark' ? 'night-owl-dark.jsonc' : 'night-owl-light.jsonc';
25
- return customizeBundledTheme(
26
- ExpressiveCodeTheme.fromJSONString(
27
- fs.readFileSync(new URL(`./themes/${bundledThemeFile}`, import.meta.url), 'utf-8')
28
- )
29
- );
24
+ const bundledTheme = theme === 'starlight-dark' ? nightOwlDark : nightOwlLight;
25
+ return customizeBundledTheme(ExpressiveCodeTheme.fromJSONString(bundledTheme));
30
26
  }
31
27
  // Otherwise, just pass it through
32
28
  return theme;
@@ -22,11 +22,13 @@ export function pathToLocale(
22
22
  ): string | undefined {
23
23
  const srcDir = new URL(astroConfig.srcDir, astroConfig.root);
24
24
  const docsDir = new URL('content/docs/', srcDir);
25
- const slug = path
26
- // Format path to unix style path.
27
- ?.replace(/\\/g, '/')
28
- // Strip docs path leaving only content collection file ID.
29
- // Example: /Users/houston/repo/src/content/docs/en/guide.md => en/guide.md
30
- .replace(docsDir.pathname, '');
25
+ // Format path to unix style path.
26
+ path = path?.replace(/\\/g, '/');
27
+ // Ensure that the page path starts with a slash if the docs directory also does,
28
+ // which makes stripping the docs path in the next step work on Windows, too.
29
+ if (path && !path.startsWith('/') && docsDir.pathname.startsWith('/')) path = '/' + path;
30
+ // Strip docs path leaving only content collection file ID.
31
+ // Example: /Users/houston/repo/src/content/docs/en/guide.md => en/guide.md
32
+ const slug = path?.replace(docsDir.pathname, '');
31
33
  return slugToLocale(slug, starlightConfig.locales);
32
34
  }
package/internal.ts ADDED
@@ -0,0 +1 @@
1
+ export { useTranslations } from './utils/translations';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/starlight",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "Build beautiful, high-performance documentation websites with Astro",
5
5
  "keywords": [
6
6
  "docs",
@@ -150,6 +150,7 @@
150
150
  "types": "./components/Search.astro.tsx",
151
151
  "import": "./components/Search.astro"
152
152
  },
153
+ "./internal": "./internal.ts",
153
154
  "./props": "./props.ts",
154
155
  "./schema": "./schema.ts",
155
156
  "./types": "./types.ts",
@@ -174,7 +175,7 @@
174
175
  "@pagefind/default-ui": "^1.0.3",
175
176
  "@types/hast": "^3.0.3",
176
177
  "@types/mdast": "^4.0.3",
177
- "astro-expressive-code": "^0.31.0",
178
+ "astro-expressive-code": "^0.32.2",
178
179
  "bcp-47": "^2.1.0",
179
180
  "hast-util-select": "^6.0.2",
180
181
  "hastscript": "^8.0.0",
@@ -205,6 +205,9 @@ const UserConfigSchema = z.object({
205
205
  .string()
206
206
  .default('|')
207
207
  .describe('Will be used as title delimiter in the generated `<title>` tag.'),
208
+
209
+ /** Disable Starlight's default 404 page. */
210
+ disable404Route: z.boolean().default(false).describe("Disable Starlight's default 404 page."),
208
211
  });
209
212
 
210
213
  export const StarlightConfigSchema = UserConfigSchema.strict().transform(