@casoon/pages-theme 0.0.0-stage → 0.12.8
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/LICENSE +21 -0
- package/README.md +279 -2
- package/assets/casoon-logo-dark.svg +70 -0
- package/assets/casoon-logo.svg +71 -0
- package/assets/favicon.svg +1 -0
- package/components/AnchorGrid.astro +135 -0
- package/components/ApiEntry.astro +136 -0
- package/components/Badge.astro +31 -0
- package/components/Badges.astro +10 -0
- package/components/BuildOutput.astro +84 -0
- package/components/Button.astro +55 -0
- package/components/CallToAction.astro +64 -0
- package/components/Callout.astro +66 -0
- package/components/CodeBlock.astro +84 -0
- package/components/Demo.astro +80 -0
- package/components/ExamplePanel.astro +153 -0
- package/components/Facts.astro +112 -0
- package/components/Faq.astro +123 -0
- package/components/Features.astro +139 -0
- package/components/FileSet.astro +258 -0
- package/components/Footer.astro +160 -0
- package/components/Header.astro +278 -0
- package/components/Hero.astro +318 -0
- package/components/Install.astro +154 -0
- package/components/Integrations.astro +125 -0
- package/components/Keymap.astro +102 -0
- package/components/Quickstart.astro +95 -0
- package/components/ReleaseHighlights.astro +115 -0
- package/components/Spotlight.astro +177 -0
- package/components/Swatch.astro +45 -0
- package/components/Tabs.astro +90 -0
- package/components/Terminal.astro +79 -0
- package/components/index.ts +25 -0
- package/content.ts +23 -0
- package/fonts/OFL.txt +95 -0
- package/fonts/inter-latin-400-normal.woff2 +0 -0
- package/fonts/inter-latin-500-normal.woff2 +0 -0
- package/fonts/inter-latin-600-normal.woff2 +0 -0
- package/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
- package/fonts/jetbrains-mono-latin-500-normal.woff2 +0 -0
- package/fonts/onest-latin-wght-normal.woff2 +0 -0
- package/index.ts +204 -0
- package/layouts/Base.astro +131 -0
- package/layouts/Docs.astro +286 -0
- package/lib/ansi.ts +168 -0
- package/lib/changelog.ts +85 -0
- package/lib/docs.ts +54 -0
- package/lib/i18n.ts +136 -0
- package/lib/og.ts +91 -0
- package/lib/showcase.ts +48 -0
- package/lib/url.ts +16 -0
- package/lib/version.ts +50 -0
- package/package.json +71 -4
- package/routes/404.astro +49 -0
- package/routes/changelog.astro +129 -0
- package/routes/docs/[...slug].astro +39 -0
- package/routes/showcase/[slug].astro +108 -0
- package/routes/showcase/index.astro +195 -0
- package/styles/base.css +307 -0
- package/styles/fonts.css +52 -0
- package/styles/tokens.css +136 -0
- package/virtual.d.ts +12 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
import config from 'virtual:casoon-pages/config';
|
|
3
|
+
import { t } from '../lib/i18n';
|
|
4
|
+
import { url } from '../lib/url';
|
|
5
|
+
import Button from './Button.astro';
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
/** Steps; inline HTML allowed (e.g. <code>). */
|
|
9
|
+
steps: string[];
|
|
10
|
+
lead?: string;
|
|
11
|
+
title?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const s = t(config.lang);
|
|
15
|
+
const { steps, lead = s.quickstartLead, title = s.quickstartTitle } = Astro.props;
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
<section class="quickstart">
|
|
19
|
+
<div>
|
|
20
|
+
<h2>{title}</h2>
|
|
21
|
+
<p class="lead">{lead}</p>
|
|
22
|
+
<ol>
|
|
23
|
+
{
|
|
24
|
+
steps.map((step, i) => (
|
|
25
|
+
<li>
|
|
26
|
+
<span class="n" aria-hidden="true">
|
|
27
|
+
{String(i + 1).padStart(2, '0')}
|
|
28
|
+
</span>
|
|
29
|
+
<span set:html={step} />
|
|
30
|
+
</li>
|
|
31
|
+
))
|
|
32
|
+
}
|
|
33
|
+
</ol>
|
|
34
|
+
<div class="cta"><Button href={url('docs/')}>{s.readDocs}</Button></div>
|
|
35
|
+
</div>
|
|
36
|
+
<div class="code"><slot /></div>
|
|
37
|
+
</section>
|
|
38
|
+
|
|
39
|
+
<style>
|
|
40
|
+
.quickstart {
|
|
41
|
+
display: grid;
|
|
42
|
+
grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
|
|
43
|
+
gap: 48px;
|
|
44
|
+
align-items: start;
|
|
45
|
+
max-width: var(--max);
|
|
46
|
+
margin: 0 auto;
|
|
47
|
+
padding: 0 24px 96px;
|
|
48
|
+
}
|
|
49
|
+
h2 {
|
|
50
|
+
margin: 0 0 14px;
|
|
51
|
+
color: var(--heading);
|
|
52
|
+
font-size: 30px;
|
|
53
|
+
font-weight: 600;
|
|
54
|
+
letter-spacing: -0.02em;
|
|
55
|
+
}
|
|
56
|
+
.lead {
|
|
57
|
+
margin: 0 0 24px;
|
|
58
|
+
font-size: 15.5px;
|
|
59
|
+
}
|
|
60
|
+
ol {
|
|
61
|
+
display: flex;
|
|
62
|
+
flex-direction: column;
|
|
63
|
+
gap: 14px;
|
|
64
|
+
margin: 0;
|
|
65
|
+
padding: 0;
|
|
66
|
+
list-style: none;
|
|
67
|
+
}
|
|
68
|
+
li {
|
|
69
|
+
display: flex;
|
|
70
|
+
gap: 12px;
|
|
71
|
+
font-size: 14.5px;
|
|
72
|
+
}
|
|
73
|
+
.n {
|
|
74
|
+
padding-top: 2px;
|
|
75
|
+
color: var(--muted);
|
|
76
|
+
font-family: var(--font-mono);
|
|
77
|
+
font-size: 12.5px;
|
|
78
|
+
}
|
|
79
|
+
li :global(code) {
|
|
80
|
+
padding: 1px 5px;
|
|
81
|
+
border-radius: 5px;
|
|
82
|
+
background: var(--code-bg);
|
|
83
|
+
font-size: 13px;
|
|
84
|
+
}
|
|
85
|
+
.cta {
|
|
86
|
+
margin-top: 28px;
|
|
87
|
+
}
|
|
88
|
+
/* Projects often show several code blocks here (e.g. Rust and Node). */
|
|
89
|
+
.code {
|
|
90
|
+
display: flex;
|
|
91
|
+
flex-direction: column;
|
|
92
|
+
gap: 16px;
|
|
93
|
+
min-width: 0;
|
|
94
|
+
}
|
|
95
|
+
</style>
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* Teaser of one release's changes on the start page, from the same `Release` the changelog
|
|
4
|
+
* route renders — parse CHANGELOG.md once with `parseChangelog`. Pass the first release whose
|
|
5
|
+
* version isn't "Unreleased" (`releases.find((r) => r.version.toLowerCase() !== 'unreleased')`),
|
|
6
|
+
* not `releases[0]`: an `## [Unreleased]` section with entries already in it would otherwise
|
|
7
|
+
* show up here as "New in vUnreleased". Never maintained twice: the entry text is the
|
|
8
|
+
* changelog entry.
|
|
9
|
+
*/
|
|
10
|
+
import config from 'virtual:casoon-pages/config';
|
|
11
|
+
import type { Release } from '../lib/changelog';
|
|
12
|
+
import { t } from '../lib/i18n';
|
|
13
|
+
import { url } from '../lib/url';
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
release: Release;
|
|
17
|
+
heading?: string;
|
|
18
|
+
/** Cap on how many of the release's entries to show. Default 6. */
|
|
19
|
+
max?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const s = t(config.lang);
|
|
23
|
+
const { release, heading = s.newIn(release.version), max = 6 } = Astro.props;
|
|
24
|
+
const tone = (kind: string) =>
|
|
25
|
+
['breaking', 'removed', 'security'].includes(kind)
|
|
26
|
+
? 'brand'
|
|
27
|
+
: kind === 'fixed'
|
|
28
|
+
? 'accent'
|
|
29
|
+
: 'muted';
|
|
30
|
+
const changes = release.changes.slice(0, max);
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
<section class="release-highlights">
|
|
34
|
+
<div class="head">
|
|
35
|
+
<h2 class="cp-label">{heading}</h2>
|
|
36
|
+
{config.changelog && <a href={url('changelog/')}>{s.changelog} →</a>}
|
|
37
|
+
</div>
|
|
38
|
+
<ul>
|
|
39
|
+
{
|
|
40
|
+
changes.map((change) => (
|
|
41
|
+
<li>
|
|
42
|
+
<span class:list={['dot', tone(change.kind)]} aria-hidden="true" />
|
|
43
|
+
<span set:html={change.html} />
|
|
44
|
+
</li>
|
|
45
|
+
))
|
|
46
|
+
}
|
|
47
|
+
</ul>
|
|
48
|
+
</section>
|
|
49
|
+
|
|
50
|
+
<style>
|
|
51
|
+
.release-highlights {
|
|
52
|
+
max-width: var(--max);
|
|
53
|
+
margin: 0 auto;
|
|
54
|
+
padding: 0 24px 80px;
|
|
55
|
+
}
|
|
56
|
+
.head {
|
|
57
|
+
display: flex;
|
|
58
|
+
align-items: baseline;
|
|
59
|
+
justify-content: space-between;
|
|
60
|
+
gap: 16px;
|
|
61
|
+
margin-bottom: 20px;
|
|
62
|
+
}
|
|
63
|
+
.head h2 {
|
|
64
|
+
margin: 0;
|
|
65
|
+
}
|
|
66
|
+
.head a {
|
|
67
|
+
font-size: 14px;
|
|
68
|
+
}
|
|
69
|
+
ul {
|
|
70
|
+
display: grid;
|
|
71
|
+
grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
|
|
72
|
+
gap: 20px 40px;
|
|
73
|
+
margin: 0;
|
|
74
|
+
padding: 0;
|
|
75
|
+
list-style: none;
|
|
76
|
+
}
|
|
77
|
+
li {
|
|
78
|
+
display: flex;
|
|
79
|
+
gap: 12px;
|
|
80
|
+
padding-top: 18px;
|
|
81
|
+
border-top: 1px solid var(--border);
|
|
82
|
+
font-size: 14.5px;
|
|
83
|
+
line-height: 1.55;
|
|
84
|
+
}
|
|
85
|
+
.dot {
|
|
86
|
+
flex-shrink: 0;
|
|
87
|
+
width: 7px;
|
|
88
|
+
height: 7px;
|
|
89
|
+
margin-top: 7px;
|
|
90
|
+
border-radius: 50%;
|
|
91
|
+
}
|
|
92
|
+
.dot.muted {
|
|
93
|
+
background: var(--muted);
|
|
94
|
+
}
|
|
95
|
+
.dot.accent {
|
|
96
|
+
background: var(--accent);
|
|
97
|
+
}
|
|
98
|
+
.dot.brand {
|
|
99
|
+
background: var(--brand);
|
|
100
|
+
}
|
|
101
|
+
li :global(strong) {
|
|
102
|
+
color: var(--heading);
|
|
103
|
+
}
|
|
104
|
+
li :global(code) {
|
|
105
|
+
padding: 1px 5px;
|
|
106
|
+
border-radius: 5px;
|
|
107
|
+
background: var(--code-bg);
|
|
108
|
+
font-size: 0.9em;
|
|
109
|
+
}
|
|
110
|
+
li :global(a) {
|
|
111
|
+
text-decoration: underline;
|
|
112
|
+
text-underline-offset: 2px;
|
|
113
|
+
text-decoration-thickness: 1px;
|
|
114
|
+
}
|
|
115
|
+
</style>
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* A repeatable two-column feature section further down the page (unlike `Hero`, which is
|
|
4
|
+
* singular): eyebrow, title, lead, an optional bullet list and link row, beside a `media` slot
|
|
5
|
+
* (a `Terminal`, `CodeBlock`, screenshot — whatever shows the feature). `reverse` swaps sides,
|
|
6
|
+
* for alternating sections down a page. `lead` and `points` accept the changelog's inline
|
|
7
|
+
* Markdown subset (`` `code` ``, `**bold**`, `[text](url)`), reused rather than re-parsed.
|
|
8
|
+
*/
|
|
9
|
+
import { inlineMarkdown } from '../lib/changelog';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
eyebrow?: string;
|
|
13
|
+
title: string;
|
|
14
|
+
lead: string;
|
|
15
|
+
points?: string[];
|
|
16
|
+
links?: { label: string; href: string }[];
|
|
17
|
+
reverse?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const { eyebrow, title, lead, points, links, reverse = false } = Astro.props;
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
<section class:list={['spotlight', reverse && 'reverse']}>
|
|
24
|
+
<div class="text">
|
|
25
|
+
{eyebrow && <p class="eyebrow">{eyebrow}</p>}
|
|
26
|
+
<h2>{title}</h2>
|
|
27
|
+
<p class="lead" set:html={inlineMarkdown(lead)} />
|
|
28
|
+
{
|
|
29
|
+
points && points.length > 0 && (
|
|
30
|
+
<ul class="points">
|
|
31
|
+
{points.map((point) => (
|
|
32
|
+
<li set:html={inlineMarkdown(point)} />
|
|
33
|
+
))}
|
|
34
|
+
</ul>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
{
|
|
38
|
+
links && links.length > 0 && (
|
|
39
|
+
<div class="links">
|
|
40
|
+
{links.map((link) => (
|
|
41
|
+
<a href={link.href}>{link.label} →</a>
|
|
42
|
+
))}
|
|
43
|
+
</div>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
</div>
|
|
47
|
+
<div class="media">
|
|
48
|
+
<slot />
|
|
49
|
+
</div>
|
|
50
|
+
</section>
|
|
51
|
+
|
|
52
|
+
<style>
|
|
53
|
+
/* Large rounded sand panel for a demo or dashboard. */
|
|
54
|
+
.spotlight {
|
|
55
|
+
display: grid;
|
|
56
|
+
gap: 44px;
|
|
57
|
+
align-items: center;
|
|
58
|
+
max-width: calc(var(--max) + 160px);
|
|
59
|
+
margin: 0 auto 80px;
|
|
60
|
+
padding: 80px;
|
|
61
|
+
border-radius: var(--r-panel);
|
|
62
|
+
background: var(--bg-deep);
|
|
63
|
+
}
|
|
64
|
+
@media (max-width: 900px) {
|
|
65
|
+
.spotlight {
|
|
66
|
+
margin-inline: 8px;
|
|
67
|
+
padding: 56px 24px;
|
|
68
|
+
border-radius: 32px;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
@media (min-width: 900px) {
|
|
72
|
+
.spotlight {
|
|
73
|
+
grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
|
|
74
|
+
gap: 56px;
|
|
75
|
+
}
|
|
76
|
+
.spotlight.reverse {
|
|
77
|
+
grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
|
|
78
|
+
}
|
|
79
|
+
.spotlight.reverse .text {
|
|
80
|
+
order: 1;
|
|
81
|
+
}
|
|
82
|
+
.spotlight.reverse .media {
|
|
83
|
+
order: 2;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
.eyebrow {
|
|
87
|
+
display: flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
gap: 8px;
|
|
90
|
+
margin: 0 0 16px;
|
|
91
|
+
color: var(--heading);
|
|
92
|
+
font-size: 14px;
|
|
93
|
+
text-transform: uppercase;
|
|
94
|
+
}
|
|
95
|
+
.eyebrow::before {
|
|
96
|
+
content: '';
|
|
97
|
+
width: 6px;
|
|
98
|
+
height: 6px;
|
|
99
|
+
border-radius: 50%;
|
|
100
|
+
background: var(--accent-fill);
|
|
101
|
+
}
|
|
102
|
+
h2 {
|
|
103
|
+
margin: 0 0 20px;
|
|
104
|
+
color: var(--heading);
|
|
105
|
+
font-size: clamp(32px, 4vw, 50px);
|
|
106
|
+
font-weight: 600;
|
|
107
|
+
letter-spacing: -0.02em;
|
|
108
|
+
line-height: 1.1;
|
|
109
|
+
}
|
|
110
|
+
.lead {
|
|
111
|
+
margin: 0;
|
|
112
|
+
font-size: 18px;
|
|
113
|
+
line-height: 1.65;
|
|
114
|
+
}
|
|
115
|
+
.lead :global(strong) {
|
|
116
|
+
color: var(--heading);
|
|
117
|
+
}
|
|
118
|
+
.lead :global(code) {
|
|
119
|
+
padding: 1px 5px;
|
|
120
|
+
border-radius: 5px;
|
|
121
|
+
background: var(--code-bg);
|
|
122
|
+
font-size: 0.9em;
|
|
123
|
+
}
|
|
124
|
+
.lead :global(a),
|
|
125
|
+
.points :global(a) {
|
|
126
|
+
text-decoration: underline;
|
|
127
|
+
text-underline-offset: 2px;
|
|
128
|
+
text-decoration-thickness: 1px;
|
|
129
|
+
}
|
|
130
|
+
.points {
|
|
131
|
+
margin: 22px 0 0;
|
|
132
|
+
padding: 0;
|
|
133
|
+
list-style: none;
|
|
134
|
+
}
|
|
135
|
+
.points li {
|
|
136
|
+
position: relative;
|
|
137
|
+
padding-left: 32px;
|
|
138
|
+
margin-bottom: 14px;
|
|
139
|
+
font-size: 16px;
|
|
140
|
+
line-height: 1.6;
|
|
141
|
+
}
|
|
142
|
+
.points li::before {
|
|
143
|
+
content: '✓';
|
|
144
|
+
position: absolute;
|
|
145
|
+
top: 2px;
|
|
146
|
+
left: 0;
|
|
147
|
+
display: grid;
|
|
148
|
+
place-items: center;
|
|
149
|
+
width: 21px;
|
|
150
|
+
height: 21px;
|
|
151
|
+
border-radius: 50%;
|
|
152
|
+
background: var(--surface);
|
|
153
|
+
color: var(--heading);
|
|
154
|
+
font-size: 12px;
|
|
155
|
+
font-weight: 700;
|
|
156
|
+
}
|
|
157
|
+
.points :global(strong) {
|
|
158
|
+
color: var(--heading);
|
|
159
|
+
}
|
|
160
|
+
.links {
|
|
161
|
+
display: flex;
|
|
162
|
+
flex-wrap: wrap;
|
|
163
|
+
gap: 18px 26px;
|
|
164
|
+
margin-top: 24px;
|
|
165
|
+
}
|
|
166
|
+
.links a {
|
|
167
|
+
color: var(--heading);
|
|
168
|
+
font-weight: 600;
|
|
169
|
+
font-size: 14.5px;
|
|
170
|
+
}
|
|
171
|
+
.links a:hover {
|
|
172
|
+
color: var(--accent);
|
|
173
|
+
}
|
|
174
|
+
.media {
|
|
175
|
+
min-width: 0;
|
|
176
|
+
}
|
|
177
|
+
</style>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
/** Colour token preview for design documentation. */
|
|
3
|
+
import config from 'virtual:casoon-pages/config';
|
|
4
|
+
import { t } from '../lib/i18n';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
token: string;
|
|
8
|
+
value?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const { token, value = t(config.lang).themeDependent } = Astro.props;
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
<div class="swatch">
|
|
15
|
+
<div class="chip" style={`background: var(${token})`}></div>
|
|
16
|
+
<p class="token">{token}</p>
|
|
17
|
+
<p class="value">{value}</p>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<style>
|
|
21
|
+
.swatch {
|
|
22
|
+
overflow: hidden;
|
|
23
|
+
border: 1px solid var(--border);
|
|
24
|
+
border-radius: 12px;
|
|
25
|
+
background: var(--surface);
|
|
26
|
+
}
|
|
27
|
+
.chip {
|
|
28
|
+
height: 56px;
|
|
29
|
+
border-bottom: 1px solid var(--border);
|
|
30
|
+
}
|
|
31
|
+
p {
|
|
32
|
+
margin: 0 !important;
|
|
33
|
+
padding: 0 12px;
|
|
34
|
+
font-family: var(--font-mono);
|
|
35
|
+
font-size: 12px;
|
|
36
|
+
}
|
|
37
|
+
.token {
|
|
38
|
+
padding-top: 10px;
|
|
39
|
+
color: var(--heading);
|
|
40
|
+
}
|
|
41
|
+
.value {
|
|
42
|
+
padding-bottom: 10px;
|
|
43
|
+
color: var(--muted);
|
|
44
|
+
}
|
|
45
|
+
</style>
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* CSS-only tabs (e.g. Rust / Node / CLI). One named slot per tab id:
|
|
4
|
+
* <Tabs tabs={[{ id: 'rust', label: 'Rust' }]}><div slot="rust">…</div></Tabs>
|
|
5
|
+
*/
|
|
6
|
+
import config from 'virtual:casoon-pages/config';
|
|
7
|
+
import { t } from '../lib/i18n';
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
tabs: { id: string; label: string }[];
|
|
11
|
+
label?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const { tabs, label = t(config.lang).tabsLabel } = Astro.props;
|
|
15
|
+
const uid = `tabs-${tabs.map((t) => t.id).join('-')}`;
|
|
16
|
+
const panels = await Promise.all(tabs.map((t) => Astro.slots.render(t.id)));
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
<div class="tabs">
|
|
20
|
+
<div class="list" role="radiogroup" aria-label={label}>
|
|
21
|
+
{
|
|
22
|
+
tabs.map((t, i) => (
|
|
23
|
+
<>
|
|
24
|
+
<input
|
|
25
|
+
class="visually-hidden"
|
|
26
|
+
type="radio"
|
|
27
|
+
name={uid}
|
|
28
|
+
id={`${uid}-${i}`}
|
|
29
|
+
value={i}
|
|
30
|
+
checked={i === 0}
|
|
31
|
+
/>
|
|
32
|
+
<label for={`${uid}-${i}`}>{t.label}</label>
|
|
33
|
+
</>
|
|
34
|
+
))
|
|
35
|
+
}
|
|
36
|
+
</div>
|
|
37
|
+
{panels.map((html, i) => <div class="panel" data-i={i} set:html={html} />)}
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<style>
|
|
41
|
+
.list {
|
|
42
|
+
display: flex;
|
|
43
|
+
gap: 2px;
|
|
44
|
+
border-bottom: 1px solid var(--border);
|
|
45
|
+
}
|
|
46
|
+
label {
|
|
47
|
+
margin-bottom: -1px;
|
|
48
|
+
padding: 9px 14px;
|
|
49
|
+
border-bottom: 2px solid transparent;
|
|
50
|
+
color: var(--muted);
|
|
51
|
+
font-size: 14px;
|
|
52
|
+
cursor: pointer;
|
|
53
|
+
}
|
|
54
|
+
input:checked + label {
|
|
55
|
+
border-bottom-color: var(--accent);
|
|
56
|
+
color: var(--heading);
|
|
57
|
+
}
|
|
58
|
+
input:focus-visible + label {
|
|
59
|
+
outline: 2px solid var(--accent);
|
|
60
|
+
outline-offset: -2px;
|
|
61
|
+
}
|
|
62
|
+
.panel {
|
|
63
|
+
display: none;
|
|
64
|
+
padding: 18px;
|
|
65
|
+
border: 1px solid var(--border);
|
|
66
|
+
border-top: 0;
|
|
67
|
+
border-radius: 0 0 12px 12px;
|
|
68
|
+
background: var(--code-bg);
|
|
69
|
+
}
|
|
70
|
+
.panel[data-i='0'],
|
|
71
|
+
.tabs:has(> .list input[value='1']:checked) > .panel[data-i='1'],
|
|
72
|
+
.tabs:has(> .list input[value='2']:checked) > .panel[data-i='2'],
|
|
73
|
+
.tabs:has(> .list input[value='3']:checked) > .panel[data-i='3'],
|
|
74
|
+
.tabs:has(> .list input[value='4']:checked) > .panel[data-i='4'],
|
|
75
|
+
.tabs:has(> .list input[value='5']:checked) > .panel[data-i='5'] {
|
|
76
|
+
display: block;
|
|
77
|
+
}
|
|
78
|
+
.tabs:has(> .list input:not([value='0']):checked) > .panel[data-i='0'] {
|
|
79
|
+
display: none;
|
|
80
|
+
}
|
|
81
|
+
.panel :global(pre.astro-code) {
|
|
82
|
+
padding: 0;
|
|
83
|
+
border: 0;
|
|
84
|
+
background: none !important;
|
|
85
|
+
font-size: 13.5px;
|
|
86
|
+
}
|
|
87
|
+
.panel :global(> :last-child) {
|
|
88
|
+
margin-bottom: 0;
|
|
89
|
+
}
|
|
90
|
+
</style>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* Terminal window. Pass raw ANSI via `ansi` (converted at build time), or
|
|
4
|
+
* pre-rendered HTML from the project's own renderer as slot content.
|
|
5
|
+
*/
|
|
6
|
+
import { ansiToHtml } from '../lib/ansi';
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
ansi?: string;
|
|
10
|
+
/** Command or shell name shown in the title bar. */
|
|
11
|
+
title?: string;
|
|
12
|
+
/** Window dots in the title bar. */
|
|
13
|
+
dots?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const { ansi, title, dots = false } = Astro.props;
|
|
17
|
+
const html = ansi !== undefined ? ansiToHtml(ansi) : await Astro.slots.render('default');
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
<figure class="terminal">
|
|
21
|
+
{
|
|
22
|
+
title && (
|
|
23
|
+
<figcaption>
|
|
24
|
+
{dots && (
|
|
25
|
+
<span class="dots" aria-hidden="true">
|
|
26
|
+
<i />
|
|
27
|
+
<i />
|
|
28
|
+
<i />
|
|
29
|
+
</span>
|
|
30
|
+
)}
|
|
31
|
+
{title}
|
|
32
|
+
</figcaption>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
<pre tabindex="0" set:html={html} />
|
|
36
|
+
</figure>
|
|
37
|
+
|
|
38
|
+
<style>
|
|
39
|
+
.terminal {
|
|
40
|
+
overflow: hidden;
|
|
41
|
+
border: 1px solid var(--border);
|
|
42
|
+
border-radius: 14px;
|
|
43
|
+
background: var(--term-bg);
|
|
44
|
+
color: var(--term-text);
|
|
45
|
+
}
|
|
46
|
+
figcaption {
|
|
47
|
+
display: flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
gap: 14px;
|
|
50
|
+
padding: 10px 16px;
|
|
51
|
+
border-bottom: 1px solid var(--term-border);
|
|
52
|
+
color: var(--term-dim);
|
|
53
|
+
font-family: var(--font-mono);
|
|
54
|
+
font-size: 12px;
|
|
55
|
+
}
|
|
56
|
+
.dots {
|
|
57
|
+
display: flex;
|
|
58
|
+
gap: 7px;
|
|
59
|
+
}
|
|
60
|
+
.dots i {
|
|
61
|
+
width: 10px;
|
|
62
|
+
height: 10px;
|
|
63
|
+
border-radius: 50%;
|
|
64
|
+
background: #ff5f57;
|
|
65
|
+
}
|
|
66
|
+
.dots i:nth-child(2) {
|
|
67
|
+
background: #febc2e;
|
|
68
|
+
}
|
|
69
|
+
.dots i:nth-child(3) {
|
|
70
|
+
background: #28c840;
|
|
71
|
+
}
|
|
72
|
+
pre {
|
|
73
|
+
margin: 0;
|
|
74
|
+
padding: 18px;
|
|
75
|
+
overflow: auto;
|
|
76
|
+
font-size: 12.5px;
|
|
77
|
+
line-height: 1.85;
|
|
78
|
+
}
|
|
79
|
+
</style>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export { default as AnchorGrid } from './AnchorGrid.astro';
|
|
2
|
+
export { default as ApiEntry } from './ApiEntry.astro';
|
|
3
|
+
export { default as Badge } from './Badge.astro';
|
|
4
|
+
export { default as Badges } from './Badges.astro';
|
|
5
|
+
export { default as BuildOutput } from './BuildOutput.astro';
|
|
6
|
+
export { default as Button } from './Button.astro';
|
|
7
|
+
export { default as Callout } from './Callout.astro';
|
|
8
|
+
export { default as CallToAction } from './CallToAction.astro';
|
|
9
|
+
export { default as CodeBlock } from './CodeBlock.astro';
|
|
10
|
+
export { default as Demo } from './Demo.astro';
|
|
11
|
+
export { default as ExamplePanel } from './ExamplePanel.astro';
|
|
12
|
+
export { default as Facts } from './Facts.astro';
|
|
13
|
+
export { default as Faq } from './Faq.astro';
|
|
14
|
+
export { default as Features } from './Features.astro';
|
|
15
|
+
export { default as FileSet } from './FileSet.astro';
|
|
16
|
+
export { default as Hero } from './Hero.astro';
|
|
17
|
+
export { default as Install } from './Install.astro';
|
|
18
|
+
export { default as Integrations } from './Integrations.astro';
|
|
19
|
+
export { default as Keymap } from './Keymap.astro';
|
|
20
|
+
export { default as Quickstart } from './Quickstart.astro';
|
|
21
|
+
export { default as ReleaseHighlights } from './ReleaseHighlights.astro';
|
|
22
|
+
export { default as Spotlight } from './Spotlight.astro';
|
|
23
|
+
export { default as Swatch } from './Swatch.astro';
|
|
24
|
+
export { default as Tabs } from './Tabs.astro';
|
|
25
|
+
export { default as Terminal } from './Terminal.astro';
|
package/content.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defineCollection } from 'astro:content';
|
|
2
|
+
import { glob } from 'astro/loaders';
|
|
3
|
+
import { z } from 'astro/zod';
|
|
4
|
+
|
|
5
|
+
export const docsSchema = z.object({
|
|
6
|
+
title: z.string(),
|
|
7
|
+
description: z.string().optional(),
|
|
8
|
+
/** Position inside its sidebar group; lower comes first. */
|
|
9
|
+
order: z.number().default(100),
|
|
10
|
+
/** Label in the sidebar, if shorter than the title. */
|
|
11
|
+
sidebarLabel: z.string().optional(),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The `docs` collection. Sources live in the project repository's docs/ folder,
|
|
16
|
+
* next to site/, so documentation is versioned and reviewed with the code.
|
|
17
|
+
*/
|
|
18
|
+
export function docsCollection({ base = '../docs' }: { base?: string } = {}) {
|
|
19
|
+
return defineCollection({
|
|
20
|
+
loader: glob({ pattern: '**/*.{md,mdx}', base }),
|
|
21
|
+
schema: docsSchema,
|
|
22
|
+
});
|
|
23
|
+
}
|