@astrojs/starlight 0.1.4 → 0.3.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 +32 -51
- package/CHANGELOG.md +45 -0
- package/components/EmptyMarkdown.md +0 -0
- package/components/HeadSEO.astro +5 -0
- package/components/Hero.astro +1 -1
- package/components/Search.astro +34 -18
- package/components/SidebarSublist.astro +20 -9
- package/components/SkipLink.astro +1 -1
- package/components/TableOfContents/generateToC.ts +1 -1
- package/components/TableOfContents/starlight-toc.ts +2 -2
- package/index.astro +3 -109
- package/layout/Page.astro +116 -0
- package/package.json +4 -4
- package/schemas/i18n.ts +82 -0
- package/style/props.css +2 -0
- package/translations/README.md +14 -0
- package/translations/de.json +3 -1
- package/translations/en.json +3 -1
- package/translations/es.json +3 -1
- package/translations/fr.json +3 -1
- package/translations/index.ts +2 -2
- package/translations/it.json +3 -1
- package/translations/ja.json +3 -1
- package/translations/pt.json +3 -1
- package/utils/navigation.ts +16 -11
- package/utils/translations.ts +6 -1
- package/utils/user-config.ts +1 -9
package/404.astro
CHANGED
|
@@ -1,58 +1,39 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { getEntry } from 'astro:content';
|
|
2
3
|
import config from 'virtual:starlight/user-config';
|
|
3
|
-
import
|
|
4
|
+
import EmptyContent from './components/EmptyMarkdown.md';
|
|
5
|
+
import Page from './layout/Page.astro';
|
|
6
|
+
import type { StarlightDocsEntry } from './utils/routing';
|
|
7
|
+
import { useTranslations } from './utils/translations';
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import './style/shiki.css';
|
|
9
|
-
import './style/util.css';
|
|
10
|
-
|
|
11
|
-
// Layout
|
|
12
|
-
import PageFrame from './layout/PageFrame.astro';
|
|
13
|
-
|
|
14
|
-
// Components
|
|
15
|
-
import Header from './components/Header.astro';
|
|
16
|
-
import MarkdownContent from './components/MarkdownContent.astro';
|
|
17
|
-
import ThemeProvider from './components/ThemeProvider.astro';
|
|
18
|
-
import SkipLink from './components/SkipLink.astro';
|
|
9
|
+
const { lang = 'en', dir = 'ltr', locale } = config.defaultLocale || {};
|
|
10
|
+
const entryMeta = { dir, lang, locale };
|
|
11
|
+
const t = useTranslations(locale);
|
|
19
12
|
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
const fallbackEntry: StarlightDocsEntry = {
|
|
14
|
+
slug: '404',
|
|
15
|
+
id: '404.md' as StarlightDocsEntry['id'],
|
|
16
|
+
body: '',
|
|
17
|
+
collection: 'docs',
|
|
18
|
+
data: {
|
|
19
|
+
title: '404',
|
|
20
|
+
template: 'splash',
|
|
21
|
+
editUrl: false,
|
|
22
|
+
head: [],
|
|
23
|
+
hero: { tagline: t('404.text'), actions: [] },
|
|
24
|
+
},
|
|
25
|
+
render: async () => ({
|
|
26
|
+
Content: EmptyContent,
|
|
27
|
+
headings: [],
|
|
28
|
+
remarkPluginFrontmatter: {},
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
22
31
|
|
|
23
|
-
const
|
|
32
|
+
const userEntry = await getEntry('docs', '404');
|
|
33
|
+
const entry = userEntry || fallbackEntry;
|
|
34
|
+
const { Content, headings } = await entry.render();
|
|
24
35
|
---
|
|
25
36
|
|
|
26
|
-
<
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
<meta name="viewport" content="width=device-width" />
|
|
30
|
-
<title>Not found</title>
|
|
31
|
-
</head>
|
|
32
|
-
<body>
|
|
33
|
-
<ThemeProvider />
|
|
34
|
-
<SkipLink {locale} />
|
|
35
|
-
<PageFrame {locale} hasSidebar={false}>
|
|
36
|
-
<Header slot="header" {locale} />
|
|
37
|
-
<main>
|
|
38
|
-
<MarkdownContent>
|
|
39
|
-
<h1 id="starlight__overview">404</h1>
|
|
40
|
-
<p>Houston, we have a problem.</p>
|
|
41
|
-
<p>
|
|
42
|
-
We couldn’t find that link. Check the address or
|
|
43
|
-
<a href={pathWithBase('/')}>head back home</a>.
|
|
44
|
-
</p>
|
|
45
|
-
</MarkdownContent>
|
|
46
|
-
</main>
|
|
47
|
-
</PageFrame>
|
|
48
|
-
|
|
49
|
-
<style>
|
|
50
|
-
main {
|
|
51
|
-
margin: auto;
|
|
52
|
-
padding: clamp(2rem, 10vmin, 6rem) var(--sl-nav-pad-x);
|
|
53
|
-
max-width: var(--sl-content-width);
|
|
54
|
-
max-width: max-content;
|
|
55
|
-
}
|
|
56
|
-
</style>
|
|
57
|
-
</body>
|
|
58
|
-
</html>
|
|
37
|
+
<Page {headings} entry={entry} slug={entry.slug} {...entryMeta} {entryMeta}>
|
|
38
|
+
<Content />
|
|
39
|
+
</Page>
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# @astrojs/starlight
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#237](https://github.com/withastro/starlight/pull/237) [`4279d75`](https://github.com/withastro/starlight/commit/4279d7512a8261b576056471f5aa1ede1e6aae4a) Thanks [@HiDeoo](https://github.com/HiDeoo)! - Use path instead of slugified path for auto-generated sidebar item configuration
|
|
8
|
+
|
|
9
|
+
⚠️ Potentially breaking change. If your docs directory names don’t match their URLs, for example they contain whitespace like `docs/my docs/`, and you were referencing these in an `autogenerate` sidebar group as `my-docs`, update your config to reference these with the directory name instead of the slugified version:
|
|
10
|
+
|
|
11
|
+
```diff
|
|
12
|
+
autogenerate: {
|
|
13
|
+
- directory: 'my-docs',
|
|
14
|
+
+ directory: 'my docs',
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- [#226](https://github.com/withastro/starlight/pull/226) [`1aa2187`](https://github.com/withastro/starlight/commit/1aa2187944dde4419e523f0087139f5a21efd826) Thanks [@delucis](https://github.com/delucis)! - Add support for custom 404 pages.
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- [#234](https://github.com/withastro/starlight/pull/234) [`91309ae`](https://github.com/withastro/starlight/commit/91309ae13250c5fd9f91a8e1843f16430773ff15) Thanks [@morinokami](https://github.com/morinokami)! - Add Japanese translation for `search.devWarning`
|
|
23
|
+
|
|
24
|
+
- [#227](https://github.com/withastro/starlight/pull/227) [`fbdecfa`](https://github.com/withastro/starlight/commit/fbdecfab47effb0cba7cbc9233a7b6bffdded320) Thanks [@Yan-Thomas](https://github.com/Yan-Thomas)! - Add missing i18n support to the Search component's dev warning.
|
|
25
|
+
|
|
26
|
+
- [#244](https://github.com/withastro/starlight/pull/244) [`f1bcbeb`](https://github.com/withastro/starlight/commit/f1bcbebeb441b6bb9ed6a1ab2414791e9d5de6ef) Thanks [@Waxer59](https://github.com/Waxer59)! - Add Spanish translation for `search.devWarning`
|
|
27
|
+
|
|
28
|
+
## 0.2.0
|
|
29
|
+
|
|
30
|
+
### Minor Changes
|
|
31
|
+
|
|
32
|
+
- [#171](https://github.com/withastro/starlight/pull/171) [`198c3f0`](https://github.com/withastro/starlight/commit/198c3f001410f259dab7d085136a37afe863cfa4) Thanks [@delucis](https://github.com/delucis)! - Add Starlight generator tag to HTML output
|
|
33
|
+
|
|
34
|
+
- [#217](https://github.com/withastro/starlight/pull/217) [`490fd98`](https://github.com/withastro/starlight/commit/490fd98d4e7b38ec01c568eee0ab00844e59c53d) Thanks [@delucis](https://github.com/delucis)! - Updated sidebar styles. Sidebars now support top-level links and groups are styled with a subtle border and indentation to improve comprehension of nesting.
|
|
35
|
+
|
|
36
|
+
- [#178](https://github.com/withastro/starlight/pull/178) [`d046c55`](https://github.com/withastro/starlight/commit/d046c55a62290c15f2e09faf4359f02df9492f6d) Thanks [@delucis](https://github.com/delucis)! - Add support for translating the Pagefind search modal
|
|
37
|
+
|
|
38
|
+
- [#210](https://github.com/withastro/starlight/pull/210) [`cb5b121`](https://github.com/withastro/starlight/commit/cb5b1210e23548e2983865a4b38308b0f54dc7ce) Thanks [@delucis](https://github.com/delucis)! - Change page title ID to `_top` for cleaner hash URLs
|
|
39
|
+
|
|
40
|
+
⚠️ Potentially breaking change if you were linking manually to `#starlight__overview` anywhere. If you were, update these links to use `#_top` instead.
|
|
41
|
+
|
|
42
|
+
### Patch Changes
|
|
43
|
+
|
|
44
|
+
- [#208](https://github.com/withastro/starlight/pull/208) [`09fc565`](https://github.com/withastro/starlight/commit/09fc565d44bd3abb4508541b458531de8624036f) Thanks [@delucis](https://github.com/delucis)! - Update `@astrojs/mdx` and `@astrojs/sitemap` to latest
|
|
45
|
+
|
|
46
|
+
- [#216](https://github.com/withastro/starlight/pull/216) [`54905c5`](https://github.com/withastro/starlight/commit/54905c502c5e6de5516e36ddcd4969893572baa5) Thanks [@morinokami](https://github.com/morinokami)! - Encode heading id when finding current link
|
|
47
|
+
|
|
3
48
|
## 0.1.4
|
|
4
49
|
|
|
5
50
|
### Patch Changes
|
|
File without changes
|
package/components/HeadSEO.astro
CHANGED
|
@@ -5,6 +5,7 @@ import type { HeadConfigSchema } from '../schemas/head';
|
|
|
5
5
|
import { createHead } from '../utils/head';
|
|
6
6
|
import { localizedUrl } from '../utils/localizedUrl';
|
|
7
7
|
import { fileWithBase } from '../utils/base';
|
|
8
|
+
import { version } from '../package.json';
|
|
8
9
|
|
|
9
10
|
interface Props {
|
|
10
11
|
data: CollectionEntry<'docs'>['data'];
|
|
@@ -28,6 +29,10 @@ const headDefaults: z.input<ReturnType<typeof HeadConfigSchema>> = [
|
|
|
28
29
|
{ tag: 'title', content: title },
|
|
29
30
|
{ tag: 'link', attrs: { rel: 'canonical', href: canonical?.href } },
|
|
30
31
|
{ tag: 'meta', attrs: { name: 'generator', content: Astro.generator } },
|
|
32
|
+
{
|
|
33
|
+
tag: 'meta',
|
|
34
|
+
attrs: { name: 'generator', content: `Starlight v${version}` },
|
|
35
|
+
},
|
|
31
36
|
// Favicon
|
|
32
37
|
{
|
|
33
38
|
tag: 'link',
|
package/components/Hero.astro
CHANGED
package/components/Search.astro
CHANGED
|
@@ -8,9 +8,18 @@ interface Props {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
const t = useTranslations(Astro.props.locale);
|
|
11
|
+
const pagefindTranslations = {
|
|
12
|
+
placeholder: t('search.label'),
|
|
13
|
+
...Object.fromEntries(
|
|
14
|
+
Object.entries(t.pick('pagefind.')).map(([key, value]) => [
|
|
15
|
+
key.replace('pagefind.', ''),
|
|
16
|
+
value,
|
|
17
|
+
])
|
|
18
|
+
),
|
|
19
|
+
};
|
|
11
20
|
---
|
|
12
21
|
|
|
13
|
-
<site-search>
|
|
22
|
+
<site-search data-translations={JSON.stringify(pagefindTranslations)}>
|
|
14
23
|
<button data-open-modal disabled>
|
|
15
24
|
{
|
|
16
25
|
/* The span is `aria-hidden` because it is not shown on small screens. Instead, the icon label is used for accessibility purposes. */
|
|
@@ -34,9 +43,8 @@ const t = useTranslations(Astro.props.locale);
|
|
|
34
43
|
</button>
|
|
35
44
|
{
|
|
36
45
|
import.meta.env.DEV ? (
|
|
37
|
-
<div style="margin: auto; text-align: center;" dir="ltr">
|
|
38
|
-
<p>
|
|
39
|
-
<p>Try building and previewing the site to test it out locally.</p>
|
|
46
|
+
<div style="margin: auto; text-align: center; white-space: pre-line;" dir="ltr">
|
|
47
|
+
<p>{t("search.devWarning")}</p>
|
|
40
48
|
</div>
|
|
41
49
|
) : (
|
|
42
50
|
<div class="search-container">
|
|
@@ -96,23 +104,31 @@ const t = useTranslations(Astro.props.locale);
|
|
|
96
104
|
e.preventDefault();
|
|
97
105
|
}
|
|
98
106
|
});
|
|
107
|
+
|
|
108
|
+
let translations = {};
|
|
109
|
+
try {
|
|
110
|
+
translations = JSON.parse(this.dataset.translations || '{}');
|
|
111
|
+
} catch {}
|
|
112
|
+
|
|
113
|
+
window.addEventListener('DOMContentLoaded', () => {
|
|
114
|
+
if (import.meta.env.DEV) return;
|
|
115
|
+
const onIdle =
|
|
116
|
+
window.requestIdleCallback || ((cb) => setTimeout(cb, 1));
|
|
117
|
+
onIdle(async () => {
|
|
118
|
+
const { PagefindUI } = await import('@pagefind/default-ui');
|
|
119
|
+
new PagefindUI({
|
|
120
|
+
element: '#starlight__search',
|
|
121
|
+
baseUrl: import.meta.env.BASE_URL,
|
|
122
|
+
bundlePath:
|
|
123
|
+
import.meta.env.BASE_URL.replace(/\/$/, '') + '/_pagefind/',
|
|
124
|
+
showImages: false,
|
|
125
|
+
translations,
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
});
|
|
99
129
|
}
|
|
100
130
|
}
|
|
101
131
|
customElements.define('site-search', SiteSearch);
|
|
102
|
-
|
|
103
|
-
window.addEventListener('DOMContentLoaded', () => {
|
|
104
|
-
if (import.meta.env.DEV) return;
|
|
105
|
-
const onIdle = window.requestIdleCallback || ((cb) => setTimeout(cb, 1));
|
|
106
|
-
onIdle(async () => {
|
|
107
|
-
const { PagefindUI } = await import('@pagefind/default-ui');
|
|
108
|
-
new PagefindUI({
|
|
109
|
-
element: '#starlight__search',
|
|
110
|
-
baseUrl: import.meta.env.BASE_URL,
|
|
111
|
-
bundlePath: import.meta.env.BASE_URL.replace(/\/$/, '') + '/_pagefind/',
|
|
112
|
-
showImages: false,
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
132
|
</script>
|
|
117
133
|
|
|
118
134
|
<style>
|
|
@@ -4,24 +4,29 @@ import Icon from './Icon.astro';
|
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
6
|
sublist: SidebarEntry[];
|
|
7
|
+
nested?: boolean;
|
|
7
8
|
}
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
<ul>
|
|
11
|
+
<ul class:list={{ 'top-level': !Astro.props.nested }}>
|
|
11
12
|
{
|
|
12
13
|
Astro.props.sublist.map((entry) => (
|
|
13
|
-
<li
|
|
14
|
+
<li>
|
|
14
15
|
{entry.type === 'link' ? (
|
|
15
|
-
<a
|
|
16
|
+
<a
|
|
17
|
+
href={entry.href}
|
|
18
|
+
aria-current={entry.isCurrent && 'page'}
|
|
19
|
+
class:list={{ large: !Astro.props.nested }}
|
|
20
|
+
>
|
|
16
21
|
{entry.label}
|
|
17
22
|
</a>
|
|
18
23
|
) : (
|
|
19
24
|
<details open>
|
|
20
25
|
<summary>
|
|
21
|
-
<h2>{entry.label}</h2>
|
|
26
|
+
<h2 class="large">{entry.label}</h2>
|
|
22
27
|
<Icon name="right-caret" class="caret" size="1.25rem" />
|
|
23
28
|
</summary>
|
|
24
|
-
<Astro.self sublist={entry.entries} />
|
|
29
|
+
<Astro.self sublist={entry.entries} nested />
|
|
25
30
|
</details>
|
|
26
31
|
)}
|
|
27
32
|
</li>
|
|
@@ -36,13 +41,19 @@ interface Props {
|
|
|
36
41
|
padding: 0;
|
|
37
42
|
}
|
|
38
43
|
|
|
39
|
-
|
|
44
|
+
ul ul li {
|
|
45
|
+
margin-inline-start: var(--sl-sidebar-item-padding-inline);
|
|
46
|
+
border-inline-start: 1px solid var(--sl-color-hairline-light);
|
|
47
|
+
padding-inline-start: var(--sl-sidebar-item-padding-inline);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.large {
|
|
40
51
|
font-size: var(--sl-text-lg);
|
|
41
52
|
font-weight: 600;
|
|
42
53
|
color: var(--sl-color-white);
|
|
43
54
|
}
|
|
44
55
|
|
|
45
|
-
.
|
|
56
|
+
.top-level > li + li {
|
|
46
57
|
margin-top: 0.75rem;
|
|
47
58
|
}
|
|
48
59
|
|
|
@@ -91,10 +102,10 @@ interface Props {
|
|
|
91
102
|
}
|
|
92
103
|
|
|
93
104
|
@media (min-width: 50rem) {
|
|
94
|
-
.
|
|
105
|
+
.top-level > li + li {
|
|
95
106
|
margin-top: 0.5rem;
|
|
96
107
|
}
|
|
97
|
-
|
|
108
|
+
.large {
|
|
98
109
|
font-size: var(--sl-text-base);
|
|
99
110
|
}
|
|
100
111
|
a {
|
|
@@ -25,7 +25,7 @@ export function generateToC(
|
|
|
25
25
|
headings: MarkdownHeading[],
|
|
26
26
|
{ minHeadingLevel, maxHeadingLevel, title = 'Overview' }: TocOpts
|
|
27
27
|
) {
|
|
28
|
-
const overview = { depth: 2, slug: '
|
|
28
|
+
const overview = { depth: 2, slug: '_top', text: title };
|
|
29
29
|
headings = [
|
|
30
30
|
overview,
|
|
31
31
|
...headings.filter(
|
|
@@ -22,7 +22,7 @@ export class StarlightTOC extends HTMLElement {
|
|
|
22
22
|
const isHeading = (el: Element): el is HTMLHeadingElement => {
|
|
23
23
|
if (el instanceof HTMLHeadingElement) {
|
|
24
24
|
// Special case for page title h1
|
|
25
|
-
if (el.
|
|
25
|
+
if ('pageTitle' in el.dataset) return true;
|
|
26
26
|
// Check the heading level is within the user-configured limits for the ToC
|
|
27
27
|
const level = el.tagName[1];
|
|
28
28
|
if (level) {
|
|
@@ -60,7 +60,7 @@ export class StarlightTOC extends HTMLElement {
|
|
|
60
60
|
if (!isIntersecting) continue;
|
|
61
61
|
const heading = getElementHeading(target);
|
|
62
62
|
if (!heading) continue;
|
|
63
|
-
const link = links.find((link) => link.hash === '#' + heading.id);
|
|
63
|
+
const link = links.find((link) => link.hash === '#' + encodeURIComponent(heading.id));
|
|
64
64
|
if (link) {
|
|
65
65
|
this.current = link;
|
|
66
66
|
break;
|
package/index.astro
CHANGED
|
@@ -1,121 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { InferGetStaticPropsType } from 'astro';
|
|
3
|
-
import config from 'virtual:starlight/user-config';
|
|
4
|
-
|
|
5
|
-
import { getSidebar } from './utils/navigation';
|
|
6
3
|
import { paths } from './utils/routing';
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
import './style/props.css';
|
|
10
|
-
import './style/reset.css';
|
|
11
|
-
import './style/shiki.css';
|
|
12
|
-
import './style/util.css';
|
|
13
|
-
|
|
14
|
-
// Components — can override built-in CSS, but not user CSS.
|
|
15
|
-
import ContentPanel from './components/ContentPanel.astro';
|
|
16
|
-
import FallbackContentNotice from './components/FallbackContentNotice.astro';
|
|
17
|
-
import HeadSEO from './components/HeadSEO.astro';
|
|
18
|
-
import Header from './components/Header.astro';
|
|
19
|
-
import Footer from './components/Footer.astro';
|
|
20
|
-
import MarkdownContent from './components/MarkdownContent.astro';
|
|
21
|
-
import RightSidebar from './components/RightSidebar.astro';
|
|
22
|
-
import Sidebar from './components/Sidebar.astro';
|
|
23
|
-
import SkipLink from './components/SkipLink.astro';
|
|
24
|
-
import ThemeProvider from './components/ThemeProvider.astro';
|
|
25
|
-
import PageFrame from './layout/PageFrame.astro';
|
|
26
|
-
import TwoColumnContent from './layout/TwoColumnContent.astro';
|
|
27
|
-
import Hero from './components/Hero.astro';
|
|
28
|
-
|
|
29
|
-
// Remark component CSS (needs to override `MarkdownContent.astro`)
|
|
30
|
-
import './style/asides.css';
|
|
31
|
-
|
|
32
|
-
// Important that this is the last import so it can override built-in styles.
|
|
33
|
-
import 'virtual:starlight/user-css';
|
|
5
|
+
import Page from './layout/Page.astro';
|
|
34
6
|
|
|
35
7
|
export async function getStaticPaths() {
|
|
36
8
|
return paths;
|
|
37
9
|
}
|
|
38
10
|
|
|
39
11
|
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
|
40
|
-
|
|
41
|
-
const { dir, entry, entryMeta, isFallback, lang, locale } = Astro.props;
|
|
42
|
-
const { Content, headings } = await entry.render();
|
|
43
|
-
const sidebar = getSidebar(Astro.url.pathname, locale);
|
|
44
|
-
|
|
45
|
-
const hasSidebar = entry.data.template !== 'splash';
|
|
46
|
-
const tocConfig = !hasSidebar
|
|
47
|
-
? false
|
|
48
|
-
: entry.data.tableOfContents !== undefined
|
|
49
|
-
? entry.data.tableOfContents
|
|
50
|
-
: config.tableOfContents;
|
|
51
|
-
const hasToC = Boolean(tocConfig);
|
|
52
|
-
const hasHero = Boolean(entry.data.hero);
|
|
12
|
+
const { Content, headings } = await Astro.props.entry.render();
|
|
53
13
|
---
|
|
54
14
|
|
|
55
|
-
<
|
|
56
|
-
<head>
|
|
57
|
-
<HeadSEO data={entry.data} lang={lang} />
|
|
58
|
-
<style>
|
|
59
|
-
html:not([data-has-toc]) {
|
|
60
|
-
--sl-mobile-toc-height: 0rem;
|
|
61
|
-
}
|
|
62
|
-
html:not([data-has-sidebar]) {
|
|
63
|
-
--sl-content-width: 67.5rem;
|
|
64
|
-
}
|
|
65
|
-
/* Add scroll padding to ensure anchor headings aren't obscured by nav */
|
|
66
|
-
html {
|
|
67
|
-
/* Additional padding is needed to account for the mobile TOC */
|
|
68
|
-
scroll-padding-top: calc(
|
|
69
|
-
1.5rem + var(--sl-nav-height) + var(--sl-mobile-toc-height)
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
main {
|
|
73
|
-
padding-bottom: 3vh;
|
|
74
|
-
}
|
|
75
|
-
@media (min-width: 50em) {
|
|
76
|
-
[data-has-sidebar] {
|
|
77
|
-
--sl-content-inline-start: var(--sl-sidebar-width);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
@media (min-width: 72em) {
|
|
81
|
-
html {
|
|
82
|
-
scroll-padding-top: calc(1.5rem + var(--sl-nav-height));
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
</style>
|
|
86
|
-
</head>
|
|
87
|
-
<body>
|
|
88
|
-
<ThemeProvider />
|
|
89
|
-
<SkipLink {locale} />
|
|
90
|
-
<PageFrame {locale} {hasSidebar}>
|
|
91
|
-
<Header slot="header" {locale} />
|
|
92
|
-
{hasSidebar && <Sidebar slot="sidebar" {sidebar} {locale} />}
|
|
93
|
-
<TwoColumnContent {hasToC}>
|
|
94
|
-
<RightSidebar slot="right-sidebar" {headings} {locale} {tocConfig} />
|
|
95
|
-
<main data-pagefind-body lang={entryMeta.lang} dir={entryMeta.dir}>
|
|
96
|
-
{/* TODO: Revisit how this logic flows. */}
|
|
97
|
-
{entry.data.hero ? (
|
|
98
|
-
<ContentPanel>
|
|
99
|
-
<Hero hero={entry.data.hero} fallbackTitle={entry.data.title} />
|
|
100
|
-
<MarkdownContent><Content /></MarkdownContent>
|
|
101
|
-
</ContentPanel>
|
|
102
|
-
) : (
|
|
103
|
-
<ContentPanel>
|
|
104
|
-
<h1
|
|
105
|
-
id="starlight__overview"
|
|
106
|
-
style="font-size: var(--sl-text-h1); line-height: var(--sl-line-height-headings); font-weight: 600; color: var(--sl-color-white); margin-top: 1rem;"
|
|
107
|
-
>
|
|
108
|
-
{entry.data.title}
|
|
109
|
-
</h1>
|
|
110
|
-
{isFallback && <FallbackContentNotice {locale} />}
|
|
111
|
-
</ContentPanel>
|
|
112
|
-
<ContentPanel>
|
|
113
|
-
<MarkdownContent><Content /></MarkdownContent>
|
|
114
|
-
<Footer {...{ entry, dir, lang, locale, sidebar }} />
|
|
115
|
-
</ContentPanel>
|
|
116
|
-
)}
|
|
117
|
-
</main>
|
|
118
|
-
</TwoColumnContent>
|
|
119
|
-
</PageFrame>
|
|
120
|
-
</body>
|
|
121
|
-
</html>
|
|
15
|
+
<Page {...Astro.props} {headings}><Content /></Page>
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
import config from 'virtual:starlight/user-config';
|
|
3
|
+
import type { MarkdownHeading } from 'astro';
|
|
4
|
+
import { getSidebar } from '../utils/navigation';
|
|
5
|
+
import type { Route } from '../utils/routing';
|
|
6
|
+
|
|
7
|
+
// Built-in CSS styles.
|
|
8
|
+
import '../style/props.css';
|
|
9
|
+
import '../style/reset.css';
|
|
10
|
+
import '../style/shiki.css';
|
|
11
|
+
import '../style/util.css';
|
|
12
|
+
|
|
13
|
+
// Components — can override built-in CSS, but not user CSS.
|
|
14
|
+
import ContentPanel from '../components/ContentPanel.astro';
|
|
15
|
+
import FallbackContentNotice from '../components/FallbackContentNotice.astro';
|
|
16
|
+
import Footer from '../components/Footer.astro';
|
|
17
|
+
import HeadSEO from '../components/HeadSEO.astro';
|
|
18
|
+
import Header from '../components/Header.astro';
|
|
19
|
+
import Hero from '../components/Hero.astro';
|
|
20
|
+
import MarkdownContent from '../components/MarkdownContent.astro';
|
|
21
|
+
import RightSidebar from '../components/RightSidebar.astro';
|
|
22
|
+
import Sidebar from '../components/Sidebar.astro';
|
|
23
|
+
import SkipLink from '../components/SkipLink.astro';
|
|
24
|
+
import ThemeProvider from '../components/ThemeProvider.astro';
|
|
25
|
+
import PageFrame from '../layout/PageFrame.astro';
|
|
26
|
+
import TwoColumnContent from '../layout/TwoColumnContent.astro';
|
|
27
|
+
|
|
28
|
+
// Remark component CSS (needs to override `MarkdownContent.astro`)
|
|
29
|
+
import '../style/asides.css';
|
|
30
|
+
|
|
31
|
+
// Important that this is the last import so it can override built-in styles.
|
|
32
|
+
import 'virtual:starlight/user-css';
|
|
33
|
+
|
|
34
|
+
type Props = Route & { headings: MarkdownHeading[] };
|
|
35
|
+
|
|
36
|
+
const { dir, entry, entryMeta, headings, isFallback, lang, locale } = Astro.props;
|
|
37
|
+
const sidebar = getSidebar(Astro.url.pathname, locale);
|
|
38
|
+
|
|
39
|
+
const hasSidebar = entry.data.template !== 'splash';
|
|
40
|
+
const tocConfig = !hasSidebar
|
|
41
|
+
? false
|
|
42
|
+
: entry.data.tableOfContents !== undefined
|
|
43
|
+
? entry.data.tableOfContents
|
|
44
|
+
: config.tableOfContents;
|
|
45
|
+
const hasToC = Boolean(tocConfig);
|
|
46
|
+
const hasHero = Boolean(entry.data.hero);
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
<html lang={lang} dir={dir} data-has-toc={hasToC} data-has-sidebar={hasSidebar} data-has-hero={hasHero}>
|
|
50
|
+
<head>
|
|
51
|
+
<HeadSEO data={entry.data} lang={lang} />
|
|
52
|
+
<style>
|
|
53
|
+
html:not([data-has-toc]) {
|
|
54
|
+
--sl-mobile-toc-height: 0rem;
|
|
55
|
+
}
|
|
56
|
+
html:not([data-has-sidebar]) {
|
|
57
|
+
--sl-content-width: 67.5rem;
|
|
58
|
+
}
|
|
59
|
+
/* Add scroll padding to ensure anchor headings aren't obscured by nav */
|
|
60
|
+
html {
|
|
61
|
+
/* Additional padding is needed to account for the mobile TOC */
|
|
62
|
+
scroll-padding-top: calc(
|
|
63
|
+
1.5rem + var(--sl-nav-height) + var(--sl-mobile-toc-height)
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
main {
|
|
67
|
+
padding-bottom: 3vh;
|
|
68
|
+
}
|
|
69
|
+
@media (min-width: 50em) {
|
|
70
|
+
[data-has-sidebar] {
|
|
71
|
+
--sl-content-inline-start: var(--sl-sidebar-width);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
@media (min-width: 72em) {
|
|
75
|
+
html {
|
|
76
|
+
scroll-padding-top: calc(1.5rem + var(--sl-nav-height));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
</style>
|
|
80
|
+
</head>
|
|
81
|
+
<body>
|
|
82
|
+
<ThemeProvider />
|
|
83
|
+
<SkipLink {locale} />
|
|
84
|
+
<PageFrame {locale} {hasSidebar}>
|
|
85
|
+
<Header slot="header" {locale} />
|
|
86
|
+
{hasSidebar && <Sidebar slot="sidebar" {sidebar} {locale} />}
|
|
87
|
+
<TwoColumnContent {hasToC}>
|
|
88
|
+
<RightSidebar slot="right-sidebar" {headings} {locale} {tocConfig} />
|
|
89
|
+
<main data-pagefind-body={entry.slug !== '404'} lang={entryMeta.lang} dir={entryMeta.dir}>
|
|
90
|
+
{/* TODO: Revisit how this logic flows. */}
|
|
91
|
+
{entry.data.hero ? (
|
|
92
|
+
<ContentPanel>
|
|
93
|
+
<Hero hero={entry.data.hero} fallbackTitle={entry.data.title} />
|
|
94
|
+
<MarkdownContent><slot /></MarkdownContent>
|
|
95
|
+
</ContentPanel>
|
|
96
|
+
) : (
|
|
97
|
+
<ContentPanel>
|
|
98
|
+
<h1
|
|
99
|
+
id="_top"
|
|
100
|
+
data-page-title
|
|
101
|
+
style="font-size: var(--sl-text-h1); line-height: var(--sl-line-height-headings); font-weight: 600; color: var(--sl-color-white); margin-top: 1rem;"
|
|
102
|
+
>
|
|
103
|
+
{entry.data.title}
|
|
104
|
+
</h1>
|
|
105
|
+
{isFallback && <FallbackContentNotice {locale} />}
|
|
106
|
+
</ContentPanel>
|
|
107
|
+
<ContentPanel>
|
|
108
|
+
<MarkdownContent><slot /></MarkdownContent>
|
|
109
|
+
<Footer {...{ entry, dir, lang, locale, sidebar }} />
|
|
110
|
+
</ContentPanel>
|
|
111
|
+
)}
|
|
112
|
+
</main>
|
|
113
|
+
</TwoColumnContent>
|
|
114
|
+
</PageFrame>
|
|
115
|
+
</body>
|
|
116
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/starlight",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Build beautiful, high-performance documentation websites with Astro",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"docs",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"astro": "^2.5.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@astrojs/mdx": "^0.19.
|
|
38
|
-
"@astrojs/sitemap": "^1.3.
|
|
37
|
+
"@astrojs/mdx": "^0.19.7",
|
|
38
|
+
"@astrojs/sitemap": "^1.3.3",
|
|
39
39
|
"@pagefind/default-ui": "^1.0.0-alpha.5",
|
|
40
40
|
"@types/mdast": "^3.0.11",
|
|
41
41
|
"bcp-47": "^2.1.0",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"unified": "^10.1.2",
|
|
48
48
|
"unist-util-remove": "^3.1.1",
|
|
49
49
|
"unist-util-visit": "^4.1.2",
|
|
50
|
-
"vfile": "^
|
|
50
|
+
"vfile": "^6.0.0"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {}
|
|
53
53
|
}
|
package/schemas/i18n.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { z } from 'astro/zod';
|
|
2
2
|
|
|
3
3
|
export function i18nSchema() {
|
|
4
|
+
return starlightI18nSchema().merge(pagefindI18nSchema());
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function builtinI18nSchema() {
|
|
8
|
+
return starlightI18nSchema().required().strict().merge(pagefindI18nSchema());
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function starlightI18nSchema() {
|
|
4
12
|
return z
|
|
5
13
|
.object({
|
|
6
14
|
'skipLink.label': z
|
|
@@ -21,6 +29,10 @@ export function i18nSchema() {
|
|
|
21
29
|
.string()
|
|
22
30
|
.describe('Text for the “Cancel” button that closes the search modal.'),
|
|
23
31
|
|
|
32
|
+
'search.devWarning': z
|
|
33
|
+
.string()
|
|
34
|
+
.describe('Warning displayed when opening the Search in a dev environment.'),
|
|
35
|
+
|
|
24
36
|
'themeSelect.accessibleLabel': z
|
|
25
37
|
.string()
|
|
26
38
|
.describe('Accessible label for the theme selection dropdown.'),
|
|
@@ -86,6 +98,76 @@ export function i18nSchema() {
|
|
|
86
98
|
.describe(
|
|
87
99
|
'Label shown on the “next page” pagination arrow in the page footer.'
|
|
88
100
|
),
|
|
101
|
+
|
|
102
|
+
'404.text': z
|
|
103
|
+
.string()
|
|
104
|
+
.describe('Text shown on Starlight’s default 404 page'),
|
|
105
|
+
})
|
|
106
|
+
.partial();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function pagefindI18nSchema() {
|
|
110
|
+
return z
|
|
111
|
+
.object({
|
|
112
|
+
'pagefind.clear_search': z
|
|
113
|
+
.string()
|
|
114
|
+
.describe(
|
|
115
|
+
'Pagefind UI translation. English default value: `"Clear"`. See https://pagefind.app/docs/ui/#translations'
|
|
116
|
+
),
|
|
117
|
+
|
|
118
|
+
'pagefind.load_more': z
|
|
119
|
+
.string()
|
|
120
|
+
.describe(
|
|
121
|
+
'Pagefind UI translation. English default value: `"Load more results"`. See https://pagefind.app/docs/ui/#translations'
|
|
122
|
+
),
|
|
123
|
+
|
|
124
|
+
'pagefind.search_label': z
|
|
125
|
+
.string()
|
|
126
|
+
.describe(
|
|
127
|
+
'Pagefind UI translation. English default value: `"Search this site"`. See https://pagefind.app/docs/ui/#translations'
|
|
128
|
+
),
|
|
129
|
+
|
|
130
|
+
'pagefind.filters_label': z
|
|
131
|
+
.string()
|
|
132
|
+
.describe(
|
|
133
|
+
'Pagefind UI translation. English default value: `"Filters"`. See https://pagefind.app/docs/ui/#translations'
|
|
134
|
+
),
|
|
135
|
+
|
|
136
|
+
'pagefind.zero_results': z
|
|
137
|
+
.string()
|
|
138
|
+
.describe(
|
|
139
|
+
'Pagefind UI translation. English default value: `"No results for [SEARCH_TERM]"`. See https://pagefind.app/docs/ui/#translations'
|
|
140
|
+
),
|
|
141
|
+
|
|
142
|
+
'pagefind.many_results': z
|
|
143
|
+
.string()
|
|
144
|
+
.describe(
|
|
145
|
+
'Pagefind UI translation. English default value: `"[COUNT] results for [SEARCH_TERM]"`. See https://pagefind.app/docs/ui/#translations'
|
|
146
|
+
),
|
|
147
|
+
|
|
148
|
+
'pagefind.one_result': z
|
|
149
|
+
.string()
|
|
150
|
+
.describe(
|
|
151
|
+
'Pagefind UI translation. English default value: `"[COUNT] result for [SEARCH_TERM]"`. See https://pagefind.app/docs/ui/#translations'
|
|
152
|
+
),
|
|
153
|
+
|
|
154
|
+
'pagefind.alt_search': z
|
|
155
|
+
.string()
|
|
156
|
+
.describe(
|
|
157
|
+
'Pagefind UI translation. English default value: `"No results for [SEARCH_TERM]. Showing results for [DIFFERENT_TERM] instead"`. See https://pagefind.app/docs/ui/#translations'
|
|
158
|
+
),
|
|
159
|
+
|
|
160
|
+
'pagefind.search_suggestion': z
|
|
161
|
+
.string()
|
|
162
|
+
.describe(
|
|
163
|
+
'Pagefind UI translation. English default value: `"No results for [SEARCH_TERM]. Try one of the following searches:"`. See https://pagefind.app/docs/ui/#translations'
|
|
164
|
+
),
|
|
165
|
+
|
|
166
|
+
'pagefind.searching': z
|
|
167
|
+
.string()
|
|
168
|
+
.describe(
|
|
169
|
+
'Pagefind UI translation. English default value: `"Searching for [SEARCH_TERM]..."`. See https://pagefind.app/docs/ui/#translations'
|
|
170
|
+
),
|
|
89
171
|
})
|
|
90
172
|
.partial();
|
|
91
173
|
}
|
package/style/props.css
CHANGED
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
--sl-color-bg-nav: var(--sl-color-gray-6);
|
|
44
44
|
--sl-color-bg-sidebar: var(--sl-color-gray-6);
|
|
45
45
|
--sl-color-bg-inline-code: var(--sl-color-gray-5);
|
|
46
|
+
--sl-color-hairline-light: var(--sl-color-gray-5);
|
|
46
47
|
--sl-color-hairline: var(--sl-color-gray-6);
|
|
47
48
|
--sl-color-hairline-shade: var(--sl-color-black);
|
|
48
49
|
|
|
@@ -150,6 +151,7 @@
|
|
|
150
151
|
--sl-color-bg-nav: var(--sl-color-gray-7);
|
|
151
152
|
--sl-color-bg-sidebar: var(--sl-color-bg);
|
|
152
153
|
--sl-color-bg-inline-code: var(--sl-color-gray-6);
|
|
154
|
+
--sl-color-hairline-light: var(--sl-color-gray-6);
|
|
153
155
|
--sl-color-hairline-shade: var(--sl-color-gray-6);
|
|
154
156
|
|
|
155
157
|
--sl-color-backdrop-overlay: hsla(225, 9%, 36%, 0.66);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Starlight UI translation files
|
|
2
|
+
|
|
3
|
+
This directory contains translation data for Starlight’s UI.
|
|
4
|
+
Each language has its own JSON file and follows the [translation structure described in Starlight’s docs](https://starlight.astro.build/guides/i18n/#translate-starlights-ui).
|
|
5
|
+
|
|
6
|
+
## Add a new language
|
|
7
|
+
|
|
8
|
+
1. Create a JSON file named using the BCP-47 tag for the language, e.g. `en.json` or `ja.json`.
|
|
9
|
+
|
|
10
|
+
2. Fill the file with translations for each UI string. You can base your translations on [`en.json`](./en.json). Translate only the values, leaving the keys in English (e.g. `"search.label": "Buscar"`).
|
|
11
|
+
|
|
12
|
+
3. Import your file in [`index.ts`](./index.ts) and add your language to the `Object.entries`.
|
|
13
|
+
|
|
14
|
+
4. Open a pull request on GitHub to add your file to Starlight!
|
package/translations/de.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "Suchen",
|
|
4
4
|
"search.shortcutLabel": "(Drücke / zum Suchen)",
|
|
5
5
|
"search.cancelLabel": "Abbrechen",
|
|
6
|
+
"search.devWarning": "Search is only available in production builds. \nTry building and previewing the site to test it out locally.",
|
|
6
7
|
"themeSelect.accessibleLabel": "Farbschema wählen",
|
|
7
8
|
"themeSelect.dark": "Dunkel",
|
|
8
9
|
"themeSelect.light": "Hell",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "Seite bearbeiten",
|
|
17
18
|
"page.lastUpdated": "Zuletzt bearbeitet:",
|
|
18
19
|
"page.previousLink": "Vorherige Seite",
|
|
19
|
-
"page.nextLink": "Nächste Seite"
|
|
20
|
+
"page.nextLink": "Nächste Seite",
|
|
21
|
+
"404.text": "Seite nicht gefunden. Überprüfe die URL oder nutze die Suchleiste."
|
|
20
22
|
}
|
package/translations/en.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "Search",
|
|
4
4
|
"search.shortcutLabel": "(Press / to Search)",
|
|
5
5
|
"search.cancelLabel": "Cancel",
|
|
6
|
+
"search.devWarning": "Search is only available in production builds. \nTry building and previewing the site to test it out locally.",
|
|
6
7
|
"themeSelect.accessibleLabel": "Select theme",
|
|
7
8
|
"themeSelect.dark": "Dark",
|
|
8
9
|
"themeSelect.light": "Light",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "Edit page",
|
|
17
18
|
"page.lastUpdated": "Last updated:",
|
|
18
19
|
"page.previousLink": "Previous",
|
|
19
|
-
"page.nextLink": "Next"
|
|
20
|
+
"page.nextLink": "Next",
|
|
21
|
+
"404.text": "Page not found. Check the URL or try using the search bar."
|
|
20
22
|
}
|
package/translations/es.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "Buscar",
|
|
4
4
|
"search.shortcutLabel": "(Presiona / para buscar)",
|
|
5
5
|
"search.cancelLabel": "Interrumpir",
|
|
6
|
+
"search.devWarning": "La búsqueda solo está disponible en las versiones de producción. \nIntenta construir y previsualizar el sitio para probarlo localmente.",
|
|
6
7
|
"themeSelect.accessibleLabel": "Seleccionar tema",
|
|
7
8
|
"themeSelect.dark": "Oscuro",
|
|
8
9
|
"themeSelect.light": "Claro",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "Edita esta página",
|
|
17
18
|
"page.lastUpdated": "Última actualización:",
|
|
18
19
|
"page.previousLink": "Página anterior",
|
|
19
|
-
"page.nextLink": "Siguiente página"
|
|
20
|
+
"page.nextLink": "Siguiente página",
|
|
21
|
+
"404.text": "Página no encontrada. Verifique la URL o intente usar la barra de búsqueda."
|
|
20
22
|
}
|
package/translations/fr.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "Rechercher",
|
|
4
4
|
"search.shortcutLabel": "(Presser / pour rechercher)",
|
|
5
5
|
"search.cancelLabel": "Annuler",
|
|
6
|
+
"search.devWarning": "Search is only available in production builds. \nTry building and previewing the site to test it out locally.",
|
|
6
7
|
"themeSelect.accessibleLabel": "Selectionner le thème",
|
|
7
8
|
"themeSelect.dark": "Dark",
|
|
8
9
|
"themeSelect.light": "Light",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "Editer la page",
|
|
17
18
|
"page.lastUpdated": "Dernière mise à jour :",
|
|
18
19
|
"page.previousLink": "Précédent",
|
|
19
|
-
"page.nextLink": "Suivant"
|
|
20
|
+
"page.nextLink": "Suivant",
|
|
21
|
+
"404.text": "Page non trouvée. Vérifiez l'URL ou essayez d'utiliser la barre de recherche."
|
|
20
22
|
}
|
package/translations/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { builtinI18nSchema } from '../schemas/i18n';
|
|
2
2
|
import en from './en.json';
|
|
3
3
|
import es from './es.json';
|
|
4
4
|
import de from './de.json';
|
|
@@ -7,7 +7,7 @@ import pt from './pt.json';
|
|
|
7
7
|
import fr from './fr.json';
|
|
8
8
|
import it from './it.json';
|
|
9
9
|
|
|
10
|
-
const parse =
|
|
10
|
+
const { parse } = builtinI18nSchema();
|
|
11
11
|
|
|
12
12
|
export default Object.fromEntries(
|
|
13
13
|
Object.entries({ en, es, de, ja, pt, fr, it }).map(([key, dict]) => [key, parse(dict)])
|
package/translations/it.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "Cerca",
|
|
4
4
|
"search.shortcutLabel": "(Usa / per cercare)",
|
|
5
5
|
"search.cancelLabel": "Cancella",
|
|
6
|
+
"search.devWarning": "Search is only available in production builds. \nTry building and previewing the site to test it out locally.",
|
|
6
7
|
"themeSelect.accessibleLabel": "Seleziona tema",
|
|
7
8
|
"themeSelect.dark": "Scuro",
|
|
8
9
|
"themeSelect.light": "Chiaro",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "Modifica pagina",
|
|
17
18
|
"page.lastUpdated": "Ultimo aggiornamento:",
|
|
18
19
|
"page.previousLink": "Indietro",
|
|
19
|
-
"page.nextLink": "Avanti"
|
|
20
|
+
"page.nextLink": "Avanti",
|
|
21
|
+
"404.text": "Pagina non trovata. Verifica l'URL o prova a utilizzare la barra di ricerca."
|
|
20
22
|
}
|
package/translations/ja.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "検索",
|
|
4
4
|
"search.shortcutLabel": "(/を押して検索)",
|
|
5
5
|
"search.cancelLabel": "キャンセル",
|
|
6
|
+
"search.devWarning": "検索はプロダクションビルドでのみ利用可能です。\nローカルでテストするには、サイトをビルドしてプレビューしてください。",
|
|
6
7
|
"themeSelect.accessibleLabel": "テーマの選択",
|
|
7
8
|
"themeSelect.dark": "ダーク",
|
|
8
9
|
"themeSelect.light": "ライト",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "ページを編集",
|
|
17
18
|
"page.lastUpdated": "最終更新日:",
|
|
18
19
|
"page.previousLink": "前へ",
|
|
19
|
-
"page.nextLink": "次へ"
|
|
20
|
+
"page.nextLink": "次へ",
|
|
21
|
+
"404.text": "ページが見つかりません。 URL を確認するか、検索バーを使用してみてください。"
|
|
20
22
|
}
|
package/translations/pt.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"search.label": "Pesquisar",
|
|
4
4
|
"search.shortcutLabel": "(Pressione / para Pesquisar)",
|
|
5
5
|
"search.cancelLabel": "Cancelar",
|
|
6
|
+
"search.devWarning": "A pesquisa está disponível apenas em builds em produção. \nTente fazer a build e pré-visualize o site para testar localmente.",
|
|
6
7
|
"themeSelect.accessibleLabel": "Selecionar tema",
|
|
7
8
|
"themeSelect.dark": "Escuro",
|
|
8
9
|
"themeSelect.light": "Claro",
|
|
@@ -16,5 +17,6 @@
|
|
|
16
17
|
"page.editLink": "Editar página",
|
|
17
18
|
"page.lastUpdated": "Última atualização:",
|
|
18
19
|
"page.previousLink": "Anterior",
|
|
19
|
-
"page.nextLink": "Próximo"
|
|
20
|
+
"page.nextLink": "Próximo",
|
|
21
|
+
"404.text": "Página não encontrada. Verifique o URL ou tente usar a barra de pesquisa."
|
|
20
22
|
}
|
package/utils/navigation.ts
CHANGED
|
@@ -69,9 +69,9 @@ function groupFromAutogenerateConfig(
|
|
|
69
69
|
const dirDocs = routes.filter(
|
|
70
70
|
(doc) =>
|
|
71
71
|
// Match against `foo.md` or `foo/index.md`.
|
|
72
|
-
doc.
|
|
72
|
+
stripExtension(doc.entry.id) === localeDir ||
|
|
73
73
|
// Match against `foo/anything/else.md`.
|
|
74
|
-
doc.
|
|
74
|
+
doc.entry.id.startsWith(localeDir + '/')
|
|
75
75
|
);
|
|
76
76
|
const tree = treeify(dirDocs, localeDir);
|
|
77
77
|
return {
|
|
@@ -115,16 +115,18 @@ function makeLink(href: string, label: string, currentPathname: string): Link {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
/** Get the segments leading to a page. */
|
|
118
|
-
function getBreadcrumbs(
|
|
119
|
-
//
|
|
120
|
-
|
|
118
|
+
function getBreadcrumbs(path: string, baseDir: string): string[] {
|
|
119
|
+
// Strip extension from path.
|
|
120
|
+
const pathWithoutExt = stripExtension(path);
|
|
121
|
+
// Index paths will match `baseDir` and don’t include breadcrumbs.
|
|
122
|
+
if (pathWithoutExt === baseDir) return [];
|
|
121
123
|
// Ensure base directory ends in a trailing slash.
|
|
122
124
|
if (!baseDir.endsWith('/')) baseDir += '/';
|
|
123
|
-
// Strip base directory from
|
|
124
|
-
const
|
|
125
|
-
?
|
|
126
|
-
:
|
|
127
|
-
let dir = dirname(
|
|
125
|
+
// Strip base directory from path if present.
|
|
126
|
+
const relativePath = pathWithoutExt.startsWith(baseDir)
|
|
127
|
+
? pathWithoutExt.replace(baseDir, '')
|
|
128
|
+
: pathWithoutExt;
|
|
129
|
+
let dir = dirname(relativePath);
|
|
128
130
|
// Return no breadcrumbs for items in the root directory.
|
|
129
131
|
if (dir === '.') return [];
|
|
130
132
|
return dir.split('/');
|
|
@@ -134,7 +136,7 @@ function getBreadcrumbs(slug: string, baseDir: string): string[] {
|
|
|
134
136
|
function treeify(routes: Route[], baseDir: string): Dir {
|
|
135
137
|
const treeRoot: Dir = {};
|
|
136
138
|
routes.forEach((doc) => {
|
|
137
|
-
const breadcrumbs = getBreadcrumbs(doc.
|
|
139
|
+
const breadcrumbs = getBreadcrumbs(doc.entry.id, baseDir);
|
|
138
140
|
|
|
139
141
|
// Walk down the route’s path to generate the tree.
|
|
140
142
|
let currentDir = treeRoot;
|
|
@@ -236,3 +238,6 @@ export function getPrevNextLinks(sidebar: SidebarEntry[]): {
|
|
|
236
238
|
const next = currentIndex > -1 ? entries[currentIndex + 1] : undefined;
|
|
237
239
|
return { prev, next };
|
|
238
240
|
}
|
|
241
|
+
|
|
242
|
+
/** Remove the extension from a path. */
|
|
243
|
+
const stripExtension = (path: string) => path.replace(/\.\w+$/, '');
|
package/utils/translations.ts
CHANGED
|
@@ -38,7 +38,12 @@ export function useTranslations(locale: string | undefined) {
|
|
|
38
38
|
builtinTranslations[lang],
|
|
39
39
|
userTranslations[lang]
|
|
40
40
|
);
|
|
41
|
-
|
|
41
|
+
const t = <K extends keyof typeof dictionary>(key: K) => dictionary[key];
|
|
42
|
+
t.pick = (startOfKey: string) =>
|
|
43
|
+
Object.fromEntries(
|
|
44
|
+
Object.entries(dictionary).filter(([k]) => k.startsWith(startOfKey))
|
|
45
|
+
);
|
|
46
|
+
return t;
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
/** Build a dictionary by layering preferred translation sources. */
|
package/utils/user-config.ts
CHANGED
|
@@ -95,14 +95,6 @@ const SidebarItemSchema = z.union([
|
|
|
95
95
|
]);
|
|
96
96
|
export type SidebarItem = z.infer<typeof SidebarItemSchema>;
|
|
97
97
|
|
|
98
|
-
const SidebarGroupSchema: z.ZodType<
|
|
99
|
-
| z.output<typeof ManualSidebarGroupSchema>
|
|
100
|
-
| z.output<typeof AutoSidebarGroupSchema>,
|
|
101
|
-
z.ZodTypeDef,
|
|
102
|
-
| z.input<typeof ManualSidebarGroupSchema>
|
|
103
|
-
| z.input<typeof AutoSidebarGroupSchema>
|
|
104
|
-
> = z.union([ManualSidebarGroupSchema, AutoSidebarGroupSchema]);
|
|
105
|
-
|
|
106
98
|
const UserConfigSchema = z.object({
|
|
107
99
|
/** Title for your website. Will be used in metadata and as browser tab title. */
|
|
108
100
|
title: z
|
|
@@ -202,7 +194,7 @@ const UserConfigSchema = z.object({
|
|
|
202
194
|
defaultLocale: z.string().optional(),
|
|
203
195
|
|
|
204
196
|
/** Configure your site’s sidebar navigation items. */
|
|
205
|
-
sidebar:
|
|
197
|
+
sidebar: SidebarItemSchema.array().optional(),
|
|
206
198
|
|
|
207
199
|
/**
|
|
208
200
|
* Add extra tags to your site’s `<head>`.
|