@astrojs/starlight 0.23.3 → 0.24.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/404.astro +3 -1
- package/CHANGELOG.md +21 -0
- package/components/Footer.astro +31 -2
- package/components/SidebarSublist.astro +11 -12
- package/components.ts +1 -0
- package/index.ts +12 -3
- package/integrations/shared/localeToLang.ts +2 -1
- package/package.json +1 -1
- package/schemas/badge.ts +9 -0
- package/schemas/i18n.ts +6 -0
- package/translations/ar.json +2 -1
- package/translations/cs.json +2 -1
- package/translations/da.json +2 -1
- package/translations/de.json +2 -1
- package/translations/en.json +2 -1
- package/translations/es.json +2 -1
- package/translations/fa.json +2 -1
- package/translations/fr.json +2 -1
- package/translations/gl.json +2 -1
- package/translations/he.json +2 -1
- package/translations/hi.json +2 -1
- package/translations/id.json +2 -1
- package/translations/it.json +2 -1
- package/translations/ja.json +2 -1
- package/translations/ko.json +2 -1
- package/translations/nb.json +2 -1
- package/translations/nl.json +2 -1
- package/translations/pl.json +2 -1
- package/translations/pt.json +2 -1
- package/translations/ro.json +2 -1
- package/translations/ru.json +2 -1
- package/translations/sv.json +2 -1
- package/translations/tr.json +2 -1
- package/translations/uk.json +2 -1
- package/translations/vi.json +2 -1
- package/translations/zh-CN.json +2 -1
- package/translations/zh-TW.json +2 -1
- package/user-components/Badge.astro +141 -0
- package/user-components/Steps.astro +0 -2
- package/utils/createTranslationSystem.ts +2 -1
- package/utils/i18n.ts +166 -0
- package/utils/routing.ts +2 -1
- package/utils/slugs.ts +2 -1
- package/utils/user-config.ts +14 -3
- package/components/Badge.astro +0 -87
package/404.astro
CHANGED
|
@@ -6,10 +6,12 @@ import Page from './components/Page.astro';
|
|
|
6
6
|
import { generateRouteData } from './utils/route-data';
|
|
7
7
|
import type { StarlightDocsEntry } from './utils/routing';
|
|
8
8
|
import { useTranslations } from './utils/translations';
|
|
9
|
+
import { BuiltInDefaultLocale } from './utils/i18n';
|
|
9
10
|
|
|
10
11
|
export const prerender = true;
|
|
11
12
|
|
|
12
|
-
const { lang =
|
|
13
|
+
const { lang = BuiltInDefaultLocale.lang, dir = BuiltInDefaultLocale.dir } =
|
|
14
|
+
config.defaultLocale || {};
|
|
13
15
|
let locale = config.defaultLocale?.locale;
|
|
14
16
|
if (locale === 'root') locale = undefined;
|
|
15
17
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @astrojs/starlight
|
|
2
2
|
|
|
3
|
+
## 0.24.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#1841](https://github.com/withastro/starlight/pull/1841) [`ee0cd38a`](https://github.com/withastro/starlight/commit/ee0cd38a1fae31717fe820e779baeabe693cd67a) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Adds support for `Astro.currentLocale` and Astro’s i18n routing.
|
|
8
|
+
|
|
9
|
+
⚠️ **Potentially breaking change:** Starlight now configures Astro’s `i18n` option for you based on its `locales` config.
|
|
10
|
+
|
|
11
|
+
If you are currently using Astro’s `i18n` option as well as Starlight’s `locales` option, you will need to remove one of these.
|
|
12
|
+
In general we recommend using Starlight’s `locales`, but if you have a more advanced configuration you may choose to keep Astro’s `i18n` config instead.
|
|
13
|
+
|
|
14
|
+
- [#1958](https://github.com/withastro/starlight/pull/1958) [`081d1a96`](https://github.com/withastro/starlight/commit/081d1a969462633e41ca95a18a1ec121cb4af5d2) Thanks [@delucis](https://github.com/delucis)! - Allows users to opt into displaying a “Built with Starlight” link in the site footer
|
|
15
|
+
|
|
16
|
+
- [#1530](https://github.com/withastro/starlight/pull/1530) [`dd64836a`](https://github.com/withastro/starlight/commit/dd64836af45f33df4a99ab864eabb91fc9b8e204) Thanks [@kevinzunigacuellar](https://github.com/kevinzunigacuellar)! - Adds a new `<Badge>` component
|
|
17
|
+
|
|
18
|
+
## 0.23.4
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- [#1955](https://github.com/withastro/starlight/pull/1955) [`15ef1f4b`](https://github.com/withastro/starlight/commit/15ef1f4bdbf7174134121f4bbdf82ca3903c802a) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Reverts a [change](https://github.com/withastro/starlight/pull/1948) to prevent a numbering issue with the `<Steps>` component in future versions of Chrome.
|
|
23
|
+
|
|
3
24
|
## 0.23.3
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
package/components/Footer.astro
CHANGED
|
@@ -4,26 +4,55 @@ import type { Props } from '../props';
|
|
|
4
4
|
import EditLink from 'virtual:starlight/components/EditLink';
|
|
5
5
|
import LastUpdated from 'virtual:starlight/components/LastUpdated';
|
|
6
6
|
import Pagination from 'virtual:starlight/components/Pagination';
|
|
7
|
+
import config from 'virtual:starlight/user-config';
|
|
8
|
+
import { Icon } from '../components';
|
|
7
9
|
---
|
|
8
10
|
|
|
9
|
-
<footer>
|
|
11
|
+
<footer class="sl-flex">
|
|
10
12
|
<div class="meta sl-flex">
|
|
11
13
|
<EditLink {...Astro.props} />
|
|
12
14
|
<LastUpdated {...Astro.props} />
|
|
13
15
|
</div>
|
|
14
16
|
<Pagination {...Astro.props} />
|
|
17
|
+
|
|
18
|
+
{
|
|
19
|
+
config.credits && (
|
|
20
|
+
<a class="kudos sl-flex" href="https://starlight.astro.build">
|
|
21
|
+
<Icon name={'starlight'} /> {Astro.props.labels['builtWithStarlight.label']}
|
|
22
|
+
</a>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
15
25
|
</footer>
|
|
16
26
|
|
|
17
27
|
<style>
|
|
28
|
+
footer {
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
gap: 1.5rem;
|
|
31
|
+
}
|
|
18
32
|
.meta {
|
|
19
33
|
gap: 0.75rem 3rem;
|
|
20
34
|
justify-content: space-between;
|
|
21
35
|
flex-wrap: wrap;
|
|
22
|
-
margin-
|
|
36
|
+
margin-top: 3rem;
|
|
23
37
|
font-size: var(--sl-text-sm);
|
|
24
38
|
color: var(--sl-color-gray-3);
|
|
25
39
|
}
|
|
26
40
|
.meta > :global(p:only-child) {
|
|
27
41
|
margin-inline-start: auto;
|
|
28
42
|
}
|
|
43
|
+
|
|
44
|
+
.kudos {
|
|
45
|
+
align-items: center;
|
|
46
|
+
gap: 0.5em;
|
|
47
|
+
margin: 1.5rem auto;
|
|
48
|
+
font-size: var(--sl-text-xs);
|
|
49
|
+
text-decoration: none;
|
|
50
|
+
color: var(--sl-color-gray-3);
|
|
51
|
+
}
|
|
52
|
+
.kudos :global(svg) {
|
|
53
|
+
color: var(--sl-color-orange);
|
|
54
|
+
}
|
|
55
|
+
.kudos:hover {
|
|
56
|
+
color: var(--sl-color-white);
|
|
57
|
+
}
|
|
29
58
|
</style>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { flattenSidebar, type SidebarEntry } from '../utils/navigation';
|
|
3
3
|
import Icon from '../user-components/Icon.astro';
|
|
4
|
-
import Badge from '
|
|
4
|
+
import Badge from '../user-components/Badge.astro';
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
7
|
sublist: SidebarEntry[];
|
|
@@ -24,13 +24,11 @@ const { sublist, nested } = Astro.props;
|
|
|
24
24
|
>
|
|
25
25
|
<span>{entry.label}</span>
|
|
26
26
|
{entry.badge && (
|
|
27
|
-
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
/>
|
|
33
|
-
</>
|
|
27
|
+
<Badge
|
|
28
|
+
variant={entry.badge.variant}
|
|
29
|
+
class={entry.badge.class}
|
|
30
|
+
text={entry.badge.text}
|
|
31
|
+
/>
|
|
34
32
|
)}
|
|
35
33
|
</a>
|
|
36
34
|
) : (
|
|
@@ -41,10 +39,11 @@ const { sublist, nested } = Astro.props;
|
|
|
41
39
|
<div class="group-label">
|
|
42
40
|
<span class="large">{entry.label}</span>
|
|
43
41
|
{entry.badge && (
|
|
44
|
-
|
|
45
|
-
{
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
<Badge
|
|
43
|
+
variant={entry.badge.variant}
|
|
44
|
+
class={entry.badge.class}
|
|
45
|
+
text={entry.badge.text}
|
|
46
|
+
/>
|
|
48
47
|
)}
|
|
49
48
|
</div>
|
|
50
49
|
<Icon name="right-caret" class="caret" size="1.25rem" />
|
package/components.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { default as Aside } from './user-components/Aside.astro';
|
|
2
|
+
export { default as Badge } from './user-components/Badge.astro';
|
|
2
3
|
export { default as Card } from './user-components/Card.astro';
|
|
3
4
|
export { default as CardGrid } from './user-components/CardGrid.astro';
|
|
4
5
|
export { default as Icon } from './user-components/Icon.astro';
|
package/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { vitePluginStarlightUserConfig } from './integrations/virtual-user-confi
|
|
|
10
10
|
import { rehypeRtlCodeSupport } from './integrations/code-rtl-support';
|
|
11
11
|
import { createTranslationSystemFromFs } from './utils/translations-fs';
|
|
12
12
|
import { runPlugins, type StarlightUserConfigWithPlugins } from './utils/plugins';
|
|
13
|
+
import { processI18nConfig } from './utils/i18n';
|
|
13
14
|
import type { StarlightConfig } from './types';
|
|
14
15
|
|
|
15
16
|
export default function StarlightIntegration({
|
|
@@ -28,18 +29,25 @@ export default function StarlightIntegration({
|
|
|
28
29
|
logger,
|
|
29
30
|
updateConfig,
|
|
30
31
|
}) => {
|
|
31
|
-
// Run plugins to get the
|
|
32
|
-
const
|
|
32
|
+
// Run plugins to get the updated configuration and any extra Astro integrations to load.
|
|
33
|
+
const pluginResult = await runPlugins(opts, plugins, {
|
|
33
34
|
command,
|
|
34
35
|
config,
|
|
35
36
|
isRestart,
|
|
36
37
|
logger,
|
|
37
38
|
});
|
|
39
|
+
// Process the Astro and Starlight configurations for i18n and translations.
|
|
40
|
+
const { astroI18nConfig, starlightConfig } = processI18nConfig(
|
|
41
|
+
pluginResult.starlightConfig,
|
|
42
|
+
config.i18n
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const { integrations } = pluginResult;
|
|
38
46
|
userConfig = starlightConfig;
|
|
39
47
|
|
|
40
48
|
const useTranslations = createTranslationSystemFromFs(starlightConfig, config);
|
|
41
49
|
|
|
42
|
-
if (!
|
|
50
|
+
if (!starlightConfig.disable404Route) {
|
|
43
51
|
injectRoute({
|
|
44
52
|
pattern: '404',
|
|
45
53
|
entrypoint: '@astrojs/starlight/404.astro',
|
|
@@ -92,6 +100,7 @@ export default function StarlightIntegration({
|
|
|
92
100
|
experimental: {
|
|
93
101
|
globalRoutePriority: true,
|
|
94
102
|
},
|
|
103
|
+
i18n: astroI18nConfig,
|
|
95
104
|
});
|
|
96
105
|
},
|
|
97
106
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { StarlightConfig } from '../../types';
|
|
2
|
+
import { BuiltInDefaultLocale } from '../../utils/i18n';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Get the BCP-47 language tag for the given locale.
|
|
@@ -7,5 +8,5 @@ import type { StarlightConfig } from '../../types';
|
|
|
7
8
|
export function localeToLang(config: StarlightConfig, locale: string | undefined): string {
|
|
8
9
|
const lang = locale ? config.locales?.[locale]?.lang : config.locales?.root?.lang;
|
|
9
10
|
const defaultLang = config.defaultLocale?.lang || config.defaultLocale?.locale;
|
|
10
|
-
return lang || defaultLang ||
|
|
11
|
+
return lang || defaultLang || BuiltInDefaultLocale.lang;
|
|
11
12
|
}
|
package/package.json
CHANGED
package/schemas/badge.ts
CHANGED
|
@@ -4,8 +4,17 @@ const badgeSchema = () =>
|
|
|
4
4
|
z.object({
|
|
5
5
|
variant: z.enum(['note', 'danger', 'success', 'caution', 'tip', 'default']).default('default'),
|
|
6
6
|
text: z.string(),
|
|
7
|
+
class: z.string().optional(),
|
|
7
8
|
});
|
|
8
9
|
|
|
10
|
+
export const BadgeComponentSchema = badgeSchema()
|
|
11
|
+
.extend({
|
|
12
|
+
size: z.enum(['small', 'medium', 'large']).default('small'),
|
|
13
|
+
})
|
|
14
|
+
.passthrough();
|
|
15
|
+
|
|
16
|
+
export type BadgeComponentProps = z.input<typeof BadgeComponentSchema>;
|
|
17
|
+
|
|
9
18
|
export const BadgeConfigSchema = () =>
|
|
10
19
|
z
|
|
11
20
|
.union([z.string(), badgeSchema()])
|
package/schemas/i18n.ts
CHANGED
|
@@ -138,6 +138,12 @@ function starlightI18nSchema() {
|
|
|
138
138
|
'fileTree.directory': z
|
|
139
139
|
.string()
|
|
140
140
|
.describe('Label for the directory icon in the file tree component.'),
|
|
141
|
+
|
|
142
|
+
'builtWithStarlight.label': z
|
|
143
|
+
.string()
|
|
144
|
+
.describe(
|
|
145
|
+
'Label for the “Built with Starlight” badge optionally displayed in the site footer.'
|
|
146
|
+
),
|
|
141
147
|
})
|
|
142
148
|
.partial();
|
|
143
149
|
}
|
package/translations/ar.json
CHANGED
package/translations/cs.json
CHANGED
package/translations/da.json
CHANGED
package/translations/de.json
CHANGED
package/translations/en.json
CHANGED
package/translations/es.json
CHANGED
|
@@ -27,5 +27,6 @@
|
|
|
27
27
|
"expressiveCode.copyButtonCopied": "¡Copiado!",
|
|
28
28
|
"expressiveCode.copyButtonTooltip": "Copiar al portapapeles",
|
|
29
29
|
"expressiveCode.terminalWindowFallbackTitle": "Ventana de terminal",
|
|
30
|
-
"fileTree.directory": "Directory"
|
|
30
|
+
"fileTree.directory": "Directory",
|
|
31
|
+
"builtWithStarlight.label": "Hecho con Starlight"
|
|
31
32
|
}
|
package/translations/fa.json
CHANGED
package/translations/fr.json
CHANGED
|
@@ -27,5 +27,6 @@
|
|
|
27
27
|
"expressiveCode.copyButtonCopied": "Copié !",
|
|
28
28
|
"expressiveCode.copyButtonTooltip": "Copier dans le presse-papiers",
|
|
29
29
|
"expressiveCode.terminalWindowFallbackTitle": "Fenêtre de terminal",
|
|
30
|
-
"fileTree.directory": "Répertoire"
|
|
30
|
+
"fileTree.directory": "Répertoire",
|
|
31
|
+
"builtWithStarlight.label": "Créé avec Starlight"
|
|
31
32
|
}
|
package/translations/gl.json
CHANGED
package/translations/he.json
CHANGED
package/translations/hi.json
CHANGED
package/translations/id.json
CHANGED
package/translations/it.json
CHANGED
package/translations/ja.json
CHANGED
package/translations/ko.json
CHANGED
package/translations/nb.json
CHANGED
package/translations/nl.json
CHANGED
package/translations/pl.json
CHANGED
|
@@ -27,5 +27,6 @@
|
|
|
27
27
|
"fileTree.directory": "Folder",
|
|
28
28
|
"expressiveCode.copyButtonCopied": "Skopiowane!",
|
|
29
29
|
"expressiveCode.copyButtonTooltip": "Skopiuj do schowka",
|
|
30
|
-
"expressiveCode.terminalWindowFallbackTitle": "Okno terminala"
|
|
30
|
+
"expressiveCode.terminalWindowFallbackTitle": "Okno terminala",
|
|
31
|
+
"builtWithStarlight.label": "Built with Starlight"
|
|
31
32
|
}
|
package/translations/pt.json
CHANGED
package/translations/ro.json
CHANGED
package/translations/ru.json
CHANGED
|
@@ -27,5 +27,6 @@
|
|
|
27
27
|
"fileTree.directory": "Директория",
|
|
28
28
|
"expressiveCode.copyButtonCopied": "Скопировано!",
|
|
29
29
|
"expressiveCode.copyButtonTooltip": "Копировать",
|
|
30
|
-
"expressiveCode.terminalWindowFallbackTitle": "Окно терминала"
|
|
30
|
+
"expressiveCode.terminalWindowFallbackTitle": "Окно терминала",
|
|
31
|
+
"builtWithStarlight.label": "Built with Starlight"
|
|
31
32
|
}
|
package/translations/sv.json
CHANGED
package/translations/tr.json
CHANGED
package/translations/uk.json
CHANGED
package/translations/vi.json
CHANGED
package/translations/zh-CN.json
CHANGED
package/translations/zh-TW.json
CHANGED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { BadgeComponentSchema, type BadgeComponentProps } from '../schemas/badge';
|
|
3
|
+
import { parseWithFriendlyErrors } from '../utils/error-map';
|
|
4
|
+
import type { HTMLAttributes } from 'astro/types';
|
|
5
|
+
|
|
6
|
+
type Props = BadgeComponentProps & HTMLAttributes<'span'>;
|
|
7
|
+
|
|
8
|
+
const {
|
|
9
|
+
text,
|
|
10
|
+
variant,
|
|
11
|
+
size,
|
|
12
|
+
class: customClass,
|
|
13
|
+
...attrs
|
|
14
|
+
} = parseWithFriendlyErrors(
|
|
15
|
+
BadgeComponentSchema,
|
|
16
|
+
Astro.props,
|
|
17
|
+
'Invalid prop passed to the `<Badge/>` component.'
|
|
18
|
+
);
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
<span class:list={['sl-badge', variant, size, customClass]} {...attrs}>{text}</span>
|
|
22
|
+
|
|
23
|
+
<style>
|
|
24
|
+
:global(:root) {
|
|
25
|
+
--sl-badge-default-border: var(--sl-color-accent);
|
|
26
|
+
--sl-badge-default-bg: var(--sl-color-accent-low);
|
|
27
|
+
--sl-badge-default-text: #fff;
|
|
28
|
+
|
|
29
|
+
--sl-badge-note-border: var(--sl-color-blue);
|
|
30
|
+
--sl-badge-note-bg: var(--sl-color-blue-low);
|
|
31
|
+
--sl-badge-note-text: #fff;
|
|
32
|
+
|
|
33
|
+
--sl-badge-danger-border: var(--sl-color-red);
|
|
34
|
+
--sl-badge-danger-bg: var(--sl-color-red-low);
|
|
35
|
+
--sl-badge-danger-text: #fff;
|
|
36
|
+
|
|
37
|
+
--sl-badge-success-border: var(--sl-color-green);
|
|
38
|
+
--sl-badge-success-bg: var(--sl-color-green-low);
|
|
39
|
+
--sl-badge-success-text: #fff;
|
|
40
|
+
|
|
41
|
+
--sl-badge-caution-border: var(--sl-color-orange);
|
|
42
|
+
--sl-badge-caution-bg: var(--sl-color-orange-low);
|
|
43
|
+
--sl-badge-caution-text: #fff;
|
|
44
|
+
|
|
45
|
+
--sl-badge-tip-border: var(--sl-color-purple);
|
|
46
|
+
--sl-badge-tip-bg: var(--sl-color-purple-low);
|
|
47
|
+
--sl-badge-tip-text: #fff;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
:global([data-theme='light']:root) {
|
|
51
|
+
--sl-badge-default-bg: var(--sl-color-accent-high);
|
|
52
|
+
--sl-badge-note-bg: var(--sl-color-blue-high);
|
|
53
|
+
--sl-badge-danger-bg: var(--sl-color-red-high);
|
|
54
|
+
--sl-badge-success-bg: var(--sl-color-green-high);
|
|
55
|
+
--sl-badge-caution-bg: var(--sl-color-orange-high);
|
|
56
|
+
--sl-badge-tip-bg: var(--sl-color-purple-high);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.sl-badge {
|
|
60
|
+
display: inline-block;
|
|
61
|
+
border: 1px solid var(--sl-color-border-badge);
|
|
62
|
+
border-radius: 0.25rem;
|
|
63
|
+
font-family: var(--sl-font-system-mono);
|
|
64
|
+
line-height: normal;
|
|
65
|
+
color: var(--sl-color-text-badge);
|
|
66
|
+
background-color: var(--sl-color-bg-badge);
|
|
67
|
+
overflow-wrap: anywhere;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* Sidebar overrides */
|
|
71
|
+
:global(.sidebar-content) .sl-badge {
|
|
72
|
+
line-height: 1;
|
|
73
|
+
font-size: var(--sl-text-xs);
|
|
74
|
+
padding: 0.125rem 0.375rem;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* outline variant */
|
|
78
|
+
:global(.sidebar-content a[aria-current='page']) > .sl-badge {
|
|
79
|
+
--sl-color-bg-badge: transparent;
|
|
80
|
+
--sl-color-border-badge: currentColor;
|
|
81
|
+
color: inherit;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Color variants */
|
|
85
|
+
.default {
|
|
86
|
+
--sl-color-bg-badge: var(--sl-badge-default-bg);
|
|
87
|
+
--sl-color-border-badge: var(--sl-badge-default-border);
|
|
88
|
+
--sl-color-text-badge: var(--sl-badge-default-text);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.note {
|
|
92
|
+
--sl-color-bg-badge: var(--sl-badge-note-bg);
|
|
93
|
+
--sl-color-border-badge: var(--sl-badge-note-border);
|
|
94
|
+
--sl-color-text-badge: var(--sl-badge-note-text);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.danger {
|
|
98
|
+
--sl-color-bg-badge: var(--sl-badge-danger-bg);
|
|
99
|
+
--sl-color-border-badge: var(--sl-badge-danger-border);
|
|
100
|
+
--sl-color-text-badge: var(--sl-badge-danger-text);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.success {
|
|
104
|
+
--sl-color-bg-badge: var(--sl-badge-success-bg);
|
|
105
|
+
--sl-color-border-badge: var(--sl-badge-success-border);
|
|
106
|
+
--sl-color-text-badge: var(--sl-badge-success-text);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.tip {
|
|
110
|
+
--sl-color-bg-badge: var(--sl-badge-tip-bg);
|
|
111
|
+
--sl-color-border-badge: var(--sl-badge-tip-border);
|
|
112
|
+
--sl-color-text-badge: var(--sl-badge-tip-text);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.caution {
|
|
116
|
+
--sl-color-bg-badge: var(--sl-badge-caution-bg);
|
|
117
|
+
--sl-color-border-badge: var(--sl-badge-caution-border);
|
|
118
|
+
--sl-color-text-badge: var(--sl-badge-caution-text);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* Size variants */
|
|
122
|
+
.small {
|
|
123
|
+
font-size: var(--sl-text-xs);
|
|
124
|
+
padding: 0.125rem 0.25rem;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.medium {
|
|
128
|
+
font-size: var(--sl-text-sm);
|
|
129
|
+
padding: 0.175rem 0.35rem;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.large {
|
|
133
|
+
font-size: var(--sl-text-base);
|
|
134
|
+
padding: 0.225rem 0.45rem;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* Badge in headings */
|
|
138
|
+
:global(.sl-markdown-content :is(h1, h2, h3, h4, h5, h6)) .sl-badge {
|
|
139
|
+
vertical-align: middle;
|
|
140
|
+
}
|
|
141
|
+
</style>
|
|
@@ -23,8 +23,6 @@ const { html } = processSteps(content);
|
|
|
23
23
|
padding-bottom: 1px;
|
|
24
24
|
/* Prevent bullets from touching in short list items. */
|
|
25
25
|
min-height: calc(var(--bullet-size) + var(--bullet-margin));
|
|
26
|
-
/* Enforce style containment so that nested lists CSS counters are scoped to the contained element. */
|
|
27
|
-
contain: style;
|
|
28
26
|
}
|
|
29
27
|
.sl-steps > li + li {
|
|
30
28
|
/* Remove margin between steps. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { i18nSchemaOutput } from '../schemas/i18n';
|
|
2
2
|
import builtinTranslations from '../translations/index';
|
|
3
|
+
import { BuiltInDefaultLocale } from './i18n';
|
|
3
4
|
import type { StarlightConfig } from './user-config';
|
|
4
5
|
|
|
5
6
|
export function createTranslationSystem<T extends i18nSchemaOutput>(
|
|
@@ -64,7 +65,7 @@ function localeToLang(
|
|
|
64
65
|
): string {
|
|
65
66
|
const lang = locale ? locales?.[locale]?.lang : locales?.root?.lang;
|
|
66
67
|
const defaultLang = defaultLocale?.lang || defaultLocale?.locale;
|
|
67
|
-
return lang || defaultLang ||
|
|
68
|
+
return lang || defaultLang || BuiltInDefaultLocale.lang;
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
type BuiltInStrings = (typeof builtinTranslations)['en'];
|
package/utils/i18n.ts
CHANGED
|
@@ -1,3 +1,166 @@
|
|
|
1
|
+
import type { AstroConfig } from 'astro';
|
|
2
|
+
import { AstroError } from 'astro/errors';
|
|
3
|
+
import type { StarlightConfig } from './user-config';
|
|
4
|
+
|
|
5
|
+
/** Informations about the built-in default locale used as a fallback when no locales are defined. */
|
|
6
|
+
export const BuiltInDefaultLocale = { ...getLocaleInfo('en'), lang: 'en' };
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Processes the Astro and Starlight i18n configurations to generate/update them accordingly:
|
|
10
|
+
*
|
|
11
|
+
* - If no Astro and Starlight i18n configurations are provided, the built-in default locale is
|
|
12
|
+
* used in Starlight and the generated Astro i18n configuration will match it.
|
|
13
|
+
* - If only a Starlight i18n configuration is provided, an equivalent Astro i18n configuration is
|
|
14
|
+
* generated.
|
|
15
|
+
* - If only an Astro i18n configuration is provided, an equivalent Starlight i18n configuration is
|
|
16
|
+
* used.
|
|
17
|
+
* - If both an Astro and Starlight i18n configurations are provided, an error is thrown.
|
|
18
|
+
*/
|
|
19
|
+
export function processI18nConfig(
|
|
20
|
+
starlightConfig: StarlightConfig,
|
|
21
|
+
astroI18nConfig: AstroConfig['i18n']
|
|
22
|
+
) {
|
|
23
|
+
// We don't know what to do if both an Astro and Starlight i18n configuration are provided.
|
|
24
|
+
if (astroI18nConfig && !starlightConfig.isUsingBuiltInDefaultLocale) {
|
|
25
|
+
throw new AstroError(
|
|
26
|
+
'Cannot provide both an Astro `i18n` configuration and a Starlight `locales` configuration.',
|
|
27
|
+
'Remove one of the two configurations.\nSee more at https://starlight.astro.build/guides/i18n/'
|
|
28
|
+
);
|
|
29
|
+
} else if (astroI18nConfig) {
|
|
30
|
+
// If a Starlight compatible Astro i18n configuration is provided, we generate the matching
|
|
31
|
+
// Starlight configuration.
|
|
32
|
+
return {
|
|
33
|
+
astroI18nConfig,
|
|
34
|
+
starlightConfig: {
|
|
35
|
+
...starlightConfig,
|
|
36
|
+
...getStarlightI18nConfig(astroI18nConfig),
|
|
37
|
+
} as StarlightConfig,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// Otherwise, we generate the Astro i18n configuration based on the Starlight configuration.
|
|
41
|
+
return { astroI18nConfig: getAstroI18nConfig(starlightConfig), starlightConfig: starlightConfig };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Generate an Astro i18n configuration based on a Starlight configuration. */
|
|
45
|
+
function getAstroI18nConfig(config: StarlightConfig): NonNullable<AstroConfig['i18n']> {
|
|
46
|
+
return {
|
|
47
|
+
defaultLocale:
|
|
48
|
+
config.defaultLocale.lang ?? config.defaultLocale.locale ?? BuiltInDefaultLocale.lang,
|
|
49
|
+
locales: config.locales
|
|
50
|
+
? Object.entries(config.locales).map(([locale, localeConfig]) => {
|
|
51
|
+
return {
|
|
52
|
+
codes: [localeConfig?.lang ?? locale],
|
|
53
|
+
path: locale === 'root' ? localeConfig?.lang ?? BuiltInDefaultLocale.lang : locale,
|
|
54
|
+
};
|
|
55
|
+
})
|
|
56
|
+
: [BuiltInDefaultLocale.lang],
|
|
57
|
+
routing: {
|
|
58
|
+
prefixDefaultLocale:
|
|
59
|
+
// Sites with multiple languages without a root locale.
|
|
60
|
+
(config.isMultilingual && config.locales?.root === undefined) ||
|
|
61
|
+
// Sites with a single non-root language different from the built-in default locale.
|
|
62
|
+
(!config.isMultilingual && config.locales !== undefined),
|
|
63
|
+
redirectToDefaultLocale: false,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Generate a Starlight i18n configuration based on an Astro configuration. */
|
|
69
|
+
function getStarlightI18nConfig(
|
|
70
|
+
astroI18nConfig: NonNullable<AstroConfig['i18n']>
|
|
71
|
+
): Pick<StarlightConfig, 'isMultilingual' | 'locales' | 'defaultLocale'> {
|
|
72
|
+
if (astroI18nConfig.routing === 'manual') {
|
|
73
|
+
throw new AstroError(
|
|
74
|
+
'Starlight is not compatible with the `manual` routing option in the Astro i18n configuration.'
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const prefixDefaultLocale = astroI18nConfig.routing.prefixDefaultLocale;
|
|
79
|
+
const isMultilingual = astroI18nConfig.locales.length > 1;
|
|
80
|
+
const isMonolingualWithRootLocale = !isMultilingual && !prefixDefaultLocale;
|
|
81
|
+
|
|
82
|
+
const locales = isMonolingualWithRootLocale
|
|
83
|
+
? undefined
|
|
84
|
+
: Object.fromEntries(
|
|
85
|
+
astroI18nConfig.locales.map((locale) => [
|
|
86
|
+
isDefaultAstroLocale(astroI18nConfig, locale) && !prefixDefaultLocale
|
|
87
|
+
? 'root'
|
|
88
|
+
: isAstroLocaleExtendedConfig(locale)
|
|
89
|
+
? locale.path
|
|
90
|
+
: locale,
|
|
91
|
+
inferStarlightLocaleFromAstroLocale(locale),
|
|
92
|
+
])
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const defaultAstroLocale = astroI18nConfig.locales.find((locale) =>
|
|
96
|
+
isDefaultAstroLocale(astroI18nConfig, locale)
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// This should never happen as Astro validation should prevent this case.
|
|
100
|
+
if (!defaultAstroLocale) {
|
|
101
|
+
throw new AstroError(
|
|
102
|
+
'Astro default locale not found.',
|
|
103
|
+
'This should never happen. Please open a new issue: https://github.com/withastro/starlight/issues/new?template=---01-bug-report.yml'
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
isMultilingual,
|
|
109
|
+
locales,
|
|
110
|
+
defaultLocale: {
|
|
111
|
+
...inferStarlightLocaleFromAstroLocale(defaultAstroLocale),
|
|
112
|
+
locale: isMonolingualWithRootLocale
|
|
113
|
+
? undefined
|
|
114
|
+
: isAstroLocaleExtendedConfig(defaultAstroLocale)
|
|
115
|
+
? defaultAstroLocale.codes[0]
|
|
116
|
+
: defaultAstroLocale,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Infer Starlight locale informations based on a locale from an Astro i18n configuration. */
|
|
122
|
+
function inferStarlightLocaleFromAstroLocale(astroLocale: AstroLocale) {
|
|
123
|
+
const lang = isAstroLocaleExtendedConfig(astroLocale) ? astroLocale.codes[0] : astroLocale;
|
|
124
|
+
return { ...getLocaleInfo(lang), lang };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Check if the passed locale is the default locale in an Astro i18n configuration. */
|
|
128
|
+
function isDefaultAstroLocale(
|
|
129
|
+
astroI18nConfig: NonNullable<AstroConfig['i18n']>,
|
|
130
|
+
locale: AstroLocale
|
|
131
|
+
) {
|
|
132
|
+
return (
|
|
133
|
+
(isAstroLocaleExtendedConfig(locale) ? locale.path : locale) === astroI18nConfig.defaultLocale
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Check if the passed Astro locale is using the object variant.
|
|
139
|
+
* @see AstroLocaleExtendedConfig
|
|
140
|
+
*/
|
|
141
|
+
function isAstroLocaleExtendedConfig(locale: AstroLocale): locale is AstroLocaleExtendedConfig {
|
|
142
|
+
return typeof locale !== 'string';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Returns the locale informations such as a label and a direction based on a BCP-47 tag. */
|
|
146
|
+
function getLocaleInfo(lang: string) {
|
|
147
|
+
try {
|
|
148
|
+
const locale = new Intl.Locale(lang);
|
|
149
|
+
const label = new Intl.DisplayNames(locale, { type: 'language' }).of(lang);
|
|
150
|
+
if (!label || lang === label) throw new Error('Label not found.');
|
|
151
|
+
return {
|
|
152
|
+
label: label[0]?.toLocaleUpperCase(locale) + label.slice(1),
|
|
153
|
+
// @ts-expect-error - `textInfo` is not part of the `Intl.Locale` type but is available in Node.js 18.0.0+.
|
|
154
|
+
dir: locale.textInfo.direction as 'ltr' | 'rtl',
|
|
155
|
+
};
|
|
156
|
+
} catch (error) {
|
|
157
|
+
throw new AstroError(
|
|
158
|
+
`Failed to get locale informations for the '${lang}' locale.`,
|
|
159
|
+
'Make sure to provide a valid BCP-47 tags (e.g. en, ar, or zh-CN).'
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
1
164
|
/**
|
|
2
165
|
* Get the string for the passed language from a dictionary object.
|
|
3
166
|
*
|
|
@@ -14,3 +177,6 @@ export function pickLang<T extends Record<string, string>>(
|
|
|
14
177
|
): string | undefined {
|
|
15
178
|
return dictionary[lang];
|
|
16
179
|
}
|
|
180
|
+
|
|
181
|
+
type AstroLocale = NonNullable<AstroConfig['i18n']>['locales'][number];
|
|
182
|
+
type AstroLocaleExtendedConfig = Exclude<AstroLocale, string>;
|
package/utils/routing.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
slugToParam,
|
|
10
10
|
} from './slugs';
|
|
11
11
|
import { validateLogoImports } from './validateLogoImports';
|
|
12
|
+
import { BuiltInDefaultLocale } from './i18n';
|
|
12
13
|
|
|
13
14
|
// Validate any user-provided logos imported correctly.
|
|
14
15
|
// We do this here so all pages trigger it and at the top level so it runs just once.
|
|
@@ -86,7 +87,7 @@ function getRoutes(): Route[] {
|
|
|
86
87
|
slug,
|
|
87
88
|
id,
|
|
88
89
|
isFallback: true,
|
|
89
|
-
lang: localeConfig.lang ||
|
|
90
|
+
lang: localeConfig.lang || BuiltInDefaultLocale.lang,
|
|
90
91
|
locale,
|
|
91
92
|
dir: localeConfig.dir,
|
|
92
93
|
entryMeta: slugToLocaleData(fallback.slug),
|
package/utils/slugs.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import config from 'virtual:starlight/user-config';
|
|
2
|
+
import { BuiltInDefaultLocale } from './i18n';
|
|
2
3
|
|
|
3
4
|
export interface LocaleData {
|
|
4
5
|
/** Writing direction. */
|
|
@@ -35,7 +36,7 @@ export function slugToLocaleData(slug: string): LocaleData {
|
|
|
35
36
|
export function localeToLang(locale: string | undefined): string {
|
|
36
37
|
const lang = locale ? config.locales?.[locale]?.lang : config.locales?.root?.lang;
|
|
37
38
|
const defaultLang = config.defaultLocale?.lang || config.defaultLocale?.locale;
|
|
38
|
-
return lang || defaultLang ||
|
|
39
|
+
return lang || defaultLang || BuiltInDefaultLocale.lang;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
/**
|
package/utils/user-config.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { SidebarItemSchema } from '../schemas/sidebar';
|
|
|
9
9
|
import { SocialLinksSchema } from '../schemas/social';
|
|
10
10
|
import { TableOfContentsSchema } from '../schemas/tableOfContents';
|
|
11
11
|
import { TitleConfigSchema, TitleTransformConfigSchema } from '../schemas/site-title';
|
|
12
|
+
import { BuiltInDefaultLocale } from './i18n';
|
|
12
13
|
|
|
13
14
|
const LocaleSchema = z.object({
|
|
14
15
|
/** The label for this language to show in UI, e.g. `"English"`, `"العربية"`, or `"简体中文"`. */
|
|
@@ -207,6 +208,12 @@ const UserConfigSchema = z.object({
|
|
|
207
208
|
|
|
208
209
|
/** Disable Starlight's default 404 page. */
|
|
209
210
|
disable404Route: z.boolean().default(false).describe("Disable Starlight's default 404 page."),
|
|
211
|
+
|
|
212
|
+
/** Enable displaying a “Built with Starlight” link in your site’s footer. */
|
|
213
|
+
credits: z
|
|
214
|
+
.boolean()
|
|
215
|
+
.default(false)
|
|
216
|
+
.describe('Enable displaying a “Built with Starlight” link in your site’s footer.'),
|
|
210
217
|
});
|
|
211
218
|
|
|
212
219
|
export const StarlightConfigSchema = UserConfigSchema.strict().transform(
|
|
@@ -244,6 +251,8 @@ export const StarlightConfigSchema = UserConfigSchema.strict().transform(
|
|
|
244
251
|
title: parsedTitle,
|
|
245
252
|
/** Flag indicating if this site has multiple locales set up. */
|
|
246
253
|
isMultilingual: configuredLocales.length > 1,
|
|
254
|
+
/** Flag indicating if the Starlight built-in default locale is used. */
|
|
255
|
+
isUsingBuiltInDefaultLocale: false,
|
|
247
256
|
/** Full locale object for this site’s default language. */
|
|
248
257
|
defaultLocale: { ...defaultLocaleConfig, locale: defaultLocale },
|
|
249
258
|
locales,
|
|
@@ -254,9 +263,9 @@ export const StarlightConfigSchema = UserConfigSchema.strict().transform(
|
|
|
254
263
|
// pretty simple.
|
|
255
264
|
/** Full locale object for this site’s default language. */
|
|
256
265
|
const defaultLocaleConfig = {
|
|
257
|
-
label:
|
|
258
|
-
lang:
|
|
259
|
-
dir:
|
|
266
|
+
label: BuiltInDefaultLocale.label,
|
|
267
|
+
lang: BuiltInDefaultLocale.lang,
|
|
268
|
+
dir: BuiltInDefaultLocale.dir,
|
|
260
269
|
locale: undefined,
|
|
261
270
|
...locales?.root,
|
|
262
271
|
};
|
|
@@ -268,6 +277,8 @@ export const StarlightConfigSchema = UserConfigSchema.strict().transform(
|
|
|
268
277
|
title: parsedTitle,
|
|
269
278
|
/** Flag indicating if this site has multiple locales set up. */
|
|
270
279
|
isMultilingual: false,
|
|
280
|
+
/** Flag indicating if the Starlight built-in default locale is used. */
|
|
281
|
+
isUsingBuiltInDefaultLocale: locales?.root === undefined,
|
|
271
282
|
defaultLocale: defaultLocaleConfig,
|
|
272
283
|
locales: undefined,
|
|
273
284
|
} as const;
|
package/components/Badge.astro
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { Badge } from '../schemas/badge';
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
5
|
-
variant?: Badge['variant'] | 'outline';
|
|
6
|
-
text?: string;
|
|
7
|
-
}
|
|
8
|
-
const { variant = 'default', text } = Astro.props;
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
<span class:list={['sl-badge', variant]} set:html={text} />
|
|
12
|
-
|
|
13
|
-
<style>
|
|
14
|
-
.sl-badge {
|
|
15
|
-
display: inline-block;
|
|
16
|
-
border: 1px solid var(--sl-color-border-badge);
|
|
17
|
-
border-radius: 0.25rem;
|
|
18
|
-
font-family: var(--sl-font-system-mono);
|
|
19
|
-
font-size: var(--sl-text-xs);
|
|
20
|
-
font-weight: 400;
|
|
21
|
-
padding: 0.125rem 0.375rem;
|
|
22
|
-
line-height: 1;
|
|
23
|
-
color: #fff;
|
|
24
|
-
background-color: var(--sl-color-bg-badge);
|
|
25
|
-
overflow-wrap: anywhere;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.outline {
|
|
29
|
-
--sl-color-bg-badge: transparent;
|
|
30
|
-
--sl-color-border-badge: currentColor;
|
|
31
|
-
color: inherit;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.default {
|
|
35
|
-
--sl-color-bg-badge: var(--sl-color-accent-low);
|
|
36
|
-
--sl-color-border-badge: var(--sl-color-accent);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.note {
|
|
40
|
-
--sl-color-bg-badge: var(--sl-color-blue-low);
|
|
41
|
-
--sl-color-border-badge: var(--sl-color-blue);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.danger {
|
|
45
|
-
--sl-color-bg-badge: var(--sl-color-red-low);
|
|
46
|
-
--sl-color-border-badge: var(--sl-color-red);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.success {
|
|
50
|
-
--sl-color-bg-badge: var(--sl-color-green-low);
|
|
51
|
-
--sl-color-border-badge: var(--sl-color-green);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.caution {
|
|
55
|
-
--sl-color-bg-badge: var(--sl-color-orange-low);
|
|
56
|
-
--sl-color-border-badge: var(--sl-color-orange);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.tip {
|
|
60
|
-
--sl-color-bg-badge: var(--sl-color-purple-low);
|
|
61
|
-
--sl-color-border-badge: var(--sl-color-purple);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
:global([data-theme='light']) .default {
|
|
65
|
-
--sl-color-bg-badge: var(--sl-color-accent-high);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
:global([data-theme='light']) .note {
|
|
69
|
-
--sl-color-bg-badge: var(--sl-color-blue-high);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
:global([data-theme='light']) .danger {
|
|
73
|
-
--sl-color-bg-badge: var(--sl-color-red-high);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
:global([data-theme='light']) .success {
|
|
77
|
-
--sl-color-bg-badge: var(--sl-color-green-high);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
:global([data-theme='light']) .caution {
|
|
81
|
-
--sl-color-bg-badge: var(--sl-color-orange-high);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
:global([data-theme='light']) .tip {
|
|
85
|
-
--sl-color-bg-badge: var(--sl-color-purple-high);
|
|
86
|
-
}
|
|
87
|
-
</style>
|