stropress 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +307 -0
- package/dist/theme-default/package.json +20 -0
- package/dist/theme-default/postcss.config.mjs +5 -0
- package/dist/theme-default/src/components/BaseHead.astro +53 -0
- package/dist/theme-default/src/components/DocToc.astro +111 -0
- package/dist/theme-default/src/components/GithubIcon.astro +35 -0
- package/dist/theme-default/src/components/HomePage.astro +198 -0
- package/dist/theme-default/src/components/Icon.astro +78 -0
- package/dist/theme-default/src/components/LocaleSelect.astro +187 -0
- package/dist/theme-default/src/components/NavBar.astro +231 -0
- package/dist/theme-default/src/components/SearchInput.astro +84 -0
- package/dist/theme-default/src/components/SearchModal.astro +209 -0
- package/dist/theme-default/src/components/Sidebar.astro +101 -0
- package/dist/theme-default/src/content/docs/guide/configuration.mdx +195 -0
- package/dist/theme-default/src/content/docs/guide/getting-started.md +98 -0
- package/dist/theme-default/src/content/docs/guide/search.mdx +41 -0
- package/dist/theme-default/src/content/docs/index.css +0 -0
- package/dist/theme-default/src/content/docs/index.md +6 -0
- package/dist/theme-default/src/content/docs/zh/guide/configuration.mdx +149 -0
- package/dist/theme-default/src/content/docs/zh/guide/getting-started.md +31 -0
- package/dist/theme-default/src/content/docs/zh/guide/search.mdx +23 -0
- package/dist/theme-default/src/content/docs/zh/index.astro +75 -0
- package/dist/theme-default/src/content/docs/zh/index.md +6 -0
- package/dist/theme-default/src/content.config.ts +14 -0
- package/dist/theme-default/src/env.d.ts +15 -0
- package/dist/theme-default/src/layouts/DocsLayout.astro +278 -0
- package/dist/theme-default/src/lib/config.ts +195 -0
- package/dist/theme-default/src/lib/custom-home.ts +40 -0
- package/dist/theme-default/src/lib/custom-style.ts +11 -0
- package/dist/theme-default/src/lib/og.ts +275 -0
- package/dist/theme-default/src/pages/[...slug]/index.astro +83 -0
- package/dist/theme-default/src/pages/index.astro +47 -0
- package/dist/theme-default/src/pages/og/[...slug].png.ts +70 -0
- package/dist/theme-default/src/scripts/code-copy.ts +54 -0
- package/dist/theme-default/src/scripts/doc-toc.ts +109 -0
- package/dist/theme-default/src/scripts/search.ts +329 -0
- package/dist/theme-default/src/styles/global.css +70 -0
- package/dist/theme-default/src/styles/markdown.css +141 -0
- package/dist/theme-default/tsconfig.json +10 -0
- package/package.json +32 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Search
|
|
3
|
+
description: Configure and use search in your Stropress documentation site
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Search
|
|
7
|
+
|
|
8
|
+
Stropress has built-in search that works out of the box — no configuration required.
|
|
9
|
+
Search is powered by local MiniSearch.
|
|
10
|
+
|
|
11
|
+
## How it works
|
|
12
|
+
|
|
13
|
+
A search button is displayed in the header. Clicking it opens a modal where you can type to find pages across your docs.
|
|
14
|
+
|
|
15
|
+
**Keyboard shortcuts**
|
|
16
|
+
|
|
17
|
+
| Key | Action |
|
|
18
|
+
| :-------------- | :------------------- |
|
|
19
|
+
| `⌘K` / `Ctrl K` | Open search |
|
|
20
|
+
| `↑` / `↓` | Navigate results |
|
|
21
|
+
| `Enter` | Open selected result |
|
|
22
|
+
| `Esc` | Close search |
|
|
23
|
+
|
|
24
|
+
## Local search (default)
|
|
25
|
+
|
|
26
|
+
By default, Stropress indexes all your `.md` and `.mdx` pages at build time using [MiniSearch](https://lucaong.github.io/minisearch/).
|
|
27
|
+
No extra setup is needed.
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"search": {
|
|
32
|
+
"provider": "local"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The `provider: "local"` line is optional — local search is enabled even without a `search` field.
|
|
38
|
+
|
|
39
|
+
## Notes
|
|
40
|
+
|
|
41
|
+
Search indexes your markdown content and runs fully on the client.
|
|
File without changes
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 配置
|
|
3
|
+
description: 配置导航、侧边栏和双语
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 配置
|
|
7
|
+
|
|
8
|
+
使用 `docs/config.json` 配置站点信息与导航结构。
|
|
9
|
+
|
|
10
|
+
- `navbar`:顶部导航
|
|
11
|
+
- `nav`:显示在社交链接旁边的主导航
|
|
12
|
+
- `sidebar`:侧边栏分组
|
|
13
|
+
- `search`:本地搜索选项
|
|
14
|
+
- `markdown`:Markdown 渲染选项
|
|
15
|
+
- `locales`:多语言配置
|
|
16
|
+
|
|
17
|
+
## 搜索
|
|
18
|
+
|
|
19
|
+
默认搜索使用内置 MiniSearch,无需额外依赖。
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"search": {
|
|
24
|
+
"provider": "local"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 代码块主题
|
|
30
|
+
|
|
31
|
+
你可以在 `docs/config.json` 中通过 `markdown.codeTheme` 配置代码块高亮主题。
|
|
32
|
+
|
|
33
|
+
使用单一主题:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"markdown": {
|
|
38
|
+
"codeTheme": "github-dark"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
或分别配置亮色/暗色主题:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"markdown": {
|
|
48
|
+
"codeTheme": {
|
|
49
|
+
"light": "github-light",
|
|
50
|
+
"dark": "github-dark"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
常见主题名(由 Astro 通过 Shiki 提供,具体可用性取决于 Astro/Shiki 版本):
|
|
57
|
+
|
|
58
|
+
- `github-light`
|
|
59
|
+
- `github-dark`
|
|
60
|
+
- `one-dark-pro`
|
|
61
|
+
- `dracula`
|
|
62
|
+
- `nord`
|
|
63
|
+
- `material-theme-darker`
|
|
64
|
+
- `catppuccin-latte`
|
|
65
|
+
- `catppuccin-frappe`
|
|
66
|
+
- `catppuccin-macchiato`
|
|
67
|
+
- `catppuccin-mocha`
|
|
68
|
+
|
|
69
|
+
One Dark + Catppuccin 示例:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"markdown": {
|
|
74
|
+
"codeTheme": {
|
|
75
|
+
"light": "catppuccin-latte",
|
|
76
|
+
"dark": "one-dark-pro"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
如果主题名在当前版本不可用,`dev/build` 会提示主题加载错误。
|
|
83
|
+
|
|
84
|
+
## 双语配置
|
|
85
|
+
|
|
86
|
+
推荐将中文文档放在 `docs/zh/...` 目录下,并在 `locales` 中配置 `/zh/`:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"locales": {
|
|
91
|
+
"/": {
|
|
92
|
+
"label": "English",
|
|
93
|
+
"lang": "en-US"
|
|
94
|
+
},
|
|
95
|
+
"/zh/": {
|
|
96
|
+
"label": "简体中文",
|
|
97
|
+
"lang": "zh-CN"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## 自定义首页
|
|
104
|
+
|
|
105
|
+
如果 `config.json` 里的 `home` 配置不够灵活,可以直接在 `config.json` 同目录放置 Astro 首页文件:
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
docs/
|
|
109
|
+
config.json
|
|
110
|
+
index.astro
|
|
111
|
+
zh/
|
|
112
|
+
index.astro
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
- `docs/index.astro` 会覆盖根路径 `/` 的首页。
|
|
116
|
+
- `docs/zh/index.astro` 会覆盖 `/zh/` 的多语言首页。
|
|
117
|
+
- 只要存在匹配的 `index.astro`,Stropress 就会优先使用它,而不是 `home` 或 `locales[locale].home`。
|
|
118
|
+
|
|
119
|
+
这些文件会渲染在默认文档布局内部。你也可以在 Astro frontmatter 中导出一些可选元信息:
|
|
120
|
+
|
|
121
|
+
```astro
|
|
122
|
+
---
|
|
123
|
+
export const title = "自定义首页";
|
|
124
|
+
export const description = "使用 Astro 编写的首页";
|
|
125
|
+
export const sidebar = false;
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
<section>
|
|
129
|
+
<h1>自定义首页</h1>
|
|
130
|
+
</section>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## 全局样式覆盖
|
|
134
|
+
|
|
135
|
+
你可以在根目录增加 `docs/index.css`,用来全局覆盖默认主题样式。
|
|
136
|
+
|
|
137
|
+
这份文件会在内置主题 CSS 之后加载,因此适合用来重写 `:root` 变量,或者覆盖主题里的选择器。
|
|
138
|
+
|
|
139
|
+
```css
|
|
140
|
+
:root {
|
|
141
|
+
--background-color: 250 247 240;
|
|
142
|
+
--foreground-color: 28 28 28;
|
|
143
|
+
--primary-color: 176 78 44;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.topbar {
|
|
147
|
+
backdrop-filter: blur(20px);
|
|
148
|
+
}
|
|
149
|
+
```
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 快速开始
|
|
3
|
+
description: 快速启动你的文档站点
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 快速开始
|
|
7
|
+
|
|
8
|
+
`docs/` 目录下的 Markdown 文件会被渲染为静态页面。
|
|
9
|
+
|
|
10
|
+
## 运行开发环境
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bun run dev --dir=docs
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## 构建生产版本
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
bun run build --dir=docs
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## 目录建议
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
docs/
|
|
26
|
+
config.json
|
|
27
|
+
index.md
|
|
28
|
+
guide/
|
|
29
|
+
getting-started.md
|
|
30
|
+
configuration.mdx
|
|
31
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 搜索
|
|
3
|
+
description: 配置与使用站点搜索
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 搜索
|
|
7
|
+
|
|
8
|
+
Stropress 内置本地搜索,开箱即用。
|
|
9
|
+
|
|
10
|
+
## 使用方式
|
|
11
|
+
|
|
12
|
+
在 Header 点击搜索按钮,输入关键词即可检索文档内容。
|
|
13
|
+
|
|
14
|
+
快捷键:
|
|
15
|
+
|
|
16
|
+
- `⌘K` / `Ctrl K`:打开搜索
|
|
17
|
+
- `↑` / `↓`:切换结果
|
|
18
|
+
- `Enter`:打开结果
|
|
19
|
+
- `Esc`:关闭弹窗
|
|
20
|
+
|
|
21
|
+
## 说明
|
|
22
|
+
|
|
23
|
+
搜索会索引当前语言下的文档内容,并在前端完成查询。
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
export const title = "自定义首页";
|
|
3
|
+
export const description = "用于验证 docs/zh/index.astro 是否生效的示例首页";
|
|
4
|
+
export const sidebar = false;
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<section class="custom-home">
|
|
8
|
+
<p class="eyebrow">Custom Astro Home</p>
|
|
9
|
+
<h1>这是 docs/zh/index.astro</h1>
|
|
10
|
+
<p class="lead">
|
|
11
|
+
如果你现在访问 <code>/zh/</code
|
|
12
|
+
>,看到的是这块内容,就说明多语言自定义首页已经生效。
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<div class="actions">
|
|
16
|
+
<a class="action primary" href="/zh/guide/getting-started">快速开始</a>
|
|
17
|
+
<a class="action secondary" href="/zh/guide/configuration">查看配置</a>
|
|
18
|
+
</div>
|
|
19
|
+
</section>
|
|
20
|
+
|
|
21
|
+
<style>
|
|
22
|
+
.custom-home {
|
|
23
|
+
padding: 2rem 1rem 3rem;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.eyebrow {
|
|
27
|
+
margin: 0 0 0.75rem;
|
|
28
|
+
font-size: 0.85rem;
|
|
29
|
+
font-weight: 700;
|
|
30
|
+
letter-spacing: 0.08em;
|
|
31
|
+
text-transform: uppercase;
|
|
32
|
+
color: rgba(var(--muted-color) / 1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
h1 {
|
|
36
|
+
margin: 0;
|
|
37
|
+
font-size: clamp(2.5rem, 7vw, 4.5rem);
|
|
38
|
+
line-height: 1;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.lead {
|
|
42
|
+
max-width: 42rem;
|
|
43
|
+
margin: 1rem 0 0;
|
|
44
|
+
font-size: 1.05rem;
|
|
45
|
+
line-height: 1.8;
|
|
46
|
+
color: rgba(var(--muted-color) / 1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.actions {
|
|
50
|
+
display: flex;
|
|
51
|
+
flex-wrap: wrap;
|
|
52
|
+
gap: 0.75rem;
|
|
53
|
+
margin-top: 1.75rem;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.action {
|
|
57
|
+
display: inline-flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
justify-content: center;
|
|
60
|
+
padding: 0.85rem 1.15rem;
|
|
61
|
+
font-weight: 700;
|
|
62
|
+
text-decoration: none;
|
|
63
|
+
border: 1px solid rgba(var(--border-color) / 1);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.action.primary {
|
|
67
|
+
background: rgba(var(--primary-color) / 1);
|
|
68
|
+
border-color: rgba(var(--primary-color) / 1);
|
|
69
|
+
color: rgba(var(--primary-foreground-color) / 1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.action.secondary {
|
|
73
|
+
color: rgba(var(--foreground-color) / 1);
|
|
74
|
+
}
|
|
75
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineCollection, z } from "astro:content";
|
|
2
|
+
import { glob } from "astro/loaders";
|
|
3
|
+
|
|
4
|
+
const docs = defineCollection({
|
|
5
|
+
loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/content/docs" }),
|
|
6
|
+
schema: z.object({
|
|
7
|
+
title: z.string(),
|
|
8
|
+
description: z.string().optional(),
|
|
9
|
+
}),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const collections = {
|
|
13
|
+
docs,
|
|
14
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare module "@lucide/astro" {
|
|
2
|
+
export type LucideIconComponent = (props: Record<string, unknown>) => any;
|
|
3
|
+
export const icons: Record<string, LucideIconComponent>;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
declare module "copy-to-clipboard" {
|
|
7
|
+
interface Options {
|
|
8
|
+
debug?: boolean;
|
|
9
|
+
message?: string;
|
|
10
|
+
format?: string;
|
|
11
|
+
onCopy?: (clipboardData: object) => void;
|
|
12
|
+
}
|
|
13
|
+
const copy: (text: string, options?: Options) => boolean;
|
|
14
|
+
export default copy;
|
|
15
|
+
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
---
|
|
2
|
+
import NavBar from "../components/NavBar.astro";
|
|
3
|
+
import Sidebar from "../components/Sidebar.astro";
|
|
4
|
+
import DocToc from "../components/DocToc.astro";
|
|
5
|
+
import BaseHead from "../components/BaseHead.astro";
|
|
6
|
+
import { getResolvedSiteConfig } from "../lib/config";
|
|
7
|
+
import { customGlobalStyle } from "../lib/custom-style";
|
|
8
|
+
import "../styles/global.css";
|
|
9
|
+
import "../styles/markdown.css";
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
title?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
sidebar?: boolean;
|
|
15
|
+
contentClass?: string;
|
|
16
|
+
tocHeadings?: Array<{
|
|
17
|
+
depth: number;
|
|
18
|
+
slug: string;
|
|
19
|
+
text: string;
|
|
20
|
+
}>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const {
|
|
24
|
+
title,
|
|
25
|
+
description,
|
|
26
|
+
sidebar = true,
|
|
27
|
+
contentClass = "",
|
|
28
|
+
tocHeadings = [],
|
|
29
|
+
} = Astro.props;
|
|
30
|
+
const resolvedConfig = getResolvedSiteConfig(Astro.url.pathname);
|
|
31
|
+
const pageTitle = title
|
|
32
|
+
? `${title} | ${resolvedConfig.siteTitle}`
|
|
33
|
+
: resolvedConfig.siteTitle;
|
|
34
|
+
const pageDescription = description || resolvedConfig.siteDescription;
|
|
35
|
+
const ogImagePath =
|
|
36
|
+
Astro.url.pathname === "/"
|
|
37
|
+
? "/og/index.png"
|
|
38
|
+
: `/og${Astro.url.pathname.endsWith("/") ? Astro.url.pathname.slice(0, -1) : Astro.url.pathname}.png`;
|
|
39
|
+
const tocItems = tocHeadings.filter(
|
|
40
|
+
(heading) => heading.depth >= 2 && heading.depth <= 3,
|
|
41
|
+
);
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
<!doctype html>
|
|
45
|
+
<html lang={resolvedConfig.localeLang}>
|
|
46
|
+
<head>
|
|
47
|
+
<BaseHead
|
|
48
|
+
title={pageTitle}
|
|
49
|
+
description={pageDescription}
|
|
50
|
+
lang={resolvedConfig.localeLang}
|
|
51
|
+
image={ogImagePath}
|
|
52
|
+
ogType={sidebar ? "article" : "website"}
|
|
53
|
+
/>
|
|
54
|
+
{customGlobalStyle && <style is:global set:html={customGlobalStyle} />}
|
|
55
|
+
</head>
|
|
56
|
+
<body>
|
|
57
|
+
<NavBar showSidebarToggle={sidebar} />
|
|
58
|
+
<div class:list={["wrapper", !sidebar && "wrapper-without-sidebar"]}>
|
|
59
|
+
{
|
|
60
|
+
sidebar && (
|
|
61
|
+
<>
|
|
62
|
+
<button
|
|
63
|
+
type="button"
|
|
64
|
+
class="sider-backdrop"
|
|
65
|
+
data-sidebar-backdrop
|
|
66
|
+
data-state="closed"
|
|
67
|
+
aria-label="Close navigation menu"
|
|
68
|
+
/>
|
|
69
|
+
<aside
|
|
70
|
+
id="sidebar-drawer"
|
|
71
|
+
class="sider"
|
|
72
|
+
data-sidebar-drawer
|
|
73
|
+
data-state="closed"
|
|
74
|
+
>
|
|
75
|
+
<Sidebar />
|
|
76
|
+
</aside>
|
|
77
|
+
</>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
<main class:list={["content", contentClass]}>
|
|
81
|
+
<div
|
|
82
|
+
class:list={[
|
|
83
|
+
"docs-main",
|
|
84
|
+
tocItems.length > 0 && "docs-main-with-toc",
|
|
85
|
+
]}
|
|
86
|
+
>
|
|
87
|
+
<div class="docs-main-content">
|
|
88
|
+
<slot />
|
|
89
|
+
</div>
|
|
90
|
+
<DocToc items={tocItems} />
|
|
91
|
+
</div>
|
|
92
|
+
</main>
|
|
93
|
+
</div>
|
|
94
|
+
<script>
|
|
95
|
+
import { setupCodeCopyButtons } from "../scripts/code-copy";
|
|
96
|
+
|
|
97
|
+
setupCodeCopyButtons();
|
|
98
|
+
|
|
99
|
+
let sidebarCleanup: (() => void) | null = null;
|
|
100
|
+
|
|
101
|
+
const setupSidebarDrawer = () => {
|
|
102
|
+
if (typeof sidebarCleanup === "function") {
|
|
103
|
+
sidebarCleanup();
|
|
104
|
+
sidebarCleanup = null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const drawer = document.querySelector<HTMLElement>(
|
|
108
|
+
"[data-sidebar-drawer]",
|
|
109
|
+
);
|
|
110
|
+
const backdrop = document.querySelector<HTMLElement>(
|
|
111
|
+
"[data-sidebar-backdrop]",
|
|
112
|
+
);
|
|
113
|
+
const toggle = document.querySelector<HTMLElement>(
|
|
114
|
+
"[data-sidebar-toggle]",
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
if (!drawer || !backdrop || !toggle) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const linkElements = Array.from(
|
|
122
|
+
drawer.querySelectorAll<HTMLAnchorElement>("a"),
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
const setOpen = (open: boolean) => {
|
|
126
|
+
drawer.dataset.state = open ? "open" : "closed";
|
|
127
|
+
backdrop.dataset.state = open ? "open" : "closed";
|
|
128
|
+
toggle.setAttribute("aria-expanded", open ? "true" : "false");
|
|
129
|
+
document.body.style.overflow = open ? "hidden" : "";
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const close = () => setOpen(false);
|
|
133
|
+
const onToggle = () => setOpen(drawer.dataset.state !== "open");
|
|
134
|
+
|
|
135
|
+
toggle.addEventListener("click", onToggle);
|
|
136
|
+
backdrop.addEventListener("click", close);
|
|
137
|
+
linkElements.forEach((element: HTMLAnchorElement) =>
|
|
138
|
+
element.addEventListener("click", close),
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
const onKeydown = (event: KeyboardEvent) => {
|
|
142
|
+
if (event.key === "Escape") {
|
|
143
|
+
close();
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const onResize = () => {
|
|
148
|
+
if (window.innerWidth > 900) {
|
|
149
|
+
close();
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
document.addEventListener("keydown", onKeydown);
|
|
154
|
+
window.addEventListener("resize", onResize);
|
|
155
|
+
|
|
156
|
+
sidebarCleanup = () => {
|
|
157
|
+
toggle.removeEventListener("click", onToggle);
|
|
158
|
+
backdrop.removeEventListener("click", close);
|
|
159
|
+
linkElements.forEach((element: HTMLAnchorElement) =>
|
|
160
|
+
element.removeEventListener("click", close),
|
|
161
|
+
);
|
|
162
|
+
document.removeEventListener("keydown", onKeydown);
|
|
163
|
+
window.removeEventListener("resize", onResize);
|
|
164
|
+
document.body.style.overflow = "";
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
setupSidebarDrawer();
|
|
169
|
+
document.addEventListener("astro:page-load", setupSidebarDrawer);
|
|
170
|
+
</script>
|
|
171
|
+
</body>
|
|
172
|
+
</html>
|
|
173
|
+
|
|
174
|
+
<style is:global>
|
|
175
|
+
body {
|
|
176
|
+
min-height: 100vh;
|
|
177
|
+
display: flex;
|
|
178
|
+
flex-direction: column;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.sider {
|
|
182
|
+
flex-shrink: 0;
|
|
183
|
+
width: 16rem;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.sider-backdrop {
|
|
187
|
+
display: none;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.wrapper {
|
|
191
|
+
display: flex;
|
|
192
|
+
flex-direction: row;
|
|
193
|
+
width: 100%;
|
|
194
|
+
max-width: 80rem;
|
|
195
|
+
margin: 0 auto;
|
|
196
|
+
flex: 1;
|
|
197
|
+
min-height: 0;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.content {
|
|
201
|
+
flex: 1;
|
|
202
|
+
min-width: 0;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.docs-main {
|
|
206
|
+
width: 100%;
|
|
207
|
+
min-width: 0;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.wrapper-without-sidebar {
|
|
211
|
+
width: 100%;
|
|
212
|
+
border-width: 0 1px 0 1px;
|
|
213
|
+
border-style: solid;
|
|
214
|
+
border-color: rgba(var(--border-color) / 1);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
@media (min-width: 1200px) {
|
|
218
|
+
.docs-main-with-toc {
|
|
219
|
+
display: grid;
|
|
220
|
+
grid-template-columns: minmax(0, 1fr) 15rem;
|
|
221
|
+
gap: 2rem;
|
|
222
|
+
align-items: start;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
@media (max-width: 900px) {
|
|
227
|
+
.wrapper {
|
|
228
|
+
flex-direction: column;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.wrapper-without-sidebar {
|
|
232
|
+
border-width: 0 0 0 0;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.sider-backdrop {
|
|
236
|
+
display: block;
|
|
237
|
+
position: fixed;
|
|
238
|
+
inset: 0;
|
|
239
|
+
z-index: 20;
|
|
240
|
+
border: 0;
|
|
241
|
+
background: rgba(0 0 0 / 0.4);
|
|
242
|
+
opacity: 0;
|
|
243
|
+
pointer-events: none;
|
|
244
|
+
transition: opacity 180ms ease;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.sider-backdrop[data-state="open"] {
|
|
248
|
+
opacity: 1;
|
|
249
|
+
pointer-events: auto;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.sider {
|
|
253
|
+
position: fixed;
|
|
254
|
+
left: 0;
|
|
255
|
+
top: 0;
|
|
256
|
+
z-index: 30;
|
|
257
|
+
width: min(84vw, 18rem);
|
|
258
|
+
height: 100dvh;
|
|
259
|
+
transform: translateX(-100%);
|
|
260
|
+
transition: transform 220ms ease;
|
|
261
|
+
background: rgba(var(--background-color) / 1);
|
|
262
|
+
border-right: 1px solid rgba(var(--border-color) / 1);
|
|
263
|
+
padding: 5rem 0.5rem 1rem;
|
|
264
|
+
overflow-y: auto;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.sider[data-state="open"] {
|
|
268
|
+
transform: translateX(0);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.content {
|
|
272
|
+
border-left: 0;
|
|
273
|
+
padding-inline: 0;
|
|
274
|
+
padding-bottom: 0;
|
|
275
|
+
padding-top: 1.5rem;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
</style>
|