@deot/docs-theme 1.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/README.md +44 -0
- package/dist/index.cjs +12 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +10 -0
- package/dist/index.style.css +1 -0
- package/package.json +38 -0
- package/src/functions.scss +19 -0
- package/src/mixins.scss +28 -0
- package/src/theme.scss +26 -0
- package/src/variables.d.ts +1 -0
- package/src/variables.scss +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# @deot/docs-theme
|
|
2
|
+
|
|
3
|
+
`@deot/docs-theme` 提供 `@deot/docs` 各浏览器子包共享的 Light/Dark 类型、语义变量和 SCSS 工具,不包含主题状态、持久化或界面组件。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @deot/docs-theme
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## SCSS 与 CSS
|
|
12
|
+
|
|
13
|
+
```scss
|
|
14
|
+
@use '@deot/docs-theme/variables';
|
|
15
|
+
@use '@deot/docs-theme/functions' as *;
|
|
16
|
+
@use '@deot/docs-theme/mixins' as *;
|
|
17
|
+
@use '@deot/docs-theme/theme';
|
|
18
|
+
|
|
19
|
+
.example {
|
|
20
|
+
color: varfix(foreground-color);
|
|
21
|
+
background: varfix(background-color);
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
编译后的 CSS 变量样式可通过 `@deot/docs-theme/style.css` 引入(对应 `dist/index.style.css`)。Markdown、Playground 与 Client 的构建会内联同一份变量,通常不必单独加载。
|
|
26
|
+
|
|
27
|
+
运行时由 `@deot/docs-client` 负责同步 `data-doc-theme` 与 `data-vc-theme`。直接使用 Markdown、Playground 或 Renderer 时,也可以自行在祖先元素设置这两个属性之一。
|
|
28
|
+
|
|
29
|
+
语义变量覆盖前景/背景、主色、链接、提示与警告背景,以及成对的 `error-color` 与 `error-background`。组件库已有的颜色继续复用 `--vc-*`。
|
|
30
|
+
|
|
31
|
+
公共导出包括 `DOCS_THEMES`、`isDocsTheme`,以及 `DocsTheme`、`DocsThemePreference`、`DocsThemeOptions` 类型。
|
|
32
|
+
|
|
33
|
+
## 仓库内验证
|
|
34
|
+
|
|
35
|
+
在仓库根目录执行:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm run test -- --package-name theme
|
|
39
|
+
npm run build -- --package-name theme
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 许可证
|
|
43
|
+
|
|
44
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region packages/theme/src/index.ts
|
|
3
|
+
var DOCS_THEMES = ["light", "dark"];
|
|
4
|
+
/**
|
|
5
|
+
* 判断外部配置或持久化数据是否属于主题协议。
|
|
6
|
+
* @param value 待检查的外部值。
|
|
7
|
+
* @returns 是否为受支持的主题值。
|
|
8
|
+
*/
|
|
9
|
+
var isDocsTheme = (value) => DOCS_THEMES.includes(value);
|
|
10
|
+
//#endregion
|
|
11
|
+
exports.DOCS_THEMES = DOCS_THEMES;
|
|
12
|
+
exports.isDocsTheme = isDocsTheme;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const DOCS_THEMES: readonly ["light", "dark"];
|
|
2
|
+
|
|
3
|
+
export declare type DocsTheme = typeof DOCS_THEMES[number];
|
|
4
|
+
|
|
5
|
+
export declare interface DocsThemeOptions {
|
|
6
|
+
default?: DocsThemePreference;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export declare type DocsThemePreference = DocsTheme | 'system';
|
|
10
|
+
|
|
11
|
+
export declare const isDocsTheme: (value: unknown) => value is DocsTheme;
|
|
12
|
+
|
|
13
|
+
export { }
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region packages/theme/src/index.ts
|
|
2
|
+
var DOCS_THEMES = ["light", "dark"];
|
|
3
|
+
/**
|
|
4
|
+
* 判断外部配置或持久化数据是否属于主题协议。
|
|
5
|
+
* @param value 待检查的外部值。
|
|
6
|
+
* @returns 是否为受支持的主题值。
|
|
7
|
+
*/
|
|
8
|
+
var isDocsTheme = (value) => DOCS_THEMES.includes(value);
|
|
9
|
+
//#endregion
|
|
10
|
+
export { DOCS_THEMES, isDocsTheme };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@media (prefers-color-scheme:light){:root{--docs-background-color:#fff;--docs-background-color-soft:#f7f8fa;--docs-background-color-mute:#f2f3f5;--docs-foreground-color:#17233d;--docs-foreground-color-light:#515a6e;--docs-foreground-color-mute:#808695;--docs-border-color:#e8eaec;--docs-border-color-light:#f0f1f2;--docs-primary-color:#873bf4;--docs-primary-color-light:#f2ebfe;--docs-link-color:#2d8cf0;--docs-mask-color:hsla(0,0%,100%,.72);--docs-shadow-color:rgba(0,0,0,.14);--docs-code-background:#f6f8fa;--docs-footer-background:#141313;--docs-footer-foreground:#999;--docs-tip-background:#f9f0ff;--docs-warning-background:#fff6f7;--docs-error-color:#ed4014;--docs-error-background:#fef2f2}}@media (prefers-color-scheme:dark){:root{--docs-background-color:#171b24;--docs-background-color-soft:#252b3a;--docs-background-color-mute:#303748;--docs-foreground-color:#f8f8f8;--docs-foreground-color-light:#d9d9d9;--docs-foreground-color-mute:#b9b9b9;--docs-border-color:#3b4355;--docs-border-color-light:#303748;--docs-primary-color:#873bf4;--docs-primary-color-light:#35244d;--docs-link-color:#6daeff;--docs-mask-color:rgba(10,13,18,.76);--docs-shadow-color:rgba(0,0,0,.45);--docs-code-background:#202630;--docs-footer-background:#0d0f14;--docs-footer-foreground:#999;--docs-tip-background:#30223f;--docs-warning-background:#3d2529;--docs-error-color:#ff6b6b;--docs-error-background:#41272b}}[data-doc-theme=light],[data-vc-theme=light]{--docs-background-color:#fff;--docs-background-color-soft:#f7f8fa;--docs-background-color-mute:#f2f3f5;--docs-foreground-color:#17233d;--docs-foreground-color-light:#515a6e;--docs-foreground-color-mute:#808695;--docs-border-color:#e8eaec;--docs-border-color-light:#f0f1f2;--docs-primary-color:#873bf4;--docs-primary-color-light:#f2ebfe;--docs-link-color:#2d8cf0;--docs-mask-color:hsla(0,0%,100%,.72);--docs-shadow-color:rgba(0,0,0,.14);--docs-code-background:#f6f8fa;--docs-footer-background:#141313;--docs-footer-foreground:#999;--docs-tip-background:#f9f0ff;--docs-warning-background:#fff6f7;--docs-error-color:#ed4014;--docs-error-background:#fef2f2}[data-doc-theme=dark],[data-vc-theme=dark]{--docs-background-color:#171b24;--docs-background-color-soft:#252b3a;--docs-background-color-mute:#303748;--docs-foreground-color:#f8f8f8;--docs-foreground-color-light:#d9d9d9;--docs-foreground-color-mute:#b9b9b9;--docs-border-color:#3b4355;--docs-border-color-light:#303748;--docs-primary-color:#873bf4;--docs-primary-color-light:#35244d;--docs-link-color:#6daeff;--docs-mask-color:rgba(10,13,18,.76);--docs-shadow-color:rgba(0,0,0,.45);--docs-code-background:#202630;--docs-footer-background:#0d0f14;--docs-footer-foreground:#999;--docs-tip-background:#30223f;--docs-warning-background:#3d2529;--docs-error-color:#ff6b6b;--docs-error-background:#41272b}/*$vite$:1*/
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@deot/docs-theme",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"sass": "src/variables.scss",
|
|
8
|
+
"style": "dist/index.style.css",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./functions": "./src/functions.scss",
|
|
16
|
+
"./mixins": "./src/mixins.scss",
|
|
17
|
+
"./theme": "./src/theme.scss",
|
|
18
|
+
"./variables": {
|
|
19
|
+
"types": "./src/variables.d.ts",
|
|
20
|
+
"sass": "./src/variables.scss",
|
|
21
|
+
"style": "./src/variables.scss",
|
|
22
|
+
"default": "./src/variables.scss"
|
|
23
|
+
},
|
|
24
|
+
"./style.css": "./dist/index.style.css"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"src/*.scss",
|
|
29
|
+
"src/*.d.ts"
|
|
30
|
+
],
|
|
31
|
+
"sideEffects": [
|
|
32
|
+
"**/*.scss"
|
|
33
|
+
],
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use 'sass:meta';
|
|
3
|
+
@use './theme' as *;
|
|
4
|
+
|
|
5
|
+
/** 返回 Docs 语义变量,可为组件提供更细粒度的覆盖入口。 */
|
|
6
|
+
@function varfix($value, $component-name: false, $fallback: false) {
|
|
7
|
+
$theme-value: map.get($theme, $value);
|
|
8
|
+
$has-component: meta.type-of($component-name) == 'string';
|
|
9
|
+
|
|
10
|
+
@if $has-component and $theme-value {
|
|
11
|
+
@return #{'var(--docs-#{$component-name}-#{$value}, var(--docs-'}#{$value}#{'))'};
|
|
12
|
+
} @else if $has-component and $fallback {
|
|
13
|
+
@return #{'var(--docs-'}#{$component-name}-#{$value}#{','}#{$fallback}#{')'};
|
|
14
|
+
} @else if $theme-value {
|
|
15
|
+
@return #{'var(--docs-'}#{$value}#{')'};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@error '#{$value} is not a valid docs theme value.';
|
|
19
|
+
}
|
package/src/mixins.scss
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** 为需要强制覆盖的组件分别生成 Light/Dark 样式。 */
|
|
2
|
+
@mixin themefix($light: true) {
|
|
3
|
+
@if $light {
|
|
4
|
+
@media (prefers-color-scheme: light) {
|
|
5
|
+
:root {
|
|
6
|
+
@content;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// 显式属性的权重必须高于 :root 媒体规则,调用 Light/Dark mixin 的
|
|
11
|
+
// 先后顺序才不会让系统主题覆盖用户选择。
|
|
12
|
+
[data-doc-theme='light'][data-doc-theme],
|
|
13
|
+
[data-vc-theme='light'][data-vc-theme] {
|
|
14
|
+
@content;
|
|
15
|
+
}
|
|
16
|
+
} @else {
|
|
17
|
+
@media (prefers-color-scheme: dark) {
|
|
18
|
+
:root {
|
|
19
|
+
@content;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
[data-doc-theme='dark'][data-doc-theme],
|
|
24
|
+
[data-vc-theme='dark'][data-vc-theme] {
|
|
25
|
+
@content;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
package/src/theme.scss
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docs 只声明文档自身的语义色;组件库已有颜色继续复用 --vc-*。
|
|
3
|
+
* map 值允许为 light/dark 对象,单值表示两个主题保持一致。
|
|
4
|
+
*/
|
|
5
|
+
$theme: (
|
|
6
|
+
background-color: (light: #fff, dark: #171b24),
|
|
7
|
+
background-color-soft: (light: #f7f8fa, dark: #252b3a),
|
|
8
|
+
background-color-mute: (light: #f2f3f5, dark: #303748),
|
|
9
|
+
foreground-color: (light: #17233d, dark: #f8f8f8),
|
|
10
|
+
foreground-color-light: (light: #515a6e, dark: #d9d9d9),
|
|
11
|
+
foreground-color-mute: (light: #808695, dark: #b9b9b9),
|
|
12
|
+
border-color: (light: #e8eaec, dark: #3b4355),
|
|
13
|
+
border-color-light: (light: #f0f1f2, dark: #303748),
|
|
14
|
+
primary-color: #873bf4,
|
|
15
|
+
primary-color-light: (light: #f2ebfe, dark: #35244d),
|
|
16
|
+
link-color: (light: #2d8cf0, dark: #6daeff),
|
|
17
|
+
mask-color: (light: rgb(255 255 255 / 72%), dark: rgb(10 13 18 / 76%)),
|
|
18
|
+
shadow-color: (light: rgb(0 0 0 / 14%), dark: rgb(0 0 0 / 45%)),
|
|
19
|
+
code-background: (light: #f6f8fa, dark: #202630),
|
|
20
|
+
footer-background: (light: #141313, dark: #0d0f14),
|
|
21
|
+
footer-foreground: #999,
|
|
22
|
+
tip-background: (light: #f9f0ff, dark: #30223f),
|
|
23
|
+
warning-background: (light: #fff6f7, dark: #3d2529),
|
|
24
|
+
error-color: (light: #ed4014, dark: #ff6b6b),
|
|
25
|
+
error-background: (light: #fef2f2, dark: #41272b)
|
|
26
|
+
) !default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use 'sass:meta';
|
|
3
|
+
@use './theme' as *;
|
|
4
|
+
|
|
5
|
+
@mixin generate-theme($light: true) {
|
|
6
|
+
@each $key, $value in $theme {
|
|
7
|
+
$theme-value: $value;
|
|
8
|
+
|
|
9
|
+
@if meta.type-of($value) == 'map' {
|
|
10
|
+
$light-value: map.get($value, light);
|
|
11
|
+
$dark-value: map.get($value, dark);
|
|
12
|
+
|
|
13
|
+
// 自定义主题只声明 Light 值时,Dark 继续使用该值而不是输出空变量。
|
|
14
|
+
$theme-value: $light-value;
|
|
15
|
+
|
|
16
|
+
@if not $light and $dark-value {
|
|
17
|
+
$theme-value: $dark-value;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
--docs-#{$key}: #{$theme-value};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@media (prefers-color-scheme: light) {
|
|
26
|
+
:root {
|
|
27
|
+
@include generate-theme(true);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@media (prefers-color-scheme: dark) {
|
|
32
|
+
:root {
|
|
33
|
+
@include generate-theme(false);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
[data-doc-theme='light'],
|
|
38
|
+
[data-vc-theme='light'] {
|
|
39
|
+
@include generate-theme(true);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
[data-doc-theme='dark'],
|
|
43
|
+
[data-vc-theme='dark'] {
|
|
44
|
+
@include generate-theme(false);
|
|
45
|
+
}
|