@astrojs/starlight 0.16.0 → 0.17.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.
- package/CHANGELOG.md +20 -0
- package/components/Search.astro +17 -1
- package/components.ts +1 -0
- package/index.ts +7 -7
- package/integrations/expressive-code/exports.ts +34 -0
- package/integrations/expressive-code/index.ts +77 -43
- package/integrations/expressive-code/theming.ts +4 -8
- package/integrations/shared/pathToLocale.ts +8 -6
- package/internal.ts +1 -0
- package/package.json +3 -2
- package/style/props.css +2 -2
- package/utils/user-config.ts +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @astrojs/starlight
|
|
2
2
|
|
|
3
|
+
## 0.17.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1437](https://github.com/withastro/starlight/pull/1437) [`655aed4`](https://github.com/withastro/starlight/commit/655aed4840cae59e9abd64b4b585e60f1cfab209) Thanks [@hippotastic](https://github.com/hippotastic)! - Adds Starlight-specific types to `defineEcConfig` function and exports `StarlightExpressiveCodeOptions`.
|
|
8
|
+
|
|
9
|
+
This provides Starlight types and IntelliSense support for your Expressive Code configuration options inside an `ec.config.mjs` file. See the [Expressive Code documentation](https://expressive-code.com/key-features/code-component/#using-an-ecconfigmjs-file) for more information.
|
|
10
|
+
|
|
11
|
+
- [#1420](https://github.com/withastro/starlight/pull/1420) [`275f87f`](https://github.com/withastro/starlight/commit/275f87fd7fc676b9ab323354078c06894e0832c7) Thanks [@abdelhalimjean](https://github.com/abdelhalimjean)! - Fix rare `font-family` issue if users have a font installed with a name of `""`
|
|
12
|
+
|
|
13
|
+
- [#1365](https://github.com/withastro/starlight/pull/1365) [`a0af7cc`](https://github.com/withastro/starlight/commit/a0af7cc696da987a76edab96cdd2329779e87724) Thanks [@kevinzunigacuellar](https://github.com/kevinzunigacuellar)! - Correctly format Pagefind search result links when `trailingSlash: 'never'` is used
|
|
14
|
+
|
|
15
|
+
## 0.17.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- [#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
|
|
20
|
+
|
|
21
|
+
- [#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
|
|
22
|
+
|
|
3
23
|
## 0.16.0
|
|
4
24
|
|
|
5
25
|
### Minor Changes
|
package/components/Search.astro
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import '@pagefind/default-ui/css/ui.css';
|
|
3
3
|
import Icon from '../user-components/Icon.astro';
|
|
4
|
+
import project from 'virtual:starlight/project-context';
|
|
4
5
|
import type { Props } from '../props';
|
|
5
6
|
|
|
6
7
|
const { labels } = Astro.props;
|
|
@@ -15,7 +16,10 @@ const pagefindTranslations = {
|
|
|
15
16
|
};
|
|
16
17
|
---
|
|
17
18
|
|
|
18
|
-
<site-search
|
|
19
|
+
<site-search
|
|
20
|
+
data-translations={JSON.stringify(pagefindTranslations)}
|
|
21
|
+
data-strip-trailing-slash={project.trailingSlash === 'never'}
|
|
22
|
+
>
|
|
19
23
|
<button data-open-modal disabled>
|
|
20
24
|
{
|
|
21
25
|
/* The span is `aria-hidden` because it is not shown on small screens. Instead, the icon label is used for accessibility purposes. */
|
|
@@ -112,10 +116,15 @@ const pagefindTranslations = {
|
|
|
112
116
|
translations = JSON.parse(this.dataset.translations || '{}');
|
|
113
117
|
} catch {}
|
|
114
118
|
|
|
119
|
+
const shouldStrip = this.dataset.stripTrailingSlash !== undefined;
|
|
120
|
+
const stripTrailingSlash = (path: string) => path.replace(/(.)\/(#.*)?$/, '$1$2');
|
|
121
|
+
const formatURL = shouldStrip ? stripTrailingSlash : (path: string) => path;
|
|
122
|
+
|
|
115
123
|
window.addEventListener('DOMContentLoaded', () => {
|
|
116
124
|
if (import.meta.env.DEV) return;
|
|
117
125
|
const onIdle = window.requestIdleCallback || ((cb) => setTimeout(cb, 1));
|
|
118
126
|
onIdle(async () => {
|
|
127
|
+
// @ts-expect-error — Missing types for @pagefind/default-ui package.
|
|
119
128
|
const { PagefindUI } = await import('@pagefind/default-ui');
|
|
120
129
|
new PagefindUI({
|
|
121
130
|
element: '#starlight__search',
|
|
@@ -124,6 +133,13 @@ const pagefindTranslations = {
|
|
|
124
133
|
showImages: false,
|
|
125
134
|
translations,
|
|
126
135
|
showSubResults: true,
|
|
136
|
+
processResult: (result: { url: string; sub_results: Array<{ url: string }> }) => {
|
|
137
|
+
result.url = formatURL(result.url);
|
|
138
|
+
result.sub_results = result.sub_results.map((sub_result) => {
|
|
139
|
+
sub_result.url = formatURL(sub_result.url);
|
|
140
|
+
return sub_result;
|
|
141
|
+
});
|
|
142
|
+
},
|
|
127
143
|
});
|
|
128
144
|
});
|
|
129
145
|
});
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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,37 @@
|
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
36
|
export * from 'astro-expressive-code';
|
|
37
|
+
|
|
38
|
+
import type { StarlightExpressiveCodeOptions } from './index';
|
|
39
|
+
|
|
40
|
+
export type { StarlightExpressiveCodeOptions };
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A utility function that helps you define an Expressive Code configuration object. It is meant
|
|
44
|
+
* to be used inside the optional config file `ec.config.mjs` located in the root directory
|
|
45
|
+
* of your Starlight project, and its return value to be exported as the default export.
|
|
46
|
+
*
|
|
47
|
+
* Expressive Code will automatically detect this file and use the exported configuration object
|
|
48
|
+
* to override its own default settings.
|
|
49
|
+
*
|
|
50
|
+
* Using this function is recommended, but not required. It just passes through the given object,
|
|
51
|
+
* but it also provides type information for your editor's auto-completion and type checking.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```js
|
|
55
|
+
* // ec.config.mjs
|
|
56
|
+
* import { defineEcConfig } from '@astrojs/starlight/expressive-code'
|
|
57
|
+
*
|
|
58
|
+
* export default defineEcConfig({
|
|
59
|
+
* themes: ['starlight-dark', 'github-light'],
|
|
60
|
+
* styleOverrides: {
|
|
61
|
+
* borderRadius: '0.5rem',
|
|
62
|
+
* },
|
|
63
|
+
* })
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export function defineEcConfig(config: StarlightExpressiveCodeOptions) {
|
|
67
|
+
return config;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
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 {
|
|
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
|
-
|
|
64
|
-
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
|
|
109
|
-
|
|
113
|
+
// Add Expressive Code UI translations (if any) for all defined locales
|
|
114
|
+
if (useTranslations) addTranslations(locales, useTranslations);
|
|
110
115
|
|
|
111
|
-
|
|
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
|
|
24
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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.
|
|
3
|
+
"version": "0.17.1",
|
|
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.
|
|
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",
|
package/style/props.css
CHANGED
|
@@ -87,8 +87,8 @@
|
|
|
87
87
|
'Segoe UI Symbol', 'Noto Color Emoji';
|
|
88
88
|
--sl-font-system-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
|
|
89
89
|
'Courier New', monospace;
|
|
90
|
-
--__sl-font: var(--sl-font,
|
|
91
|
-
--__sl-font-mono: var(--sl-font-mono,
|
|
90
|
+
--__sl-font: var(--sl-font, var(--sl-font-system)), var(--sl-font-system);
|
|
91
|
+
--__sl-font-mono: var(--sl-font-mono, var(--sl-font-system-mono)), var(--sl-font-system-mono);
|
|
92
92
|
|
|
93
93
|
/** Key layout values */
|
|
94
94
|
--sl-nav-height: 3.5rem;
|
package/utils/user-config.ts
CHANGED
|
@@ -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(
|