From 1598de81319eedd411bd06b1297af7a3020c5fd5 Mon Sep 17 00:00:00 2001 From: lutinglt Date: Mon, 11 May 2026 00:20:28 +0800 Subject: [PATCH] 1.26 syntax highlighting and code editor style css transform from sass to lightningcss --- .gitattributes | 3 +- .github/CHANGELOG.md | 2 + .vscode/extensions.json | 9 +- .vscode/settings.json | 3 - CHANGELOG.md | 11 + README.md | 6 + README_CN.md | 5 + eslint.config.ts | 50 ++ package.json | 11 +- src/core/chroma.ts | 83 ---- src/core/color.ts | 40 +- src/core/github.ts | 187 ++----- src/core/{prettylights.ts => githubSyntax.ts} | 71 ++- src/core/index.ts | 6 + src/core/theme.ts | 39 +- src/core/{types.ts => types.d.ts} | 0 src/core/vite.ts | 198 -------- src/env.d.ts | 37 ++ src/functions/index.ts | 2 +- src/functions/var.ts | 15 +- src/index.ts | 13 +- src/{core => }/selectors.ts | 24 +- src/styles/chroma.ts | 147 ++++++ src/styles/codemirror.ts | 89 ++++ .../editor.ts => src/styles/index.ts | 17 +- .../pink-light.css.ts => src/styles/meta.ts | 51 +- src/types/color/chroma.ts | 4 + src/types/color/codemirror.ts | 150 ++++++ src/types/color/github.ts | 16 + src/types/color/index.ts | 34 +- src/types/color/syntax.ts | 104 ++++ src/types/index.ts | 12 +- src/types/vars.ts | 14 +- src/vite-plugin.ts | 323 +++++++++++++ .../common/after.ts | 27 +- .../styles.ts => styles/common/animation.ts | 6 +- .../common/button.ts | 39 +- styles/common/index.ts | 23 + eslint.config.js => styles/common/label.ts | 25 +- styles/components/actions/action_svg.ts | 3 +- styles/components/actions/actions.ts | 29 +- styles/components/actions/workflow_runs.ts | 23 +- styles/components/actions/workflow_steps.ts | 21 +- styles/components/actions/workflow_summary.ts | 39 +- styles/components/chroma.ts | 305 ------------ styles/components/dashboard.ts | 55 ++- styles/components/explore.ts | 81 ++-- styles/components/footer.ts | 7 +- styles/components/heatmap.ts | 27 +- styles/components/index.ts | 2 - styles/components/issues/issue.ts | 31 +- styles/components/issues/issue_comment.ts | 29 +- styles/components/issues/issue_list.ts | 24 +- styles/components/issues/issue_sidebar.ts | 62 +-- styles/components/issues/issue_timeline.ts | 29 +- styles/components/navbar.ts | 44 +- styles/components/newrepo.ts | 4 +- styles/components/notification.ts | 19 +- styles/components/org.ts | 19 +- styles/components/repo/clone.ts | 19 +- styles/components/repo/commit.ts | 29 +- styles/components/repo/diff.ts | 74 +-- styles/components/repo/milestones.ts | 11 +- styles/components/repo/packages.ts | 13 +- styles/components/repo/release.ts | 23 +- styles/components/repo/repo.ts | 21 +- styles/components/repo/repo_file_view.ts | 205 ++++++-- styles/components/repo/repo_files.ts | 33 +- styles/components/repo/repo_sidebar.ts | 11 +- styles/components/setting.ts | 29 +- styles/components/signin.ts | 2 +- styles/components/user.ts | 21 +- styles/public/attached.ts | 11 +- styles/public/base.ts | 8 +- styles/public/button.ts | 53 +- styles/public/dropdown/branch_dropdown.ts | 11 +- styles/public/dropdown/dropdown.ts | 66 +-- styles/public/dropdown/emoji_dropdown.ts | 3 +- styles/public/dropdown/selection_dropdown.ts | 57 ++- styles/public/input.ts | 21 +- styles/public/label/label.ts | 12 +- styles/public/label/repo_label.ts | 5 +- styles/public/label/sha_label.ts | 19 +- styles/public/label/task_status_label.ts | 3 +- styles/public/menu/compact_menu.ts | 25 +- styles/public/menu/index.ts | 13 - styles/public/menu/menu.ts | 13 +- styles/public/menu/pagination_menu.ts | 9 +- styles/public/menu/secondary_menu.ts | 19 +- styles/public/menu/vertical_menu.ts | 39 +- styles/public/modal.ts | 5 +- styles/public/other.ts | 21 +- styles/public/radius.ts | 16 +- styles/public/table.ts | 3 +- styles/public/tippy.ts | 13 +- styles/public/transition.ts | 26 +- styles/templates/repo/commit_sign_badge.ts | 5 +- styles/templates/repo/commits_list.ts | 3 +- styles/templates/repo/view_content.ts | 7 +- styles/templates/repo/view_list.ts | 9 +- theme.config.ts | 74 +++ themes/colorblind-dark.css.ts | 105 ---- themes/colorblind-light.css.ts | 102 ---- themes/dark.css.ts | 119 ----- themes/githubDark.ts | 457 ++++++++++++++++++ themes/githubLight.ts | 319 ++++++++++++ themes/githubPink.ts | 97 ++++ themes/light.css.ts | 116 ----- themes/soft-dark.css.ts | 140 ------ themes/tritanopia-dark.css.ts | 68 --- themes/tritanopia-light.css.ts | 68 --- tsconfig.json | 4 +- vite.config.ts | 84 ++-- 113 files changed, 3149 insertions(+), 2339 deletions(-) delete mode 100644 .vscode/settings.json create mode 100644 eslint.config.ts delete mode 100644 src/core/chroma.ts rename src/core/{prettylights.ts => githubSyntax.ts} (64%) rename src/core/{types.ts => types.d.ts} (100%) delete mode 100644 src/core/vite.ts create mode 100644 src/env.d.ts rename src/{core => }/selectors.ts (75%) create mode 100644 src/styles/chroma.ts create mode 100644 src/styles/codemirror.ts rename styles/components/editor.ts => src/styles/index.ts (60%) rename themes/pink-light.css.ts => src/styles/meta.ts (50%) create mode 100644 src/types/color/codemirror.ts create mode 100644 src/types/color/syntax.ts create mode 100644 src/vite-plugin.ts rename themes/pink-soft-dark.css.ts => styles/common/after.ts (58%) rename src/core/styles.ts => styles/common/animation.ts (93%) rename themes/pink-dark.css.ts => styles/common/button.ts (51%) create mode 100644 styles/common/index.ts rename eslint.config.js => styles/common/label.ts (65%) delete mode 100644 styles/components/chroma.ts create mode 100644 theme.config.ts delete mode 100644 themes/colorblind-dark.css.ts delete mode 100644 themes/colorblind-light.css.ts delete mode 100644 themes/dark.css.ts create mode 100644 themes/githubDark.ts create mode 100644 themes/githubLight.ts create mode 100644 themes/githubPink.ts delete mode 100644 themes/light.css.ts delete mode 100644 themes/soft-dark.css.ts delete mode 100644 themes/tritanopia-dark.css.ts delete mode 100644 themes/tritanopia-light.css.ts diff --git a/.gitattributes b/.gitattributes index 196bff1..9815490 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,5 +5,4 @@ .vscode/** linguist-generated gitea/** linguist-generated screenshots/** linguist-vendored -scripts/** linguist-vendored -eslint.config.js linguist-vendored \ No newline at end of file +scripts/** linguist-vendored \ No newline at end of file diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index 243fecb..df0f548 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -1,3 +1,5 @@ +### ⚠️ Breaking Changes + ### 🎉 ### ✨ Feature diff --git a/.vscode/extensions.json b/.vscode/extensions.json index ce2566a..43cc5ad 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,10 +1,3 @@ { - "recommendations": [ - "esbenp.prettier-vscode", - "dbaeumer.vscode-eslint", - "usernamehw.errorlens", - "mikestead.dotenv", - "styled-components.vscode-styled-components", - "typescriptteam.native-preview" - ] + "recommendations": ["styled-components.vscode-styled-components"] } diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 8e61f97..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "typescript.experimental.useTsgo": false -} diff --git a/CHANGELOG.md b/CHANGELOG.md index d891c3a..e0163c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,21 @@ +### ⚠️ Breaking Changes + +- Because the project uses Lightning CSS to transpile CSS nesting code, it will contain a large number of :is() + selectors, and browsers below Chrome 88 are not supported. Using browsers below Chrome 88 may cause many styling + issues. Please update to Chrome 88 or above. + ### ✨ Feature - Adapt the theme color identification and color blindness identification to the new version of Gitea. - The theme name for red-green color blindness has been synchronized with GitHub, providing a more accurate display of the name. +- The CSS transpilation engine has been switched from SASS to LightingCSS. Thanks to the optimization provided by + LightingCSS, the CSS file size has been reduced by 10%. ### 🌈 Style +- Add transition animation to the repository/organization buttons on the dashboard page. + #### Adaptation for version 1.26 - Synchronize avatar administrator logo. #29 @@ -15,6 +25,7 @@ - Optimize the style of the actions page. - Synchronization shortcut key prompt style. - Synchronize the style of the pop-up window for file search results in the repository. +- Synchronize code highlighting colors and styles for online file editors. #### More aligned with GitHub style diff --git a/README.md b/README.md index 8809d50..6e358bd 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,12 @@ accepted. ## Installation +> [!IMPORTANT] +> +> Because the project uses Lightning CSS to transpile CSS nesting code, it will contain a large number of :is() +> selectors, and browsers below Chrome 88 are not supported. Using browsers below Chrome 88 may cause many styling +> issues. Please update to Chrome 88 or above. + 1. Download the latest CSS theme file from the release page and place it in the `data/gitea/public/assets/css` directory (This directory may not be available by default and needs to be manually created) 2. Modify `data/gitea/conf/app.ini` and append the CSS filename without the `theme-` prefix to the end of `THEMES` under diff --git a/README_CN.md b/README_CN.md index 5fd0b75..61969c4 100644 --- a/README_CN.md +++ b/README_CN.md @@ -33,6 +33,11 @@ Gitea 理论上小版本号变更不会修改前端布局, 所以主题的小版 ## 安装 +> [!IMPORTANT] +> +> 因为项目使用了 Lighting CSS 转译 CSS 嵌套代码, 所以会包含大量 :is() 选择器, 不支持 Chrome +> 88 版本以下的浏览器使用 Chrome 88 以下的浏览器可能会出现大量样式问题, 请更新到 Chrome 88 以上版本 + 1. 在发布页下载最新的 CSS 主题文件放入 `data/gitea/public/assets/css` 目录下 (默认可能没有此目录需手动创建) 2. 修改 `data/gitea/conf/app.ini`,并将 CSS 文件名去掉 `theme-` 的名称附加到 `[ui]` 下的 `THEMES` 末尾 3. 重启 Gitea diff --git a/eslint.config.ts b/eslint.config.ts new file mode 100644 index 0000000..8e922b4 --- /dev/null +++ b/eslint.config.ts @@ -0,0 +1,50 @@ +/*! + * Copyright (c) https://github.com/lutinglt + * + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import js from "@eslint/js"; +import { defineConfig } from "eslint/config"; +import globals from "globals"; +import tseslint from "typescript-eslint"; + +export default defineConfig([ + { + files: ["**/*.{js,mjs,cjs,ts,mts,cts}"], + plugins: { js }, + extends: ["js/recommended"], + languageOptions: { + ecmaVersion: "latest", + globals: globals.browser, + }, + rules: { + "@typescript-eslint/no-unused-vars": [ + "error", + { + args: "all", + argsIgnorePattern: "^_", + caughtErrors: "all", + caughtErrorsIgnorePattern: "^_", + destructuredArrayIgnorePattern: "^_", + varsIgnorePattern: "^_", + ignoreRestSiblings: true, + }, + ], + }, + }, + tseslint.configs.recommended, +]); diff --git a/package.json b/package.json index 23dad22..79f504a 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ }, "type": "module", "scripts": { - "dev": "vite build --mode dev", "build": "tsgo -b && vite build", "lint": "eslint .", "format": "prettier --write .", @@ -24,19 +23,19 @@ "@eslint/js": "^10.0.1", "@linaria/core": "^7.0.0", "@types/node": "^25.5.2", - "@typescript/native-preview": "^7.0.0-dev.20260406.1", + "@typescript/native-preview": "^7.0.0-dev.20260509.2", "@vanilla-extract/css": "^1.20.1", "@vanilla-extract/vite-plugin": "^5.2.2", "@wyw-in-js/vite": "^1.0.7", "dotenv": "^17.4.1", - "eslint": "^10.2.0", - "globals": "^17.4.0", + "eslint": "^10.3.0", + "globals": "^17.6.0", + "jiti": "^2.6.1", "lightningcss": "^1.32.0", "polished": "^4.3.1", "prettier": "3.8.1", "prettier-plugin-organize-imports": "^4.3.0", - "sass-embedded": "^1.99.0", - "typescript-eslint": "^8.58.0", + "typescript-eslint": "^8.59.1", "typescript-plugin-css-modules": "^5.2.0", "undici": "^7.0.0", "vite": "^8.0.5" diff --git a/src/core/chroma.ts b/src/core/chroma.ts deleted file mode 100644 index 2c8b83e..0000000 --- a/src/core/chroma.ts +++ /dev/null @@ -1,83 +0,0 @@ -/*! - * Copyright (c) https://github.com/lutinglt - * - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { prettylights2Chroma, type prettylightsColor } from "./prettylights"; - -export const lightPrettylights: prettylightsColor = { - syntax: { - brackethighlighter: { angle: "#59636e", unmatched: "#82071e" }, - carriage: { return: { bg: "#cf222e", text: "#f6f8fa" } }, - comment: "#59636e", - constant: "#0550ae", - constantOtherReferenceLink: "#0a3069", - entity: "#6639ba", - entityTag: "#0550ae", - invalid: { illegal: { bg: "#82071e", text: "#f6f8fa" } }, - keyword: "#cf222e", - markup: { - bold: "#1f2328", - changed: { bg: "#ffd8b5", text: "#953800" }, - deleted: { bg: "#ffebe9", text: "#82071e" }, - heading: "#0550ae", - ignored: { bg: "#0550ae", text: "#d1d9e0" }, - inserted: { bg: "#dafbe1", text: "#116329" }, - italic: "#1f2328", - list: "#3b2300", - }, - metaDiffRange: "#8250df", - storageModifierImport: "#1f2328", - string: "#0a3069", - stringRegexp: "#116329", - sublimelinterGutterMark: "#818b98", - variable: "#953800", - }, -}; - -export const darkPrettylights: prettylightsColor = { - syntax: { - brackethighlighter: { angle: "#9198a1", unmatched: "#f85149" }, - carriage: { return: { bg: "#b62324", text: "#f0f6fc" } }, - comment: "#9198a1", - constant: "#79c0ff", - constantOtherReferenceLink: "#a5d6ff", - entity: "#d2a8ff", - entityTag: "#7ee787", - invalid: { illegal: { bg: "#8e1519", text: "#f0f6fc" } }, - keyword: "#ff7b72", - markup: { - bold: "#f0f6fc", - changed: { bg: "#5a1e02", text: "#ffdfb6" }, - deleted: { bg: "#67060c", text: "#ffdcd7" }, - heading: "#1f6feb", - ignored: { bg: "#1158c7", text: "#f0f6fc" }, - inserted: { bg: "#033a16", text: "#aff5b4" }, - italic: "#f0f6fc", - list: "#f2cc60", - }, - metaDiffRange: "#d2a8ff", - storageModifierImport: "#f0f6fc", - string: "#a5d6ff", - stringRegexp: "#7ee787", - sublimelinterGutterMark: "#3d444d", - variable: "#ffa657", - }, -}; - -export const defaultLightChroma = prettylights2Chroma(lightPrettylights); -export const defaultDarkChroma = prettylights2Chroma(darkPrettylights); diff --git a/src/core/color.ts b/src/core/color.ts index d68e787..01c5838 100644 --- a/src/core/color.ts +++ b/src/core/color.ts @@ -19,10 +19,9 @@ import { rgba, saturate } from "polished"; import { scaleColorLight } from "src/functions"; -import type { Ansi, Chroma, Console, Diff, Github, Message, Named, Other, Primary, Secondary } from "src/types"; -import { themeVars } from "src/types/vars"; -import { defaultDarkChroma, defaultLightChroma } from "./chroma"; -import type { Theme } from "./theme"; +import type { Ansi, Console, Diff, Github, Message, Named, Other, Primary, Secondary } from "src/types"; +import { themeVars } from "src/types"; +import type { SyntaxConfig, Theme } from "./theme"; export type ThemeColor = { /** 用于标识当前是否为暗色主题: `true` 暗色 `false` 亮色 */ @@ -78,6 +77,10 @@ export type ThemeColor = { github: Github; }; +export type ThemeOptions = { + themeColor: ThemeColor; +} & SyntaxConfig; + /** 定义颜色, 用于生成颜色主题 * @example * 文件名: "dark.css.ts" @@ -103,7 +106,7 @@ export type ThemeColor = { * github, * }) */ -export function defineTheme(themeColor: ThemeColor, chroma?: Chroma): Theme { +export function defineTheme({ themeColor, ...syntaxConfig }: ThemeOptions): Theme { const brightDir = themeColor.isDarkTheme ? -1 : 1; const primary: Primary = { @@ -391,18 +394,21 @@ export function defineTheme(themeColor: ThemeColor, chroma?: Chroma): Theme { }; return { - isDarkTheme: themeColor.isDarkTheme.toString(), - chroma: chroma || (themeColor.isDarkTheme ? defaultDarkChroma : defaultLightChroma), - color: { - primary, - secondary, - ...named, - ansi, - console: themeColor.console, - diff: themeColor.diff, - ...message, - ...themeColor.other, + isDarkTheme: themeColor.isDarkTheme, + ...syntaxConfig, + themeColors: { + isDarkTheme: themeColor.isDarkTheme.toString(), + color: { + primary, + secondary, + ...named, + ansi, + console: themeColor.console, + diff: themeColor.diff, + ...message, + ...themeColor.other, + }, + github: themeColor.github, }, - github: themeColor.github, }; } diff --git a/src/core/github.ts b/src/core/github.ts index 2d6b7d6..4ac0ea2 100644 --- a/src/core/github.ts +++ b/src/core/github.ts @@ -20,8 +20,7 @@ import { saturate } from "polished"; import type { Console, Diff, Other } from "src"; import { scaleColorLight } from "src/functions"; -import type { Github } from "src/types"; -import { themeVars } from "src/types/vars"; +import { themeVars, type Github } from "src/types"; import { type ThemeColor } from "./color"; export type GithubColor = { @@ -90,6 +89,8 @@ export type GithubColor = { bgColor: { active: string; hover: string; rest: string }; transparent: { bgColor: { active: string; hover: string; selected: string } }; }; + controlTrack: { bgColor: { rest: string } }; + controlKnob: { bgColor: { rest: string } }; shadow: { floating: { small: string }; inset: string; resting: { small: string; medium: string } }; overlay: { backdrop: { bgColor: string }; bgColor: string }; underlineNav: { borderColor: { active: string } }; @@ -103,53 +104,30 @@ export type GithubColor = { export function github2ThemeColor(githubColor: GithubColor): ThemeColor { const console: Console = { - fg: { - self: githubColor.fgColor.default, - subtle: githubColor.fgColor.muted, - }, + fg: { self: githubColor.fgColor.default, subtle: githubColor.fgColor.muted }, bg: githubColor.bgColor.inset, border: githubColor.borderColor.muted, activeBg: githubColor.control.bgColor.active, hoverBg: githubColor.control.transparent.bgColor.hover, - menu: { - bg: githubColor.overlay.bgColor, - border: githubColor.borderColor.muted, - }, + menu: { bg: githubColor.overlay.bgColor, border: githubColor.borderColor.muted }, link: githubColor.fgColor.muted, }; const diff: Diff = { added: { fg: githubColor.bgColor.success.emphasis, - linenum: { - bg: githubColor.diffBlob.addtionNum.bgColor, - }, - row: { - bg: githubColor.bgColor.success.muted, - border: githubColor.bgColor.success.muted, - }, - word: { - bg: githubColor.diffBlob.addtionWord.bgColor, - }, + linenum: { bg: githubColor.diffBlob.addtionNum.bgColor }, + row: { bg: githubColor.bgColor.success.muted, border: githubColor.bgColor.success.muted }, + word: { bg: githubColor.diffBlob.addtionWord.bgColor }, }, removed: { fg: githubColor.bgColor.danger.emphasis, - linenum: { - bg: githubColor.diffBlob.deletionNum.bgColor, - }, - row: { - bg: githubColor.bgColor.danger.muted, - border: githubColor.bgColor.danger.muted, - }, - word: { - bg: githubColor.diffBlob.deletionWord.bgColor, - }, + linenum: { bg: githubColor.diffBlob.deletionNum.bgColor }, + row: { bg: githubColor.bgColor.danger.muted, border: githubColor.bgColor.danger.muted }, + word: { bg: githubColor.diffBlob.deletionWord.bgColor }, }, moved: { - row: { - bg: githubColor.bgColor.attention.muted, - border: githubColor.bgColor.attention.muted, - }, + row: { bg: githubColor.bgColor.attention.muted, border: githubColor.bgColor.attention.muted }, }, inactive: githubColor.bgColor.muted, }; @@ -159,10 +137,7 @@ export function github2ThemeColor(githubColor: GithubColor): ThemeColor { body: githubColor.bgColor.default, box: { header: githubColor.bgColor.muted, - body: { - self: themeVars.color.body, - highlight: githubColor.bgColor.accent.muted, - }, + body: { self: themeVars.color.body, highlight: githubColor.bgColor.accent.muted }, }, text: { self: githubColor.fgColor.default, @@ -182,48 +157,26 @@ export function github2ThemeColor(githubColor: GithubColor): ThemeColor { toggleBackgound: githubColor.bgColor.inset, border: themeVars.color.light.border, }, - light: { - self: themeVars.color.body, - border: githubColor.borderColor.default, - }, - hover: { - self: githubColor.control.bgColor.hover, - opaque: themeVars.color.box.header, - }, + light: { self: themeVars.color.body, border: githubColor.borderColor.default }, + hover: { self: githubColor.control.bgColor.hover, opaque: themeVars.color.box.header }, active: githubColor.control.transparent.bgColor.selected, menu: githubColor.overlay.bgColor, card: themeVars.color.body, markup: { tableRow: githubColor.bgColor.muted, - code: { - block: githubColor.bgColor.muted, - inline: githubColor.bgColor.neutral.muted, - }, + code: { block: githubColor.bgColor.muted, inline: githubColor.bgColor.neutral.muted }, }, button: githubColor.control.bgColor.rest, codeBg: "unset", - shadow: { - self: githubColor.shadow.floating.small, - opaque: themeVars.color.shadow.self, - }, + shadow: { self: githubColor.shadow.floating.small, opaque: themeVars.color.shadow.self }, secondaryBg: "unset", expandButton: githubColor.diffBlob.hunkNum.bgColor.rest, placeholderText: themeVars.color.text.light.num3, - editor: { - lineHighlight: themeVars.color.primary.light.num5, - selection: themeVars.color.editor.lineHighlight, - }, + editor: { lineHighlight: themeVars.color.secondary.light.num1, selection: themeVars.color.editor.lineHighlight }, projectColumnBg: githubColor.bgColor.inset, caret: themeVars.color.text.dark, - reaction: { - bg: "initial", - hoverBg: githubColor.bgColor.accent.muted, - activeBg: githubColor.bgColor.accent.muted, - }, - tooltip: { - text: githubColor.fgColor.onEmphasis, - bg: githubColor.bgColor.emphasis, - }, + reaction: { bg: "initial", hoverBg: githubColor.bgColor.accent.muted, activeBg: githubColor.bgColor.accent.muted }, + tooltip: { text: githubColor.fgColor.onEmphasis, bg: githubColor.bgColor.emphasis }, nav: { bg: githubColor.bgColor.inset, hoverBg: githubColor.control.transparent.bgColor.hover, @@ -238,26 +191,15 @@ export function github2ThemeColor(githubColor: GithubColor): ThemeColor { }, accent: themeVars.color.primary.light.num1, smallAccent: themeVars.color.primary.light.num5, - highlight: { - fg: githubColor.fgColor.attention, - bg: githubColor.bgColor.attention.muted, - }, + highlight: { fg: githubColor.fgColor.attention, bg: githubColor.bgColor.attention.muted }, overlayBackdrop: githubColor.overlay.backdrop.bgColor, danger: themeVars.color.red.self, - transparency: { - grid: { - light: "#ffffff", - dark: "#e5e5e5", - }, - }, + transparency: { grid: { light: "#ffffff", dark: "#e5e5e5" } }, workflowEdgeHover: githubColor.bgColor.accent.emphasis, }; const github: Github = { - avatar: { - bgColor: githubColor.avatar.bgColor, - borderColor: githubColor.avatar.borderColor, - }, + avatar: { bgColor: githubColor.avatar.bgColor, borderColor: githubColor.avatar.borderColor }, fgColor: { accent: githubColor.fgColor.accent, success: githubColor.fgColor.success, @@ -265,47 +207,22 @@ export function github2ThemeColor(githubColor: GithubColor): ThemeColor { onEmphasis: githubColor.fgColor.onEmphasis, }, bgColor: { - accent: { - emphasis: githubColor.bgColor.accent.emphasis, - muted: githubColor.bgColor.accent.muted, - }, - success: { - emphasis: githubColor.bgColor.success.emphasis, - }, - attention: { - emphasis: githubColor.bgColor.attention.emphasis, - }, - danger: { - emphasis: githubColor.bgColor.danger.emphasis, - }, - done: { - emphasis: githubColor.bgColor.done.emphasis, - }, - neutral: { - emphasis: githubColor.bgColor.neutral.emphasis, - }, + accent: { emphasis: githubColor.bgColor.accent.emphasis, muted: githubColor.bgColor.accent.muted }, + success: { emphasis: githubColor.bgColor.success.emphasis }, + attention: { emphasis: githubColor.bgColor.attention.emphasis }, + danger: { emphasis: githubColor.bgColor.danger.emphasis }, + done: { emphasis: githubColor.bgColor.done.emphasis }, + neutral: { emphasis: githubColor.bgColor.neutral.emphasis }, }, borderColor: { - accent: { - emphasis: githubColor.borderColor.accent.emphasis, - }, - attention: { - emphasis: githubColor.borderColor.attention.emphasis, - }, - success: { - emphasis: githubColor.borderColor.success.emphasis, - }, - done: { - emphasis: githubColor.borderColor.done.emphasis, - }, + accent: { emphasis: githubColor.borderColor.accent.emphasis }, + attention: { emphasis: githubColor.borderColor.attention.emphasis }, + success: { emphasis: githubColor.borderColor.success.emphasis }, + done: { emphasis: githubColor.borderColor.done.emphasis }, emphasis: githubColor.borderColor.emphasis, }, button: { - default: { - bgColor: { - active: githubColor.control.bgColor.active, - }, - }, + default: { bgColor: { active: githubColor.control.bgColor.active } }, primary: { fgColor: { accent: saturate( @@ -319,39 +236,25 @@ export function github2ThemeColor(githubColor: GithubColor): ThemeColor { hover: githubColor.button.primary.bgColor.hover, active: githubColor.button.primary.bgColor.active, }, - borderColor: { - rest: githubColor.borderColor.translucent, - hover: githubColor.borderColor.translucent, - }, + borderColor: { rest: githubColor.borderColor.translucent, hover: githubColor.borderColor.translucent }, }, danger: { - fgColor: { - rest: githubColor.button.danger.fgColor.rest, - hover: githubColor.button.danger.fgColor.hover, - }, + fgColor: { rest: githubColor.button.danger.fgColor.rest, hover: githubColor.button.danger.fgColor.hover }, bgColor: { rest: githubColor.control.bgColor.rest, hover: githubColor.button.danger.bgColor.hover, active: githubColor.button.danger.bgColor.active, }, - borderColor: { - hover: githubColor.borderColor.translucent, - }, - }, - star: { - iconColor: githubColor.button.star.iconColor, + borderColor: { hover: githubColor.borderColor.translucent }, }, + star: { iconColor: githubColor.button.star.iconColor }, }, control: { - bgColor: { - rest: githubColor.control.bgColor.rest, - }, - transparent: { - bgColor: { - hover: githubColor.control.transparent.bgColor.hover, - }, - }, + bgColor: { rest: githubColor.control.bgColor.rest }, + transparent: { bgColor: { hover: githubColor.control.transparent.bgColor.hover } }, }, + controlTrack: { bgColor: { rest: githubColor.controlTrack.bgColor.rest } }, + controlKnob: { bgColor: { rest: githubColor.controlKnob.bgColor.rest } }, shadow: { floating: { small: `0px 0px 0px 1px ${themeVars.color.light.border}, 0px 6px 12px -3px ${themeVars.color.shadow.self}, 0px 6px 18px 0px ${themeVars.color.shadow.self};`, @@ -363,11 +266,7 @@ export function github2ThemeColor(githubColor: GithubColor): ThemeColor { medium: `drop-shadow(0 1px 1px ${githubColor.shadow.floating.small}) drop-shadow(0 3px 6px ${githubColor.shadow.resting.medium})`, }, }, - underlineNav: { - borderColor: { - active: githubColor.underlineNav.borderColor.active, - }, - }, + underlineNav: { borderColor: { active: githubColor.underlineNav.borderColor.active } }, contribution: { default: { bgColor: { diff --git a/src/core/prettylights.ts b/src/core/githubSyntax.ts similarity index 64% rename from src/core/prettylights.ts rename to src/core/githubSyntax.ts index 208def3..15370aa 100644 --- a/src/core/prettylights.ts +++ b/src/core/githubSyntax.ts @@ -17,9 +17,10 @@ * limitations under the License. */ -import type { Chroma } from "src/types"; +import { type Chroma, type CodeMirror } from "src/types"; +import type { GithubColor } from "./github"; -export type prettylightsColor = { +export type PrettylightsColor = { syntax: { brackethighlighter: { angle: string; unmatched: string }; carriage: { return: { bg: string; text: string } }; @@ -49,7 +50,30 @@ export type prettylightsColor = { }; }; -export function prettylights2Chroma(prettylights: prettylightsColor): Chroma { +export type CodeMirrorColor = { + syntax: { + fgColor: { + comment: string; + constant: string; + entity: string; + keyword: string; + storage: string; + string: string; + support: string; + variable: string; + }; + }; + matchingBracket?: { + fgColor?: string; + }; +}; + +export type GitHubSyntax = { + prettyLights: PrettylightsColor; + codeMirror: CodeMirrorColor; +}; + +export function prettylights2Chroma(prettylights: PrettylightsColor): Chroma { return { textWhiteSpace: prettylights.syntax.brackethighlighter.unmatched, err: prettylights.syntax.brackethighlighter.unmatched, @@ -117,6 +141,7 @@ export function prettylights2Chroma(prettylights: prettylightsColor): Chroma { operator: { self: prettylights.syntax.constant, word: prettylights.syntax.constant, + reserved: prettylights.syntax.keyword, }, punctuation: prettylights.syntax.markup.bold, comment: { @@ -144,3 +169,43 @@ export function prettylights2Chroma(prettylights: prettylightsColor): Chroma { }, }; } + +export function githubSyntax2CodeMirror(githubSyntax: GitHubSyntax, githubColor: GithubColor): CodeMirror { + return { + token: { + keyword: githubSyntax.codeMirror.syntax.fgColor.keyword, + atom: githubSyntax.codeMirror.syntax.fgColor.constant, + bool: githubSyntax.codeMirror.syntax.fgColor.constant, + variableName: githubSyntax.codeMirror.syntax.fgColor.entity, + variableName2: githubSyntax.codeMirror.syntax.fgColor.storage, + propertyName: githubSyntax.codeMirror.syntax.fgColor.constant, + typeName: githubSyntax.codeMirror.syntax.fgColor.variable, + className: githubSyntax.codeMirror.syntax.fgColor.variable, + namespace: githubSyntax.codeMirror.syntax.fgColor.variable, + macroName: githubSyntax.prettyLights.syntax.variable, + labelName: githubSyntax.codeMirror.syntax.fgColor.constant, + number: githubSyntax.codeMirror.syntax.fgColor.constant, + string: githubSyntax.codeMirror.syntax.fgColor.string, + string2: githubSyntax.codeMirror.syntax.fgColor.string, + operator: githubSyntax.codeMirror.matchingBracket?.fgColor ?? githubColor.fgColor.default, + punctuation: githubSyntax.codeMirror.matchingBracket?.fgColor ?? githubColor.fgColor.default, + comment: githubSyntax.codeMirror.syntax.fgColor.comment, + meta: githubSyntax.codeMirror.syntax.fgColor.support, + invalid: githubSyntax.codeMirror.syntax.fgColor.keyword, + link: githubSyntax.codeMirror.syntax.fgColor.string, + heading: githubSyntax.codeMirror.syntax.fgColor.entity, + emphasis: githubSyntax.codeMirror.syntax.fgColor.comment, + strong: githubSyntax.codeMirror.syntax.fgColor.comment, + inserted: githubSyntax.codeMirror.syntax.fgColor.string, + deleted: githubSyntax.codeMirror.syntax.fgColor.keyword, + }, + language: { + json: githubSyntax.codeMirror.syntax.fgColor.constant, + json5: githubSyntax.codeMirror.syntax.fgColor.constant, + yaml: githubSyntax.codeMirror.syntax.fgColor.constant, + css: githubSyntax.codeMirror.syntax.fgColor.constant, + html: githubSyntax.codeMirror.syntax.fgColor.constant, + xml: githubSyntax.codeMirror.syntax.fgColor.constant, + }, + }; +} diff --git a/src/core/index.ts b/src/core/index.ts index 115f632..1715166 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -17,4 +17,10 @@ * limitations under the License. */ +export { defineTheme, type ThemeColor } from "./color"; +export { display2GithubColor, type DisplayColor } from "./display"; +export { github2ThemeColor, type GithubColor } from "./github"; +export type { GitHubSyntax } from "./githubSyntax"; export { createTheme } from "./theme"; +export type { Theme } from "./theme"; +export type { CSSVarFunction, MapLeafNodes } from "./types"; diff --git a/src/core/theme.ts b/src/core/theme.ts index cec622b..1f73e40 100644 --- a/src/core/theme.ts +++ b/src/core/theme.ts @@ -18,20 +18,34 @@ */ import { createGlobalTheme, globalKeyframes, globalStyle } from "@vanilla-extract/css"; -import { otherThemeVars, themeInfoVars, themeVars } from "src/types/vars"; -import * as selectors from "./selectors"; -import type { MapLeafNodes, WithOptionalLayer } from "./types"; +import { selectors } from "src"; +import { createChroma, createCodeMirror } from "src/styles"; +import { otherThemeVars, syntaxVars, themeVars, type Syntax } from "src/types"; +import type { GithubColor } from "./github"; +import { githubSyntax2CodeMirror, prettylights2Chroma, type GitHubSyntax } from "./githubSyntax"; +import type { MapLeafNodes } from "./types"; -export type Theme = WithOptionalLayer>; +/** 语法高亮配置 + * - "github": 使用 GitHub Syntax 代码高亮配色 + * - "gitea": 使用 Gitea Syntax 代码高亮配色 + */ +export type SyntaxConfig = + | { syntaxType: "github"; syntaxColors: GitHubSyntax; githubColors: GithubColor } + | { syntaxType: "gitea"; syntaxColors: Syntax }; + +export type Theme = { + isDarkTheme: boolean; + themeColors: MapLeafNodes; +} & SyntaxConfig; // vite define 编译时注入的常量 declare const __THEME_VERSION__: string; export function createTheme(theme: Theme): void { - const isDarkTheme: boolean = JSON.parse(theme.isDarkTheme); + // 注入主题标识版本号 + createGlobalTheme(selectors.root, { theme: { version: `"${__THEME_VERSION__}"` } }); // 全局主题变量 - createGlobalTheme(selectors.root, themeInfoVars, { version: `"${__THEME_VERSION__}"` }); - createGlobalTheme(selectors.root, themeVars, theme); + createGlobalTheme(selectors.root, themeVars, theme.themeColors); createGlobalTheme(selectors.root, otherThemeVars, { border: { radius: "6px" }, color: { git: "#f05133" }, @@ -40,9 +54,9 @@ export function createTheme(theme: Theme): void { // 全局样式 globalStyle(selectors.root, { accentColor: themeVars.color.accent, - colorScheme: isDarkTheme ? "dark" : "light", + colorScheme: theme.isDarkTheme ? "dark" : "light", }); - if (isDarkTheme) globalStyle(selectors.emoji, { filter: "invert(100%) hue-rotate(180deg)" }); + if (theme.isDarkTheme) globalStyle(selectors.emoji, { filter: "invert(100%) hue-rotate(180deg)" }); // 全局动画 globalKeyframes(selectors.overlayAppear, { "0%": { opacity: 0 }, @@ -56,4 +70,11 @@ export function createTheme(theme: Theme): void { "0%": { opacity: 0, transform: "translateY(8px)" }, "100%": { opacity: 1, transform: "translateY(0)" }, }); + // 代码高亮 + if (theme.syntaxType === "github") { + createChroma(prettylights2Chroma(theme.syntaxColors.prettyLights)); + createCodeMirror(githubSyntax2CodeMirror(theme.syntaxColors, theme.githubColors)); + } else { + createGlobalTheme(selectors.root, syntaxVars, theme.syntaxColors); + } } diff --git a/src/core/types.ts b/src/core/types.d.ts similarity index 100% rename from src/core/types.ts rename to src/core/types.d.ts diff --git a/src/core/vite.ts b/src/core/vite.ts deleted file mode 100644 index 18c45d5..0000000 --- a/src/core/vite.ts +++ /dev/null @@ -1,198 +0,0 @@ -/*! - * Copyright (c) https://github.com/lutinglt - * - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { execSync } from "node:child_process"; -import crypto from "node:crypto"; -import fs from "node:fs"; -import path from "node:path"; -import type { Plugin } from "vite"; - -const suffix = ".css.ts"; - -/** - * 生成主题输入 - * @param outDir 输出目录与 vite 配置中的 outDir 一致, 用于生成临时目录 - * @param themeDir 颜色主题目录 - * @param devTheme 开发模式下的主题, 仅打包该主题 - * @param mode 模式, 开发模式为 dev `vite build --mode dev` - * @returns vite.rollupOptions.input 的配置 - */ -export function themeInput(outDir: string, themeDir: string, mode: string): { [key: string]: string } { - const hash = crypto.randomBytes(6).toString("hex"); - const tmpDir = `${outDir}/tmp-${hash}`; // 输出目录下的临时目录 - fs.mkdirSync(tmpDir, { recursive: true }); - - const input: { [key: string]: string } = {}; - const themeEntries = fs.readdirSync(themeDir, { withFileTypes: true }); - const devTheme = process.env.DEV_THEME || "dark"; // 开发模式仅打包单个颜色主题 - - for (const entry of themeEntries) { - // 目录下所有的 css.ts 文件都作为主题入口 - if (entry.isFile() && entry.name.endsWith(suffix)) { - const fileName = entry.name.replace(suffix, ""); - // 开发模式只打包 devTheme 主题 - if (mode === "dev" && fileName !== devTheme) continue; - // 创建颜色主题的 css.ts 文件, vanilla-extract 需要这个文件后缀名并生成 css - const tmpCssTs = path.join(tmpDir, `${fileName}${suffix}`); - const createImport = `import { createTheme } from "src/core";`; - const themeImport = `import theme from "themes/${fileName}";`; - const createFn = `createTheme(theme);`; - fs.writeFileSync(tmpCssTs, `${createImport}\n${themeImport}\n${createFn}`); - // 生成主题入口的 .ts 文件, 合并样式和颜色主题 - const tmpInputTs = path.join(tmpDir, `${fileName}.ts`); - const stylesImport = `import "styles";`; - const cssImport = `import "./${fileName}${suffix}";`; - fs.writeFileSync(tmpInputTs, `${stylesImport}\n${cssImport}`); - - input[fileName] = tmpInputTs; - } - } - if (mode === "dev") { - console.log("[themeInput] devTheme:", devTheme); - } - return input; -} - -const colorBlindMap: Record = { - colorblind: "red-green", - tritanopia: "blue-yellow", -}; - -function giteaThemeMetaInfo(nameGroup: string[]): string { - const colorScheme = nameGroup[nameGroup.length - 1]; - const colorBlindKey = nameGroup.find(word => word in colorBlindMap); - const colorBlindType = colorBlindKey ? colorBlindMap[colorBlindKey] : ""; - // 将色盲名称放在最后 - // 调整顺序: 去除 colorBlindKey 和 colorScheme, 把 colorScheme 放回倒数第二, colorBlindKey 替换后放末尾 - const sorted = [ - ...nameGroup.filter(word => word !== colorBlindKey && word !== colorScheme), - colorScheme, - ...(colorBlindKey - ? colorBlindKey === "colorblind" - ? ["protanopia", "and", "deuteranopia"] - : [colorBlindKey] - : []), - ]; - const displayName = sorted.map(word => word[0].toUpperCase() + word.slice(1).toLowerCase()).join(" "); - - return `gitea-theme-meta-info { - --theme-display-name: "GitHub ${displayName}";${colorBlindType ? `\n --theme-colorblind-type: "${colorBlindType}";` : ""} - --theme-color-scheme: "${colorScheme}"; -} -`; // 不要省略分号, 也不要追加任何变量, 否则 Gitea 不识别 -} - -const prefix = "theme-github-"; - -/** - * 生成主题文件 - * @important vite.rollupOptions.output 配置 `assetFileNames: "[name].[ext]"` - */ -export function themePlugin(): Plugin { - return { - name: "themePlugin", - generateBundle(this, _, bundle) { - let styles = ""; - for (const [key, value] of Object.entries(bundle)) { - if (value.type === "chunk") { - delete bundle[key]; // 删除 chunk - } else { - // 样式文件是通过入口导入的, 没有原始文件名 - if (value.originalFileNames.length === 0) { - // 收集所有的样式文件(逻辑上只有一个) - // vite 会在尾部添加注释, 后续会合并到颜色主题, 此处需要删除注释 - styles += value.source.toString().replace("/*$vite$:1*/", ""); - delete bundle[key]; - } - } - } - // 生成所有的主题文件 - for (const [key, value] of Object.entries(bundle)) { - // 仅为了类型检查, 逻辑上输出中全是 asset 类型 - // vite8 中 bundle 删除后依旧有 styles.css, 追加判断需要有入口的原始文件名 - if (value.type === "asset" && value.originalFileNames.length > 0) { - const name = `${prefix}${key}`; - const fileName = `${prefix}${value.fileName}`; - const originalFileName = value.originalFileNames.pop(); - const type = value.type; - // 合并样式文件和主题信息 - const meta = giteaThemeMetaInfo(key.split(".")[0].split("-")); - const source = `${meta}${value.source.toString()}${styles}`; - // 添加主题到输出 - this.emitFile({ name, fileName, source, type, originalFileName }); - // 自动颜色主题 - const isDark = key.endsWith("dark.css"); - const darkName = key.replace("light", "dark"); - const lightName = darkName.replace("dark", "light"); - const findTheme = isDark ? lightName : darkName; - if (findTheme in bundle) { - const autoName = `${prefix}${darkName.replace("dark", "auto")}`; - const lightContent = `@import "./${prefix}${lightName}" (prefers-color-scheme: light);`; - const darkContent = `@import "./${prefix}${darkName}" (prefers-color-scheme: dark);`; - const nameGroup = key.split(".")[0].split("-").slice(0, -1); - nameGroup.push("auto"); - const metaInfo = giteaThemeMetaInfo(nameGroup); - this.emitFile({ - name: autoName, - fileName: autoName, - type: "asset", - source: `${lightContent}\n${darkContent}\n${metaInfo}`, - }); - } - // 删除原始的样式文件, 自动颜色主题因为删除, 永远不会生成两次 - delete bundle[key]; - } - } - }, - writeBundle() { - // 上传到服务器 - const server = process.env.SSH_SERVER; - const user = process.env.SSH_USER || "root"; - const theme_path = process.env.GITEA_THEME_PATH; - const gitea_path = process.env.GITEA_PATH; - const sync_tmpl = process.env.SYNC_TMPL === "true"; - if (server) { - try { - if (theme_path) { - const cmd = `scp dist/${prefix}*.css ${user}@${server}:${theme_path}`; - console.log("[themePlugin] exec:", cmd); - execSync(cmd, { stdio: "inherit" }); - } else { - console.log("[themePlugin] no GITEA_THEME_PATH, skip upload theme"); - } - if (gitea_path) { - if (sync_tmpl) { - const cmd = `scp -r templates ${user}@${server}:${gitea_path}`; - console.log("[themePlugin] exec:", cmd); - execSync(cmd, { stdio: "inherit" }); - } else { - console.log("[themePlugin] not set SYNC_TMPL=true, skip upload templates"); - } - } else { - console.log("[themePlugin] no GITEA_PATH, skip upload templates"); - } - } catch (_) { - // continue regardless of error - } - } else { - console.log("[themePlugin] no SSH_SERVER, skip upload"); - } - }, - }; -} diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 0000000..c8cf42a --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,37 @@ +/*! + * Copyright (c) https://github.com/lutinglt + * + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +declare namespace NodeJS { + interface ProcessEnv { + /** 开发环境主题名称 */ + DEV_THEME?: string; + /** 主题编译后上传的服务器地址 (通过 SCP 上传) */ + SSH_SERVER?: string; + /** 主题编译后上传的服务器用户名 (不支持密码, 请确保有 SSH 免密登录) */ + SSH_USER?: string; + /** 上传到服务器的主题目录 (请确保目录存在并使用绝对路径) */ + GITEA_THEME_PATH?: string; + /** 上传到服务器的 Gitea 目录 (请使用绝对路径) + * 用于上传模板, 翻译文件 + */ + GITEA_PATH?: string; + /** 是否同步模板 */ + SYNC_TMPL?: string; + } +} diff --git a/src/functions/index.ts b/src/functions/index.ts index 002676b..51d1e7c 100644 --- a/src/functions/index.ts +++ b/src/functions/index.ts @@ -18,4 +18,4 @@ */ export { scaleColorLight } from "./scss"; -export { extractVarName, fallbackVar } from "./var"; +export { extractVarName } from "./var"; diff --git a/src/functions/var.ts b/src/functions/var.ts index f71b3ed..7797dcc 100644 --- a/src/functions/var.ts +++ b/src/functions/var.ts @@ -17,18 +17,8 @@ * limitations under the License. */ -import type { CSSVarFunction } from "src/core/types"; - -type CSSFallbackVar = `var(--${string}, ${string})`; -/** 设置 CSS 变量的回退值 - * @param cssvar `var(--${string})` - * @param fallback - * @returns `var(--${string}, fallback)` - */ -export function fallbackVar(cssvar: CSSVarFunction, fallback: string): CSSFallbackVar { - const var_name = cssvar.replace("var(--", "").replace(")", ""); - return `var(--${var_name}, ${fallback})`; -} +import { assertVarName } from "@vanilla-extract/css"; +import type { CSSVarFunction } from "src/core"; type CSSVarName = `--${string}`; /** 提取 CSS 变量名 @@ -36,6 +26,7 @@ type CSSVarName = `--${string}`; * @returns `--${string}` */ export function extractVarName(cssvar: CSSVarFunction): CSSVarName { + assertVarName(cssvar); const var_name = cssvar.replace("var(--", "").replace(")", ""); return `--${var_name}`; } diff --git a/src/index.ts b/src/index.ts index 14c481a..cc87080 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,8 +17,13 @@ * limitations under the License. */ -export { defaultDarkChroma, defaultLightChroma } from "./core/chroma"; -export { defineTheme, type ThemeColor } from "./core/color"; -export type { Theme } from "./core/theme"; +import selectors from "./selectors"; + +export { createTheme, defineTheme, display2GithubColor, github2ThemeColor } from "./core"; +export type { DisplayColor, GitHubSyntax, GithubColor, ThemeColor } from "./core"; +export { extractVarName, scaleColorLight } from "./functions"; +export { createThemeMetaInfo } from "./styles"; +export { chromaVars, customThemeVars, otherThemeVars, syntaxVars, themeVars } from "./types"; export type { Ansi, Chroma, Console, Diff, Github, Message, Named, Other, Primary, Secondary } from "./types"; -export { otherThemeVars, themeVars } from "./types/vars"; +export { defineThemeConfig } from "./vite-plugin"; +export { selectors }; diff --git a/src/core/selectors.ts b/src/selectors.ts similarity index 75% rename from src/core/selectors.ts rename to src/selectors.ts index 8590450..50aee16 100644 --- a/src/core/selectors.ts +++ b/src/selectors.ts @@ -17,8 +17,14 @@ * limitations under the License. */ -export const root = ":root"; -export const emoji = `.emoji[aria-label="check mark"], +const root = ":root"; +const metaInfo = "gitea-theme-meta-info"; +const chroma = ".chroma"; +const codeMirror = ".code-editor-container"; +const overlayAppear = "overlayAppear"; +const overlayAppearDown = "overlayAppearDown"; +const overlayAppearUp = "overlayAppearUp"; +const emoji = `.emoji[aria-label="check mark"], .emoji[aria-label="currency exchange"], .emoji[aria-label="TOP arrow"], .emoji[aria-label="END arrow"], @@ -39,6 +45,14 @@ export const emoji = `.emoji[aria-label="check mark"], .emoji[aria-label="musical note"], .emoji[aria-label="musical notes"] `; -export const overlayAppear = "overlayAppear"; -export const overlayAppearDown = "overlayAppearDown"; -export const overlayAppearUp = "overlayAppearUp"; + +export default { + root, + metaInfo, + chroma, + codeMirror, + overlayAppear, + overlayAppearDown, + overlayAppearUp, + emoji, +} as const; diff --git a/src/styles/chroma.ts b/src/styles/chroma.ts new file mode 100644 index 0000000..7f3ff33 --- /dev/null +++ b/src/styles/chroma.ts @@ -0,0 +1,147 @@ +/*! + * Copyright (c) https://github.com/lutinglt + * + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createGlobalTheme, globalStyle, type StyleRule } from "@vanilla-extract/css"; +import { selectors } from "src"; +import { chromaVars, type Chroma } from "src/types"; + +function chromaStyle(selector: string, style: StyleRule): void; +function chromaStyle(selector: string[], style: StyleRule): void; +function chromaStyle(selector: string | string[], style: StyleRule): void { + globalStyle((Array.isArray(selector) ? selector : [selector]).map(s => `${selectors.chroma} ${s}`).join(","), style); +} +// 样式来源: https://github.com/go-gitea/gitea/blob/main/web_src/css/chroma/base.css +function createChromaBase(): void { + // LineTableTD + chromaStyle(".lntd", { verticalAlign: "top", padding: 0, margin: 0, border: 0 }); + // LineTable + chromaStyle(".lntable", { + borderSpacing: 0, + padding: 0, + margin: 0, + border: 0, + width: "auto", + overflow: "auto", + display: "block", + }); + // LineHighlight + chromaStyle(".hl", { display: "block", width: "100%" }); + // LineNumbersTable + chromaStyle([".lnt", ".ln"], { marginRight: "0.4em", padding: "0 0.4em" }); + // GenericStrong + chromaStyle(".gs", { fontWeight: "var(--font-weight-semibold)" }); + // GenericUnderline + chromaStyle(".gl", { textDecoration: "underline" }); +} +// 样式来源: https://github.com/alecthomas/chroma/blob/6428fb4e65f3c1493491571c8a6a8f1add1da822/types.go#L208 +function createChromaCode(): void { + // TextWhiteSpace + chromaStyle(".w", { color: chromaVars.textWhiteSpace }); + // Errorvoid + chromaStyle(".err", { color: chromaVars.err }); + // Keyword + chromaStyle(".k", { color: chromaVars.keyword.self }); + chromaStyle(".kc", { color: chromaVars.keyword.constant }); + chromaStyle(".kd", { color: chromaVars.keyword.declaration }); + chromaStyle(".kn", { color: chromaVars.keyword.namespace }); + chromaStyle(".kp", { color: chromaVars.keyword.pseudo }); + chromaStyle(".kr", { color: chromaVars.keyword.reserved }); + chromaStyle(".kt", { color: chromaVars.keyword.type }); + // Name + chromaStyle(".n", { color: chromaVars.name.self }); + chromaStyle(".na", { color: chromaVars.name.attribute }); + chromaStyle(".nb", { color: chromaVars.name.builtin }); + chromaStyle(".bp", { color: chromaVars.name.builtinPseudo }); + chromaStyle(".nc", { color: chromaVars.name.class }); + chromaStyle(".no", { color: chromaVars.name.constant }); + chromaStyle(".nd", { color: chromaVars.name.decorator }); + chromaStyle(".ni", { color: chromaVars.name.entity }); + chromaStyle(".ne", { color: chromaVars.name.exception }); + chromaStyle(".nf", { color: chromaVars.name.function }); + chromaStyle(".fm", { color: chromaVars.name.functionMagic }); + chromaStyle(".py", { color: chromaVars.name.property }); + chromaStyle(".nl", { color: chromaVars.name.label }); + chromaStyle(".nn", { color: chromaVars.name.namespace }); + chromaStyle(".nx", { color: chromaVars.name.other }); + chromaStyle(".nt", { color: chromaVars.name.tag }); + chromaStyle(".nv", { color: chromaVars.name.variable }); + chromaStyle(".vc", { color: chromaVars.name.variableClass }); + chromaStyle(".vg", { color: chromaVars.name.variableGlobal }); + chromaStyle(".vi", { color: chromaVars.name.variableInstance }); + chromaStyle(".vm", { color: chromaVars.name.variableMagic }); + // Literal + chromaStyle(".l", { color: chromaVars.literal.self }); + chromaStyle(".ld", { color: chromaVars.literal.date }); + // String + chromaStyle(".s", { color: chromaVars.string.self }); + chromaStyle(".sa", { color: chromaVars.string.affix }); + chromaStyle(".sb", { color: chromaVars.string.backtick }); + chromaStyle(".sc", { color: chromaVars.string.char }); + chromaStyle(".dl", { color: chromaVars.string.delimiter }); + chromaStyle(".sd", { color: chromaVars.string.doc }); + chromaStyle(".s2", { color: chromaVars.string.double }); + chromaStyle(".se", { color: chromaVars.string.escape }); + chromaStyle(".sh", { color: chromaVars.string.heredoc }); + chromaStyle(".si", { color: chromaVars.string.interpol }); + chromaStyle(".sx", { color: chromaVars.string.other }); + chromaStyle(".sr", { color: chromaVars.string.regex }); + chromaStyle(".s1", { color: chromaVars.string.single }); + chromaStyle(".ss", { color: chromaVars.string.symbol }); + // Number + chromaStyle(".m", { color: chromaVars.number.self }); + chromaStyle(".mb", { color: chromaVars.number.bin }); + chromaStyle(".mf", { color: chromaVars.number.float }); + chromaStyle(".mh", { color: chromaVars.number.hex }); + chromaStyle(".mi", { color: chromaVars.number.integer }); + chromaStyle(".il", { color: chromaVars.number.integerLong }); + chromaStyle(".mo", { color: chromaVars.number.oct }); + // Operator + chromaStyle(".o", { color: chromaVars.operator.self }); + chromaStyle(".ow", { color: chromaVars.operator.word }); + chromaStyle(".or", { color: chromaVars.operator.reserved }); + // Punctuation + chromaStyle(".p", { color: chromaVars.punctuation }); + // Comment + chromaStyle(".c", { color: chromaVars.comment.self }); + chromaStyle(".ch", { color: chromaVars.comment.hashbang }); + chromaStyle(".cm", { color: chromaVars.comment.multiline }); + chromaStyle(".cp", { color: chromaVars.comment.preproc }); + chromaStyle(".cpf", { color: chromaVars.comment.preprocFile }); + chromaStyle(".c1", { color: chromaVars.comment.single }); + chromaStyle(".cs", { color: chromaVars.comment.special }); + // Generic + chromaStyle(".g", { color: chromaVars.generic.self }); + chromaStyle(".gd", { color: chromaVars.generic.deleted }); + chromaStyle(".ge", { color: chromaVars.generic.emph }); + chromaStyle(".gr", { color: chromaVars.generic.error }); + chromaStyle(".gh", { color: chromaVars.generic.heading }); + chromaStyle(".gi", { color: chromaVars.generic.inserted }); + chromaStyle(".go", { color: chromaVars.generic.output }); + chromaStyle(".gp", { color: chromaVars.generic.prompt }); + chromaStyle(".gs", { color: chromaVars.generic.strong }); + chromaStyle(".gu", { color: chromaVars.generic.subheading }); + chromaStyle(".gt", { color: chromaVars.generic.traceback }); + chromaStyle(".gl", { color: chromaVars.generic.underline }); +} +/** 创建 chroma 样式 */ +export function createChroma(chroma: Chroma): void { + createChromaBase(); + createChromaCode(); + createGlobalTheme(selectors.chroma, chromaVars, chroma); +} diff --git a/src/styles/codemirror.ts b/src/styles/codemirror.ts new file mode 100644 index 0000000..079a08e --- /dev/null +++ b/src/styles/codemirror.ts @@ -0,0 +1,89 @@ +/*! + * Copyright (c) https://github.com/lutinglt + * + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createGlobalTheme, globalStyle, type StyleRule } from "@vanilla-extract/css"; +import { selectors } from "src"; +import { codeMirrorVars, type CodeMirror } from "src/types"; + +function codeMirrorStyle(selector: string, style: StyleRule): void; +function codeMirrorStyle(selector: string[], style: StyleRule): void; +function codeMirrorStyle(selector: string | string[], style: StyleRule): void { + globalStyle( + (Array.isArray(selector) ? selector : [selector]).map(s => `${selectors.codeMirror} ${s}`).join(","), + style + ); +} +// 样式来源: https://github.com/go-gitea/gitea/blob/ce089f498bce32305b2d9e8c6adfd8cb7c82f88f/web_src/css/modules/codeeditor.css#L506 +function createCodeMirrorBase(): void { + codeMirrorStyle(".tok-keyword", { color: codeMirrorVars.token.keyword }); + codeMirrorStyle(".tok-atom", { color: codeMirrorVars.token.atom }); + codeMirrorStyle(".tok-bool", { color: codeMirrorVars.token.bool }); + codeMirrorStyle(".tok-variableName", { color: codeMirrorVars.token.variableName }); + codeMirrorStyle(".tok-variableName2", { color: codeMirrorVars.token.variableName2 }); + codeMirrorStyle(".tok-propertyName", { color: codeMirrorVars.token.propertyName }); + codeMirrorStyle(".tok-typeName", { color: codeMirrorVars.token.typeName }); + codeMirrorStyle(".tok-className", { color: codeMirrorVars.token.className }); + codeMirrorStyle(".tok-namespace", { color: codeMirrorVars.token.namespace }); + codeMirrorStyle(".tok-macroName", { color: codeMirrorVars.token.macroName }); + codeMirrorStyle(".tok-labelName", { color: codeMirrorVars.token.labelName }); + codeMirrorStyle(".tok-number", { color: codeMirrorVars.token.number }); + codeMirrorStyle(".tok-string", { color: codeMirrorVars.token.string }); + codeMirrorStyle(".tok-string2", { color: codeMirrorVars.token.string2 }); + codeMirrorStyle(".tok-operator", { color: codeMirrorVars.token.operator }); + codeMirrorStyle(".tok-punctuation", { color: codeMirrorVars.token.punctuation }); + codeMirrorStyle(".tok-comment", { color: codeMirrorVars.token.comment }); + codeMirrorStyle(".tok-meta", { color: codeMirrorVars.token.meta }); + codeMirrorStyle(".tok-invalid", { color: codeMirrorVars.token.invalid }); + codeMirrorStyle(".tok-link", { color: codeMirrorVars.token.link }); + codeMirrorStyle(".tok-heading", { color: codeMirrorVars.token.heading }); + codeMirrorStyle(".tok-emphasis", { color: codeMirrorVars.token.emphasis }); + codeMirrorStyle(".tok-strong", { color: codeMirrorVars.token.strong }); + codeMirrorStyle(".tok-inserted", { color: codeMirrorVars.token.inserted }); + codeMirrorStyle(".tok-deleted", { color: codeMirrorVars.token.deleted }); +} +// 样式来源: https://github.com/go-gitea/gitea/blob/ce089f498bce32305b2d9e8c6adfd8cb7c82f88f/web_src/css/modules/codeeditor.css#L533 +function createCodeMirrorSpecific(): void { + // 语言样式 + function langStyle(lang: string, style: StyleRule): void { + globalStyle(`${selectors.codeMirror}[data-language="${lang}"] .tok-propertyName`, style); + } + langStyle("json", { color: codeMirrorVars.language.json }); + langStyle("json5", { color: codeMirrorVars.language.json5 }); + langStyle("yaml", { color: codeMirrorVars.language.yaml }); + langStyle("css", { color: codeMirrorVars.language.css }); + langStyle("html", { color: codeMirrorVars.language.html }); + langStyle("xml", { color: codeMirrorVars.language.xml }); + // 特殊样式 + // 语法中导入部分的变量变为命名空间样式 + codeMirrorStyle(".tok-punctuation+.tok-variableName.tok-definition", { color: codeMirrorVars.token.namespace }); + // 避免锚中变量, 变量后接的是 .tok-operator + codeMirrorStyle(".tok-keyword+.tok-variableName.tok-definition:has(+.tok-punctuation)", { + color: codeMirrorVars.token.namespace, + }); + // keywork + variableName + punctuation + typeName 这种情况还原变量颜色 + codeMirrorStyle(".tok-keyword+.tok-variableName.tok-definition:has(+.tok-punctuation+.tok-typeName)", { + color: codeMirrorVars.token.variableName, + }); +} + +/** 创建 CodeMirror 样式 */ +export function createCodeMirror(codeMirror: CodeMirror): void { + createCodeMirrorBase(); + createCodeMirrorSpecific(); + createGlobalTheme(selectors.codeMirror, codeMirrorVars, codeMirror); +} diff --git a/styles/components/editor.ts b/src/styles/index.ts similarity index 60% rename from styles/components/editor.ts rename to src/styles/index.ts index 73100fd..57d5737 100644 --- a/styles/components/editor.ts +++ b/src/styles/index.ts @@ -17,17 +17,6 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; - -export const monaco = css` - .monaco-editor { - --vscode-editor-background: ${themeVars.color.body} !important; - --vscode-editorGutter-background: ${themeVars.color.body} !important; - // 滚动时固定在顶部的行 - .sticky-widget { - background: ${themeVars.color.body} !important; - box-shadow: 0 1px 0 ${themeVars.color.secondary.self} !important; - width: 100% !important; - } - } -`; +export { createChroma } from "./chroma"; +export { createCodeMirror } from "./codemirror"; +export { createThemeMetaInfo, type ColorblindType, type GiteaThemeMeta } from "./meta"; diff --git a/themes/pink-light.css.ts b/src/styles/meta.ts similarity index 50% rename from themes/pink-light.css.ts rename to src/styles/meta.ts index 259e6ed..228a3ee 100644 --- a/themes/pink-light.css.ts +++ b/src/styles/meta.ts @@ -17,29 +17,32 @@ * limitations under the License. */ -/** - * @author lutinglt - */ +import { createGlobalTheme } from "@vanilla-extract/css"; +import { selectors } from "src"; -import { defineTheme } from "src"; -import { display2GithubColor, type DisplayColor } from "src/core/display"; -import { github2ThemeColor } from "src/core/github"; -import { lightGithubColors } from "themes/light"; - -export const pinkLightDisplayColors: DisplayColor = { - num0: "#ffe5f1", - num1: "#fdc9e2", - num2: "#f8a5cf", - num3: "#f184bc", - num4: "#e55da5", - num5: "#ce2c85", - num6: "#b12f79", - num7: "#8e2e66", - num8: "#6e2b53", - num9: "#4d233d", +export type ColorblindType = "red-green" | "blue-yellow"; +export type GiteaThemeMeta = { + colorScheme: "dark" | "light" | "auto"; + displayName: string; + colorblindType?: ColorblindType; }; - -export const pinkLightGithubColors = display2GithubColor(pinkLightDisplayColors, lightGithubColors); -export const pinkLightColors = github2ThemeColor(pinkLightGithubColors); - -export default defineTheme(pinkLightColors); +/** 创建 Gitea 主题元信息 */ +export function createThemeMetaInfo(meta: GiteaThemeMeta) { + createGlobalTheme(selectors.metaInfo, { + theme: { + color: { + scheme: meta.colorScheme, + }, + display: { + name: meta.displayName, + }, + ...(meta.colorblindType !== undefined + ? { + colorblind: { + type: meta.colorblindType, + }, + } + : {}), + }, + }); +} diff --git a/src/types/color/chroma.ts b/src/types/color/chroma.ts index 378a0fe..cc21bf7 100644 --- a/src/types/color/chroma.ts +++ b/src/types/color/chroma.ts @@ -210,6 +210,10 @@ export const chroma = { * @example and or not in is */ word: null, + /** 保留运算符 + * @example not in is + */ + reserved: null, }, /** 标点符号 * @example , . : ; ( ) [ ] { } diff --git a/src/types/color/codemirror.ts b/src/types/color/codemirror.ts new file mode 100644 index 0000000..aa6b609 --- /dev/null +++ b/src/types/color/codemirror.ts @@ -0,0 +1,150 @@ +/*! + * Copyright (c) https://github.com/lutinglt + * + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// 注释来自 AI +export const codeMirror = { + token: { + /** 关键字 + * @example if else return function var let const + */ + keyword: null, + /** 原子值 + * @example true false null undefined + */ + atom: null, + /** 布尔值 + * @example true false + */ + bool: null, + /** 变量名 + * @example const foo = 1 中的 foo + */ + variableName: null, + /** 二级作用域变量名 + * @example 函数参数、局部变量 + */ + variableName2: null, + /** 属性名 + * @example obj.name 中的 name + */ + propertyName: null, + /** 类型名 + * @example TypeScript 的 type、interface 名 + */ + typeName: null, + /** 类名 + * @example class MyClass 中的 MyClass + */ + className: null, + /** 命名空间 + * @example namespace Foo 中的 Foo + */ + namespace: null, + /** 宏名 + * @example C 的 #define 宏名, Rust 的 macro_rules! + */ + macroName: null, + /** 标签名 + * @example goto label:, C 的 switch case 标签 + */ + labelName: null, + /** 数字字面量 + * @example 123 3.14 0xFF + */ + number: null, + /** 字符串字面量 + * @example "hello" 'world' + */ + string: null, + /** 二级字符串 + * @example 模板字符串、正则字面量 + */ + string2: null, + /** 运算符 + * @example + - * / = == && + */ + operator: null, + /** 标点符号 + * @example , . : ; ( ) [ ] { } + */ + punctuation: null, + /** 注释 + * @example // 单行注释 多行注释 + */ + comment: null, + /** 元信息 + * @example 预处理器指令、装饰器标记 + */ + meta: null, + /** 无效/错误语法 + * @example 语法错误的标记 + */ + invalid: null, + /** 链接 + * @example Markdown 中的 [link](url) + */ + link: null, + /** 标题 + * @example Markdown 中的 # Heading + */ + heading: null, + /** 强调 (斜体) + * @example Markdown 中的 *italic* + */ + emphasis: null, + /** 加粗 + * @example Markdown 中的 **bold** + */ + strong: null, + /** 新增内容 + * @example diff 中的 + 新增行 + */ + inserted: null, + /** 删除内容 + * @example diff 中的 - 删除行 + */ + deleted: null, + }, + language: { + /** JSON 语言中属性名的颜色 + * @example {"key": "value"} 中的 key + */ + json: null, + /** JSON5 语言中属性名的颜色 + * @example {unquotedKey: 'value'} 中的 unquotedKey + */ + json5: null, + /** YAML 语言中属性名的颜色 + * @example key: value 中的 key + */ + yaml: null, + /** CSS 语言中属性名的颜色 + * @example .selector { property: value; } 中的 property + */ + css: null, + /** HTML 语言中属性名的颜色 + * @example
中的 class + */ + html: null, + /** XML 语言中属性名的颜色 + * @example 中的 attr + */ + xml: null, + }, +}; diff --git a/src/types/color/github.ts b/src/types/color/github.ts index 49fc7f8..c4f2e64 100644 --- a/src/types/color/github.ts +++ b/src/types/color/github.ts @@ -254,6 +254,22 @@ export const github = { }, }, }, + controlTrack: { + bgColor: { + /** 背景色 + * @compact_menu `smallCompactMenu` 背景色 + */ + rest: null, + }, + }, + controlKnob: { + bgColor: { + /** 背景色 + * @compact_menu `smallCompactMenu` 激活项背景色 + */ + rest: null, + }, + }, shadow: { floating: { /** 悬浮阴影 diff --git a/src/types/color/index.ts b/src/types/color/index.ts index c395b63..2f0be01 100644 --- a/src/types/color/index.ts +++ b/src/types/color/index.ts @@ -17,11 +17,29 @@ * limitations under the License. */ -export { chroma } from "./chroma"; -export { ansi, console } from "./console"; -export { diff } from "./diff"; -export { github } from "./github"; -export { primary, secondary } from "./main"; -export { message } from "./message"; -export { named } from "./named"; -export { other, otherAuto } from "./other"; +import { chroma } from "./chroma"; +import { codeMirror } from "./codemirror"; +import { ansi, console } from "./console"; +import { diff } from "./diff"; +import { github } from "./github"; +import { primary, secondary } from "./main"; +import { message } from "./message"; +import { named } from "./named"; +import { other, otherAuto } from "./other"; +import { syntax } from "./syntax"; + +export default { + chroma, + ansi, + codeMirror, + console, + diff, + github, + primary, + secondary, + message, + named, + other, + otherAuto, + syntax, +}; diff --git a/src/types/color/syntax.ts b/src/types/color/syntax.ts new file mode 100644 index 0000000..e32be14 --- /dev/null +++ b/src/types/color/syntax.ts @@ -0,0 +1,104 @@ +/*! + * Copyright (c) https://github.com/lutinglt + * + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// 注释来自 AI +export const syntax = { + /** 关键字 */ + keyword: null, + /** 布尔值 */ + bool: null, + /** 控制流关键字 */ + control: null, + /** 标识符名称 */ + name: null, + /** 类型 */ + type: null, + /** 数字 */ + number: null, + /** 运算符 */ + operator: null, + /** 正则表达式 */ + regexp: null, + /** 字符串 */ + string: null, + /** 注释 */ + comment: null, + /** 无效标记 */ + invalid: null, + /** 链接 */ + link: null, + /** 标签 */ + tag: null, + /** 属性 */ + attribute: null, + /** 属性 */ + property: null, + /** 变量 */ + variable: null, + /** 特殊字符串 */ + stringSpecial: "color-syntax-string-special", + /** 转义字符 */ + escape: null, + /** 实体 */ + entity: null, + /** 预处理器注释 */ + preproc: null, + /** 预处理器文件注释 */ + preprocFile: "color-syntax-preproc-file", + /** 装饰器 */ + decorator: null, + /** 命名空间 */ + namespace: null, + /** 标识符伪名称 */ + namePseudo: "color-syntax-name-pseudo", + /** 特殊注释 */ + commentSpecial: "color-syntax-comment-special", + /** 文本 */ + text: null, + /** 备用文本颜色 */ + textAlt: "color-syntax-text-alt", + /** 标点符号 */ + punctuation: null, + /** 空白字符 */ + whitespace: null, + /** 差异前景色 */ + diffFg: "color-syntax-diff-fg", + /** 删除内容背景色 */ + deletedBg: "color-syntax-deleted-bg", + /** 插入内容背景色 */ + insertedBg: "color-syntax-inserted-bg", + /** 斜体强调 */ + emph: null, + /** 粗体强调 */ + strong: null, + /** 标题 */ + heading: null, + /** 子标题 */ + subheading: null, + /** 输出文本 */ + output: null, + /** 提示符 */ + prompt: null, + /** 堆栈跟踪 */ + traceback: null, + /** 匹配括号背景色 */ + matchingBracketBg: "color-syntax-matching-bracket-bg", + /** 不匹配括号背景色 */ + nonmatchingBracketBg: "color-syntax-nonmatching-bracket-bg", +}; diff --git a/src/types/index.ts b/src/types/index.ts index a36a00e..a261549 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -17,11 +17,15 @@ * limitations under the License. */ -import type { MapLeafNodes } from "src/core/types"; -import * as color from "./color"; +import type { MapLeafNodes } from "src/core"; +import color from "./color"; -/** 代码高亮色 */ +/** GitHub 预览代码高亮色 */ export type Chroma = MapLeafNodes; +/** GitHub 编辑代码高亮色 */ +export type CodeMirror = MapLeafNodes; +/** Gitea 代码高亮色 */ +export type Syntax = MapLeafNodes; /** 主色调(强调色) */ export type Primary = MapLeafNodes; /** 副色调(边框色) */ @@ -40,3 +44,5 @@ export type Diff = MapLeafNodes; export type Other = MapLeafNodes; /** 仅限本主题的 Github 颜色 */ export type Github = MapLeafNodes; + +export { chromaVars, codeMirrorVars, customThemeVars, otherThemeVars, syntaxVars, themeVars } from "./vars"; diff --git a/src/types/vars.ts b/src/types/vars.ts index 5b73a0f..598f186 100644 --- a/src/types/vars.ts +++ b/src/types/vars.ts @@ -18,7 +18,7 @@ */ import { createGlobalThemeContract } from "@vanilla-extract/css"; -import * as color from "./color"; +import color from "./color"; function varMapper(prefix: string | null = null) { return (value: string | null, path: string[]) => { @@ -33,8 +33,8 @@ function varMapper(prefix: string | null = null) { } const vars = { + /** Gitea 主题的属性 */ isDarkTheme: "is-dark-theme", - chroma: color.chroma, color: { ...color.other, ...color.message, @@ -60,13 +60,9 @@ const customVars = { org: { repolistColumns: "org-repolist-columns", userlistColumns: "org-userlist-columns" }, }; -const themeInfo = { - version: null, -}; - export const themeVars = createGlobalThemeContract(vars, varMapper()); export const otherThemeVars = createGlobalThemeContract(otherVars, varMapper()); export const customThemeVars = createGlobalThemeContract(customVars, varMapper("custom")); -export const themeInfoVars = createGlobalThemeContract(themeInfo, varMapper("theme")); - -export { css } from "@linaria/core"; +export const chromaVars = createGlobalThemeContract(color.chroma, varMapper("chroma")); +export const codeMirrorVars = createGlobalThemeContract(color.codeMirror, varMapper("codeMirror")); +export const syntaxVars = createGlobalThemeContract(color.syntax, varMapper("color-syntax")); diff --git a/src/vite-plugin.ts b/src/vite-plugin.ts new file mode 100644 index 0000000..c5db647 --- /dev/null +++ b/src/vite-plugin.ts @@ -0,0 +1,323 @@ +/*! + * Copyright (c) https://github.com/lutinglt + * + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin"; +import { execSync } from "node:child_process"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { pathToFileURL } from "node:url"; +import { rolldown } from "rolldown"; +import type { Theme } from "src/core"; +import type { ColorblindType, GiteaThemeMeta } from "src/styles"; +import type { PluginOption } from "vite"; + +type ThemeEntry = { + /** 主题名称 */ + themeName: string; + /** Gitea 主题 元数据 */ + meta: GiteaThemeMeta; + /** 主题颜色 */ + theme: Theme; +}; + +type AutoThemeEntry = { darkThemeName: string; lightThemeName: string }; + +type ThemeConfig = { + /** 主题名称, 用于生成文件名, 未指定时取 themes 中的键名 */ + themeName?: string; + /** 显示名称, 用于 Gitea UI 显示的名称 + * - 未指定时根据 themeName 生成 + * - 指定时将覆盖生成的名称, 仅包含主题插件前缀, 不包含主题系列名称 + */ + displayName?: string; + /** 色盲类型, 仅用于声明主题为色盲主题 */ + colorblindType?: ColorblindType; + theme: Theme; +}; + +type Themes = + | { dark: ThemeConfig; [themeKeyName: string]: ThemeConfig } + | { light: ThemeConfig; [themeKeyName: string]: ThemeConfig }; + +type ThemeSeries = { + /** 主题系列名称, 做为前缀用于生成文件名和显示名称 */ + themeSeriesName: string; + /** 主题系列自动颜色主题配置 */ + autoTheme?: { + /** 自动颜色主题用于 Gitea UI 显示的名称 */ + displayName?: string; + /** 色盲类型, 仅用于声明主题为色盲主题 */ + colorblindType?: ColorblindType; + }; + /** 必须至少声明 dark/light 其中一个 */ + themes: Themes; +}; + +/** + * 定义主题配置, 规定入口文件必须默认导出此函数的返回值 + * 类似 vite 的 defineConfig, 提供类型约束 + */ +export function defineThemeConfig(config: ThemeSeries[]): ThemeSeries[] { + // 检查主题系列名称是否重复 + const names = config.map(c => c.themeSeriesName); + const duplicates = names.filter((name, index) => names.indexOf(name) !== index); + if (duplicates.length > 0) { + throw new Error(`Duplicate themeSeriesName found: ${[...new Set(duplicates)].join(", ")}`); + } + return config; +} + +/** Gitea GitHub Theme 主题插件: 解析入口文件, 生成主题 */ +export function giteaGitHubThemePlugin(): PluginOption[] { + const PREFIX = "theme-github-"; + let themeEntries: ThemeEntry[]; + const autoThemeEntries = new Map(); + + return [ + // createGlobalTheme 直接创建变量时, 仅使用对象值 + vanillaExtractPlugin({ identifiers: ({ debugId }) => `${debugId}` }), + { + name: "themePlugin", + + async config(userConfig) { + const root = userConfig.root || process.cwd(); + const entry = path.join(root, "theme.config.ts"); + const entryPath = path.isAbsolute(entry) ? entry : path.resolve(root, entry); + + // 1. 创建临时目录 + const hash = crypto.randomBytes(6).toString("hex"); + const tmpDir = path.join(userConfig.build?.outDir || "dist", `.gitea-theme-tmp-${hash}`); + fs.mkdirSync(tmpDir, { recursive: true }); + + // 2. 使用 rolldown 打包入口文件为 ESM, 以便在 Node.js 中 import + // 第三方包标记为外部依赖, 运行时从项目的 node_modules 解析 + const resolveAlias: Record = {}; + if (userConfig.resolve?.alias) { + const aliases = userConfig.resolve.alias; + if (Array.isArray(aliases)) { + for (const alias of aliases) { + if (typeof alias.find === "string") { + resolveAlias[alias.find] = alias.replacement; + } + } + } else { + Object.assign(resolveAlias, aliases); + } + } + + const tmpBundle = path.join(tmpDir, "_themes_entry.mjs"); + const bundle = await rolldown({ + input: entryPath, + platform: "node", + // 第三方包标记为外部依赖, 运行时从项目的 node_modules 解析, 避免无谓打包提速 + external: id => { + if (id.startsWith(".") || path.isAbsolute(id)) return false; + // alias 路径 (如 "src/core", "themes/dark", "styles") 是项目内部模块, 需要打包 + if (Object.keys(resolveAlias).some(alias => id === alias || id.startsWith(alias + "/"))) return false; + return true; + }, + resolve: { + alias: resolveAlias, + extensions: [".ts", ".js"], + }, + }); + const { output } = await bundle.generate({ format: "esm" }); + fs.writeFileSync(tmpBundle, output[0].code); + await bundle.close(); + + // 3. 动态导入打包后的入口文件, 获取主题配置 + const themeConfig: ThemeSeries[] = (await import(pathToFileURL(tmpBundle).href)).default; + + if (!themeConfig || typeof themeConfig !== "object") { + throw new Error("[themePlugin] Entry file must default-export a defineThemeConfig result"); + } + + /** 辅助函数: 按 "-" 分割字符串并首字母大写 */ + function kebabToTitle(str: string): string { + return str + .split("-") + .map(word => word.charAt(0).toUpperCase() + word.slice(1)) + .join(" "); + } + /** 辅助函数: 将主题名称转为正式主题名称 */ + function buildFullThemeName(themeSeries: ThemeSeries, themeName: string): string { + return `${PREFIX}${themeSeries.themeSeriesName !== "base" ? `${themeSeries.themeSeriesName}-` : ""}${themeName}`; + } + /** 辅助函数: 将显示名称转为正式名称 */ + function buildFullDisplayName(themeSeries: ThemeSeries, displayName: string): string { + return `GitHub${themeSeries.themeSeriesName !== "base" ? ` ${kebabToTitle(themeSeries.themeSeriesName)}` : ""} ${kebabToTitle(displayName)}`; + } + + // 4. 解析主题条目 + themeEntries = themeConfig.flatMap(themeSeries => + Object.entries(themeSeries.themes).map(([themeKeyName, entry]) => { + const name = entry.themeName ?? themeKeyName; + // 直接修改主题名用于自动主题生成使用, 避免重复计算 + entry.themeName = buildFullThemeName(themeSeries, name); + return { + themeName: entry.themeName, + meta: { + colorScheme: entry.theme.isDarkTheme ? "dark" : "light", + displayName: entry.displayName + ? `GitHub ${entry.displayName}` + : buildFullDisplayName(themeSeries, name), + colorblindType: entry.colorblindType, + }, + theme: entry.theme, + }; + }) + ); + + // 5. 为每个主题生成临时文件 + const input: Record = {}; + for (const entry of themeEntries) { + const { themeName, theme } = entry; + // 创建颜色主题的 css.ts 文件, vanilla-extract 需要这个文件后缀名并生成 css + const tmpCssTs = `${themeName}.css.ts`; + fs.writeFileSync( + path.join(tmpDir, `${tmpCssTs}`), + [ + `import { createTheme, createThemeMetaInfo } from "src";`, + `createThemeMetaInfo(${JSON.stringify(entry.meta)});`, + `createTheme(${JSON.stringify(theme)});`, + ].join("\n") + ); + // 生成主题入口的 .ts 文件, 合并样式和颜色主题 + const tmpInputTs = path.join(tmpDir, `${themeName}.ts`); + fs.writeFileSync(tmpInputTs, [`import "styles";`, `import "./${tmpCssTs}";`].join("\n")); + + input[themeName] = tmpInputTs; + } + + // 6. 生成自动主题入口 + for (const themeSeries of themeConfig) { + if (themeSeries.themes.dark && themeSeries.themes.light) { + const themeName = buildFullThemeName(themeSeries, "auto"); + const meta: GiteaThemeMeta = { + colorScheme: "auto", + displayName: themeSeries.autoTheme?.displayName + ? `GitHub ${themeSeries.autoTheme.displayName}` + : buildFullDisplayName(themeSeries, "auto"), + colorblindType: themeSeries.autoTheme?.colorblindType, + }; + const tmpCssTs = `${themeName}.css.ts`; + fs.writeFileSync( + path.join(tmpDir, `${tmpCssTs}`), + [`import { createThemeMetaInfo } from "src";`, `createThemeMetaInfo(${JSON.stringify(meta)});`].join("\n") + ); + const tmpInputTs = path.join(tmpDir, `${themeName}.ts`); + fs.writeFileSync(tmpInputTs, `import "./${tmpCssTs}";`); + autoThemeEntries.set(themeName, { + darkThemeName: themeSeries.themes.dark.themeName!, + lightThemeName: themeSeries.themes.light.themeName!, + }); + + input[themeName] = tmpInputTs; + } + } + + // 返回合并配置, 注入 rollup input + return { + build: { + rolldownOptions: { + input, + output: { assetFileNames: "[name].[ext]" }, + checks: { + // 主题构建一直过慢, 不再检查各插件消耗时间 + pluginTimings: false, + }, + }, + }, + }; + }, + + generateBundle(this, _, bundle) { + let styles = ""; + for (const [key, value] of Object.entries(bundle)) { + if (value.type === "chunk") { + delete bundle[key]; // 删除 chunk + } else { + // 样式文件是通过入口导入的, 没有原始文件名 + if (value.originalFileNames.length === 0) { + // 收集所有的样式文件(逻辑上只有一个) + // vite 会在尾部添加注释, 后续会合并到颜色主题, 此处需要删除注释 + styles += value.source.toString().replace("/*$vite$:1*/", ""); + delete bundle[key]; + } + } + } + // 生成所有的主题文件 + for (const [_key, value] of Object.entries(bundle)) { + // 仅为了类型检查, 逻辑上输出中全是 asset 类型 + // vite8 中 bundle 删除后依旧有 styles.css, 追加判断需要有入口的原始文件名 + if (value.type === "asset" && value.originalFileNames.length > 0) { + // 合并样式文件和主题信息 + const themeName = path.basename(value.fileName, ".css"); + const autoTheme = autoThemeEntries.get(themeName); + if (autoTheme) { + value.source = [ + `@import "./${autoTheme.darkThemeName}.css" (prefers-color-scheme: dark);`, + `@import "./${autoTheme.lightThemeName}.css" (prefers-color-scheme: light);`, + `${value.source.toString()}`, + ].join("\n"); + } else { + value.source = `${value.source.toString()}${styles}`; + } + } + } + }, + + writeBundle() { + // 上传到服务器 + const server = process.env.SSH_SERVER; + const user = process.env.SSH_USER || "root"; + const theme_path = process.env.GITEA_THEME_PATH; + const gitea_path = process.env.GITEA_PATH; + const sync_tmpl = process.env.SYNC_TMPL === "true"; + if (server) { + try { + if (theme_path) { + const cmd = `scp dist/${PREFIX}*.css ${user}@${server}:${theme_path}`; + console.log("[themePlugin] exec:", cmd); + execSync(cmd, { stdio: "inherit" }); + } else { + console.log("[themePlugin] no GITEA_THEME_PATH, skip upload theme"); + } + if (gitea_path) { + if (sync_tmpl) { + const cmd = `scp -r templates ${user}@${server}:${gitea_path}`; + console.log("[themePlugin] exec:", cmd); + execSync(cmd, { stdio: "inherit" }); + } else { + console.log("[themePlugin] not set SYNC_TMPL=true, skip upload templates"); + } + } else { + console.log("[themePlugin] no GITEA_PATH, skip upload templates"); + } + } catch (e) { + console.warn("[themePlugin] upload failed:", e); + } + } else { + console.log("[themePlugin] no SSH_SERVER, skip upload"); + } + }, + }, + ]; +} diff --git a/themes/pink-soft-dark.css.ts b/styles/common/after.ts similarity index 58% rename from themes/pink-soft-dark.css.ts rename to styles/common/after.ts index 88b14fe..0890a9b 100644 --- a/themes/pink-soft-dark.css.ts +++ b/styles/common/after.ts @@ -17,17 +17,18 @@ * limitations under the License. */ -/** - * @author lutinglt +import type { StyleRule } from "@vanilla-extract/css"; +import { otherThemeVars, themeVars } from "src"; + +/** 激活项后缀样式 + * @example 菜单激活子项前面的竖线, 方便识别 */ - -import { defineTheme } from "src"; -import { display2GithubColor } from "src/core/display"; -import { github2ThemeColor } from "src/core/github"; -import { softDarkGithubColors } from "themes/soft-dark"; -import { pinkDarkDisplayColors } from "./pink-dark.css"; - -export const pinkSoftDarkGithubColors = display2GithubColor(pinkDarkDisplayColors, softDarkGithubColors, true); -export const pinkSoftDarkColors = github2ThemeColor(pinkSoftDarkGithubColors); - -export default defineTheme(pinkSoftDarkColors); +export const activeItemAfterStyle = { + backgroundColor: themeVars.github.borderColor.accent.emphasis, + borderRadius: otherThemeVars.border.radius, + height: "24px", + left: "-8px", + position: "absolute", + top: "calc(50% - 12px)", + width: "4px", +} satisfies StyleRule; diff --git a/src/core/styles.ts b/styles/common/animation.ts similarity index 93% rename from src/core/styles.ts rename to styles/common/animation.ts index 80da8b0..57f5bf2 100644 --- a/src/core/styles.ts +++ b/styles/common/animation.ts @@ -17,8 +17,8 @@ * limitations under the License. */ -import { type StyleRule } from "@vanilla-extract/css"; -import * as selectors from "./selectors"; +import type { StyleRule } from "@vanilla-extract/css"; +import { selectors } from "src"; // 出现动画 export const animation = { @@ -27,12 +27,14 @@ export const animation = { animationFillMode: "forwards", animationTimingFunction: "ease-in", } satisfies StyleRule; + // 向下出现动画 export const animationDown = { animation: selectors.overlayAppearDown, animationDuration: "200ms", animationTimingFunction: "cubic-bezier(0.33, 1, 0.68, 1)", } satisfies StyleRule; + // 向上出现动画 export const animationUp = { animation: selectors.overlayAppearUp, diff --git a/themes/pink-dark.css.ts b/styles/common/button.ts similarity index 51% rename from themes/pink-dark.css.ts rename to styles/common/button.ts index b8a9d80..d6411ca 100644 --- a/themes/pink-dark.css.ts +++ b/styles/common/button.ts @@ -17,29 +17,20 @@ * limitations under the License. */ -/** - * @author lutinglt - */ +import type { StyleRule } from "@vanilla-extract/css"; +import { themeVars } from "src"; -import { defineTheme } from "src"; -import { display2GithubColor, type DisplayColor } from "src/core/display"; -import { github2ThemeColor } from "src/core/github"; -import { darkGithubColors } from "themes/dark"; +/** 主色调按钮样式 */ +export const primaryButtonStyle = { + color: themeVars.github.button.primary.fgColor.rest, + backgroundColor: themeVars.github.button.primary.bgColor.rest, + borderColor: themeVars.github.button.primary.borderColor.rest, + boxShadow: themeVars.github.shadow.resting.small, +} satisfies StyleRule; -export const pinkDarkDisplayColors: DisplayColor = { - num0: "#2d1524", - num1: "#451c35", - num2: "#65244a", - num3: "#842a5d", - num4: "#ac2f74", - num5: "#d34591", - num6: "#e57bb2", - num7: "#ec8dbd", - num8: "#f4a9cd", - num9: "#f9bed9", -}; - -export const pinkDarkGithubColors = display2GithubColor(pinkDarkDisplayColors, darkGithubColors); -export const pinkDarkColors = github2ThemeColor(pinkDarkGithubColors); - -export default defineTheme(pinkDarkColors); +/** 主色调按钮悬停样式 */ +export const primaryButtonHoverStyle = { + color: themeVars.github.button.primary.fgColor.rest, + backgroundColor: themeVars.github.button.primary.bgColor.hover, + borderColor: themeVars.github.button.primary.borderColor.hover, +} satisfies StyleRule; diff --git a/styles/common/index.ts b/styles/common/index.ts new file mode 100644 index 0000000..1b6f524 --- /dev/null +++ b/styles/common/index.ts @@ -0,0 +1,23 @@ +/*! + * Copyright (c) https://github.com/lutinglt + * + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { activeItemAfterStyle } from "./after"; +export { animation, animationDown, animationUp } from "./animation"; +export { primaryButtonHoverStyle, primaryButtonStyle } from "./button"; +export { botLabelStyle, labelStyle } from "./label"; diff --git a/eslint.config.js b/styles/common/label.ts similarity index 65% rename from eslint.config.js rename to styles/common/label.ts index d4a0bd2..19c8027 100644 --- a/eslint.config.js +++ b/styles/common/label.ts @@ -17,17 +17,16 @@ * limitations under the License. */ -import js from "@eslint/js"; -import { defineConfig } from "eslint/config"; -import globals from "globals"; -import tseslint from "typescript-eslint"; +import type { StyleRule } from "@vanilla-extract/css"; -export default defineConfig({ - ignores: ["dist"], - extends: [js.configs.recommended, ...tseslint.configs.recommended], - files: ["**/*.{ts}"], - languageOptions: { - ecmaVersion: 2020, - globals: globals.browser, - }, -}); +/** 基本标签样式 */ +export const labelStyle = { + padding: "0px 6px", +} satisfies StyleRule; + +/** bot 标签样式 */ +export const botLabelStyle = { + height: "20px", + padding: "0 6px !important", + marginLeft: "4px", +} satisfies StyleRule; diff --git a/styles/components/actions/action_svg.ts b/styles/components/actions/action_svg.ts index 14932b6..1a0b8bc 100644 --- a/styles/components/actions/action_svg.ts +++ b/styles/components/actions/action_svg.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; // 修改 action 页面 svg 颜色 (主要为了覆盖工作流状态中的白色图标) export const actionSVG = css` diff --git a/styles/components/actions/actions.ts b/styles/components/actions/actions.ts index d03ae3e..3864fd6 100644 --- a/styles/components/actions/actions.ts +++ b/styles/components/actions/actions.ts @@ -17,13 +17,14 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; // 仓库 Actions 页面 export const actions = css` - // 避免锚中设置界面里的 Actions + /* 避免锚中设置界面里的 Actions */ .page-content.repository.actions:not(.settings) .flex-container { - // Actions 列表 + /* Actions 列表 */ .flex-container-nav:before { content: "Actions"; display: block; @@ -32,9 +33,9 @@ export const actions = css` margin-top: 6px; margin-bottom: 8px; } - // 工作流列表 + /* 工作流列表 */ .flex-container-main { - // 工作流列表标题栏菜单 + /* 工作流列表标题栏菜单 */ .ui.top.attached.header { padding: 16px; &:has(+ .ui.info.attached.message) { @@ -44,17 +45,17 @@ export const actions = css` color: ${themeVars.color.text.light.num1}; } } - // 事件触发器 + /* 事件触发器 */ .ui.info.attached.message { padding: 18px 16px; - // 事件触发器按钮 + /* 事件触发器按钮 */ .ui.mini.button { padding: 3px 12px; min-height: 27px; font-size: 12px; } } - // 工作流列表 + /* 工作流列表 */ .ui.attached.segment { padding: 0; border: 0; @@ -65,7 +66,7 @@ export const actions = css` border-top: 0; font-size: 12px; - // 分支标签按钮 + /* 分支标签按钮 */ .run-list-ref { background-color: ${themeVars.github.bgColor.accent.muted}; color: ${themeVars.github.fgColor.accent}; @@ -78,7 +79,7 @@ export const actions = css` text-decoration-line: underline !important; } } - // 标签右侧任务信息 + /* 标签右侧任务信息 */ .run-list-item-right { color: ${themeVars.color.text.light.num1}; } @@ -132,11 +133,11 @@ export const label = css` export const runWorkflow = css` #runWorkflowDispatchForm { font-size: 12px; - // 描述类标签 + /* 描述类标签 */ .ui.field label { font-weight: 600; } - // use workflow from 描述 + /* use workflow from 描述 */ .ui.inline.field { > :first-child { margin-right: 8px; @@ -145,7 +146,7 @@ export const runWorkflow = css` margin-right: 0; } } - // 分支选择按钮 + /* 分支选择按钮 */ .ui.dropdown.button.branch-selector-dropdown { padding: 3px 21px 3px 12px; min-height: 27px; @@ -159,7 +160,7 @@ export const runWorkflow = css` .ui.field > label { margin-bottom: 6px; } - // 运行工作流按钮 + /* 运行工作流按钮 */ .ui.tiny.button { padding: 0px 8px; min-height: 27px; diff --git a/styles/components/actions/workflow_runs.ts b/styles/components/actions/workflow_runs.ts index 2078732..8279487 100644 --- a/styles/components/actions/workflow_runs.ts +++ b/styles/components/actions/workflow_runs.ts @@ -17,13 +17,14 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; // 工作流详情页标题 export const actionViewHeader = css` .action-view-header { .action-commit-summary { - // yml 文件名 + /* yml 文件名 */ > span:first-child { color: ${themeVars.github.fgColor.accent}; b { @@ -33,15 +34,15 @@ export const actionViewHeader = css` a:hover { text-decoration: inherit; } - // 提交哈希 + /* 提交哈希 */ > a.muted:first-of-type { text-decoration: underline; } - // 提交作者 + /* 提交作者 */ > a.muted:last-of-type { font-weight: 600; } - // 分支标签按钮 + /* 分支标签按钮 */ .ui.ui.ui.label { background-color: ${themeVars.github.bgColor.accent.muted}; border-radius: ${otherThemeVars.border.radius}; @@ -66,7 +67,7 @@ export const actionViewLeft = css` font-weight: 600; margin-left: 0.5rem; } - // 双重确保覆盖原始样式 + /* 双重确保覆盖原始样式 */ .job-brief-item.job-brief-item { border-radius: ${otherThemeVars.border.radius} !important; padding: 8px; @@ -88,12 +89,12 @@ export const actionViewLeft = css` width: 4px; } } - // 状态图标 + /* 状态图标 */ a > span:first-child { display: flex; align-items: center; } - // 默认隐藏重新运行按钮 + /* 默认隐藏重新运行按钮 */ a > svg.link-action { display: none; color: ${themeVars.color.console.fg.subtle} !important; @@ -101,17 +102,17 @@ export const actionViewLeft = css` color: ${themeVars.color.text.self} !important; } } - // 运行时长 + /* 运行时长 */ a > span:last-child { color: ${themeVars.color.console.fg.subtle}; font-size: 12px; } - // 鼠标移入时显示重新运行按钮 + /* 鼠标移入时显示重新运行按钮 */ &:hover a > svg.link-action { display: inline-block; } } - // Run Details 列表 + /* Run Details 列表 */ .ui.relaxed.list:last-of-type { padding: 0; .item { diff --git a/styles/components/actions/workflow_steps.ts b/styles/components/actions/workflow_steps.ts index 4a9b884..f7bff27 100644 --- a/styles/components/actions/workflow_steps.ts +++ b/styles/components/actions/workflow_steps.ts @@ -17,8 +17,9 @@ * limitations under the License. */ -import { animationDown } from "src/core/styles"; -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; +import { animationDown } from "styles/common"; // 工作流右侧作业步骤日志详情 export const actionViewRight = css` @@ -26,7 +27,7 @@ export const actionViewRight = css` box-shadow: ${themeVars.github.shadow.resting.small}; /* 提前加载高度和滚动条 */ min-height: calc(100vh - 245px); - // 作业详情页标题 + /* 作业详情页标题 */ .job-info-header { padding: 16px 12px 16px 24px !important; height: 80px !important; @@ -59,14 +60,14 @@ export const actionViewRight = css` padding: 8px; .job-step-section { margin: 0 4px 4px; - // 步骤标题, 双重确保覆盖原始样式 + /* 步骤标题, 双重确保覆盖原始样式 */ .job-step-summary.job-step-summary { color: ${themeVars.color.console.fg.subtle}; padding: 8px !important; height: 36px; &.selected { - // 滚动时固定在顶部的高度与 job-info-header 高度相同 + /* 滚动时固定在顶部的高度与 job-info-header 高度相同 */ top: 80px; } @@ -91,25 +92,25 @@ export const actionViewRight = css` color: ${themeVars.color.console.fg.self} !important; } } - // 步骤耗时 + /* 步骤耗时 */ .step-summary-duration { font-size: 12px; font-family: var(--fonts-monospace); } } - // 步骤日志 + /* 步骤日志 */ .job-step-logs { ${animationDown}; /* 日志字体颜色白色 */ .job-log-line { color: ${themeVars.color.console.fg.self}; - // 日志 + /* 日志 */ .log-msg:hover { - //被 hover 时覆盖 ANSI 颜色 + /*被 hover 时覆盖 ANSI 颜色 */ * { color: ${themeVars.color.console.fg.self}; } - // 日志超链接 + /* 日志超链接 */ a:hover { color: ${themeVars.color.primary.self} !important; } diff --git a/styles/components/actions/workflow_summary.ts b/styles/components/actions/workflow_summary.ts index 37623f3..445684a 100644 --- a/styles/components/actions/workflow_summary.ts +++ b/styles/components/actions/workflow_summary.ts @@ -17,23 +17,24 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; export const summaryView = css` .action-view-right:has(.action-run-summary-view) { min-height: auto; } .action-view-right .action-run-summary-view { - // 工作流运行信息 + /* 工作流运行信息 */ .action-run-summary-block { background: ${themeVars.color.body}; > .flex-text-block { - // 工作流触发方式和触发时间 + /* 工作流触发方式和触发时间 */ &:first-child { font-size: 12px; gap: 4px; } - // 工作流运行状态和运行时间 + /* 工作流运行状态和运行时间 */ &:last-child { color: ${themeVars.color.console.fg.self}; gap: 8px; @@ -44,25 +45,25 @@ export const summaryView = css` } } } - // 流程图 + /* 流程图 */ .workflow-graph { - // 流程图工作流信息标题 + /* 流程图工作流信息标题 */ .graph-header { background: ${themeVars.color.console.bg}; border-bottom: 0; padding: 16px; gap: 16px; - // 流程图标题(目前仅为解释, 内容为 Workflow Dependencies), 无需显示 + /* 流程图标题(目前仅为解释, 内容为 Workflow Dependencies), 无需显示 */ .graph-title { display: none; } - // 流程图信息 + /* 流程图信息 */ .graph-stats { align-self: flex-start; font-size: 12px; column-gap: 4px; } - // 流程图操作按钮组 + /* 流程图操作按钮组 */ > .flex-text-block { gap: 8px; .ui.compact.tiny.button { @@ -73,21 +74,21 @@ export const summaryView = css` } } } - // 流程图 + /* 流程图 */ .graph-container { background: ${themeVars.color.console.bg}; .graph-svg { - // 节点之间的连线 + /* 节点之间的连线 */ .node-edge { stroke: ${themeVars.color.light.border}; stroke-width: 2px; } - // 高亮连线 + /* 高亮连线 */ .highlighted-edge { stroke-width: 3px !important; } &:has(.highlighted-edge) { - // 有高亮线时, 降低其他线的颜色, 避免后面 path 未高亮元素遮挡高亮线 + /* 有高亮线时, 降低其他线的颜色, 避免后面 path 未高亮元素遮挡高亮线 */ .node-edge { opacity: 0.3; &.highlighted-edge { @@ -96,12 +97,12 @@ export const summaryView = css` } } .job-node-group { - // 节点 + /* 节点 */ .job-rect { fill: ${themeVars.github.workflowCardBg}; stroke-width: 1px; } - // 节点上的端口 + /* 节点上的端口 */ .node-port { r: 5.5; fill: ${themeVars.github.bgColor.neutral.emphasis}; @@ -110,19 +111,19 @@ export const summaryView = css` } &:hover { filter: ${themeVars.github.shadow.resting.medium}; - // 保留 Gitea 节点悬浮色, 因为无法实现 GitHub 悬浮时降低其他节点颜色 + /* 保留 Gitea 节点悬浮色, 因为无法实现 GitHub 悬浮时降低其他节点颜色 */ .job-rect { fill: ${themeVars.color.hover.self}; } - // 节点上的端口 + /* 节点上的端口 */ .node-port { fill: ${themeVars.color.workflowEdgeHover}; } } - // 节点上的步骤状态图标 + /* 节点上的步骤状态图标 */ .job-status-icon-wrap { span { - line-height: 1; // 使图标垂直居中 + line-height: 1; /* 使图标垂直居中 */ } } } diff --git a/styles/components/chroma.ts b/styles/components/chroma.ts deleted file mode 100644 index db89838..0000000 --- a/styles/components/chroma.ts +++ /dev/null @@ -1,305 +0,0 @@ -/*! - * Copyright (c) https://github.com/lutinglt - * - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { css, themeVars } from "src/types/vars"; - -// https://github.com/go-gitea/gitea/blob/main/web_src/css/chroma/base.css -export const chromaBase = css` - .chroma { - // LineTableTD - .lntd { - vertical-align: top; - padding: 0; - margin: 0; - border: 0; - } - // LineTable - .lntable { - border-spacing: 0; - padding: 0; - margin: 0; - border: 0; - width: auto; - overflow: auto; - display: block; - } - // LineHighlight - .hl { - display: block; - width: 100%; - } - // LineNumbersTable - .lnt, - // LineNumbers - .ln { - margin-right: 0.4em; - padding: 0 0.4em; - } - // GenericStrong - .gs { - font-weight: var(--font-weight-semibold); - } - // GenericUnderline - .gl { - text-decoration: underline; - } - } -`; - -// https://github.com/alecthomas/chroma/blob/6428fb4e65f3c1493491571c8a6a8f1add1da822/types.go#L208 -export const chromaCode = css` - .chroma { - // TextWhiteSpace - .w { - color: ${themeVars.chroma.textWhiteSpace}; - } - // Error - .err { - color: ${themeVars.chroma.err}; - } - // Keyword - .k { - color: ${themeVars.chroma.keyword.self}; - } - .kc { - color: ${themeVars.chroma.keyword.constant}; - } - .kd { - color: ${themeVars.chroma.keyword.declaration}; - } - .kn { - color: ${themeVars.chroma.keyword.namespace}; - } - .kp { - color: ${themeVars.chroma.keyword.pseudo}; - } - .kr { - color: ${themeVars.chroma.keyword.reserved}; - } - .kt { - color: ${themeVars.chroma.keyword.type}; - } - // Name - .n { - color: ${themeVars.chroma.name.self}; - } - .na { - color: ${themeVars.chroma.name.attribute}; - } - .nb { - color: ${themeVars.chroma.name.builtin}; - } - .bp { - color: ${themeVars.chroma.name.builtinPseudo}; - } - .nc { - color: ${themeVars.chroma.name.class}; - } - .no { - color: ${themeVars.chroma.name.constant}; - } - .nd { - color: ${themeVars.chroma.name.decorator}; - } - .ni { - color: ${themeVars.chroma.name.entity}; - } - .ne { - color: ${themeVars.chroma.name.exception}; - } - .nf { - color: ${themeVars.chroma.name.function}; - } - .fm { - color: ${themeVars.chroma.name.functionMagic}; - } - .py { - color: ${themeVars.chroma.name.property}; - } - .nl { - color: ${themeVars.chroma.name.label}; - } - .nn { - color: ${themeVars.chroma.name.namespace}; - } - .nx { - color: ${themeVars.chroma.name.other}; - } - .nt { - color: ${themeVars.chroma.name.tag}; - } - .nv { - color: ${themeVars.chroma.name.variable}; - } - .vc { - color: ${themeVars.chroma.name.variableClass}; - } - .vg { - color: ${themeVars.chroma.name.variableGlobal}; - } - .vi { - color: ${themeVars.chroma.name.variableInstance}; - } - .vm { - color: ${themeVars.chroma.name.variableMagic}; - } - // Literal - .l { - color: ${themeVars.chroma.literal.self}; - } - .ld { - color: ${themeVars.chroma.literal.date}; - } - // String - .s { - color: ${themeVars.chroma.string.self}; - } - .sa { - color: ${themeVars.chroma.string.affix}; - } - .sb { - color: ${themeVars.chroma.string.backtick}; - } - .sc { - color: ${themeVars.chroma.string.char}; - } - .dl { - color: ${themeVars.chroma.string.delimiter}; - } - .sd { - color: ${themeVars.chroma.string.doc}; - } - .s2 { - color: ${themeVars.chroma.string.double}; - } - .se { - color: ${themeVars.chroma.string.escape}; - } - .sh { - color: ${themeVars.chroma.string.heredoc}; - } - .si { - color: ${themeVars.chroma.string.interpol}; - } - .sx { - color: ${themeVars.chroma.string.other}; - } - .sr { - color: ${themeVars.chroma.string.regex}; - } - .s1 { - color: ${themeVars.chroma.string.single}; - } - .ss { - color: ${themeVars.chroma.string.symbol}; - } - // Number - .m { - color: ${themeVars.chroma.number.self}; - } - .mb { - color: ${themeVars.chroma.number.bin}; - } - .mf { - color: ${themeVars.chroma.number.float}; - } - .mh { - color: ${themeVars.chroma.number.hex}; - } - .mi { - color: ${themeVars.chroma.number.integer}; - } - .il { - color: ${themeVars.chroma.number.integerLong}; - } - .mo { - color: ${themeVars.chroma.number.oct}; - } - // Operator - .o { - color: ${themeVars.chroma.operator.self}; - } - .ow { - color: ${themeVars.chroma.operator.word}; - } - // Punctuation - .p { - color: ${themeVars.chroma.punctuation}; - } - // Comment - .c { - color: ${themeVars.chroma.comment.self}; - } - .ch { - color: ${themeVars.chroma.comment.hashbang}; - } - .cm { - color: ${themeVars.chroma.comment.multiline}; - } - .cp { - color: ${themeVars.chroma.comment.preproc}; - } - .cpf { - color: ${themeVars.chroma.comment.preprocFile}; - } - .c1 { - color: ${themeVars.chroma.comment.single}; - } - .cs { - color: ${themeVars.chroma.comment.special}; - } - // Generic - .g { - color: ${themeVars.chroma.generic.self}; - } - .gd { - color: ${themeVars.chroma.generic.deleted}; - } - .ge { - color: ${themeVars.chroma.generic.emph}; - } - .gr { - color: ${themeVars.chroma.generic.error}; - } - .gh { - color: ${themeVars.chroma.generic.heading}; - } - .gi { - color: ${themeVars.chroma.generic.inserted}; - } - .go { - color: ${themeVars.chroma.generic.output}; - } - .gp { - color: ${themeVars.chroma.generic.prompt}; - } - .gs { - color: ${themeVars.chroma.generic.strong}; - } - .gu { - color: ${themeVars.chroma.generic.subheading}; - } - .gt { - color: ${themeVars.chroma.generic.traceback}; - } - .gu { - color: ${themeVars.chroma.generic.underline}; - } - } -`; diff --git a/styles/components/dashboard.ts b/styles/components/dashboard.ts index 81bb65a..033fc2c 100644 --- a/styles/components/dashboard.ts +++ b/styles/components/dashboard.ts @@ -17,34 +17,40 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; -import { labelStyle } from "styles/public/label/label"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; +import { labelStyle } from "styles/common"; export const dashboard = css` .page-content.dashboard { - // 仪表板切换控制用户按钮 + /* 仪表板切换控制用户按钮 */ .ui.dropdown .menu.context-user-switch .scrolling.menu { - animation: none; // 去掉嵌套菜单导致的多余动画 + animation: none; /* 去掉嵌套菜单导致的多余动画 */ box-shadow: 0px 0px 0px 1px ${themeVars.color.light.border} !important; } } - // 首页仪表板, 避免选中管理员后台的维护管理面板 + /* 首页仪表板, 避免选中管理员后台的维护管理面板 */ .page-content.dashboard.feeds { - // 仓库列表的仓库/组织切换按钮 + /* 仓库列表的仓库/组织切换按钮 */ .ui.two.item.menu { - background: ${themeVars.color.hover.self}; + background: ${themeVars.github.controlTrack.bgColor.rest}; border: 0; + box-shadow: + 0px 0px 0px 1px ${themeVars.color.light.border}, + ${themeVars.github.shadow.resting.small}; border-radius: 12px; margin-bottom: 8px; + position: relative; + overflow: hidden; > .item { background: unset; border-radius: 12px; padding: 6px 12px !important; + position: relative; + z-index: 2; &.active { - background: ${themeVars.color.menu}; - box-shadow: - 0px 0px 0px 1px ${themeVars.color.light.border}, - ${themeVars.github.shadow.resting.small}; + background: unset !important; + box-shadow: none !important; font-weight: 600; } &::before { @@ -59,8 +65,29 @@ export const dashboard = css` } } } + /* 滑块指示器 */ + &::after { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 50%; + height: 100%; + background: ${themeVars.github.controlKnob.bgColor.rest}; + border-radius: 12px; + box-shadow: + 0px 0px 0px 1px ${themeVars.color.light.border}, + ${themeVars.github.shadow.resting.small}; + transition: transform 200ms cubic-bezier(0.33, 1, 0.68, 1); + z-index: 1; + pointer-events: none; + } + /* 右侧激活 → 滑块向右滑 */ + &:has(> .item:last-child.active)::after { + transform: translateX(100%); + } } - // 仓库/组织列表标题 + /* 仓库/组织列表标题 */ .ui.top.attached.header { border: 0; font-size: 20px; @@ -71,7 +98,7 @@ export const dashboard = css` border-color: #00000000; } } - // 仓库/组织列表 + /* 仓库/组织列表 */ .ui.attached.segment { background-color: ${themeVars.color.menu}; border: unset !important; @@ -114,7 +141,7 @@ export const dashboard = css` } } } - // 组织列表 + /* 组织列表 */ .ui.tab.dashboard-orgs .ui.attached.segment.table { border-top-left-radius: 12px; border-top-right-radius: 12px; diff --git a/styles/components/explore.ts b/styles/components/explore.ts index 037ef99..af933d7 100644 --- a/styles/components/explore.ts +++ b/styles/components/explore.ts @@ -17,8 +17,9 @@ * limitations under the License. */ -import { fallbackVar } from "src/functions"; -import { css, customThemeVars, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { fallbackVar } from "@vanilla-extract/css"; +import { customThemeVars, otherThemeVars, themeVars } from "src"; const userRepoVar = fallbackVar(customThemeVars.userRepolistColumns, "2"); const exploreRepoVar = fallbackVar(customThemeVars.explore.repolistColumns, "2"); @@ -26,39 +27,39 @@ const orgRepoVar = fallbackVar(customThemeVars.org.repolistColumns, "1"); // 仓库列表 export const repoList = css` - // 组织 + /* 组织 */ .page-content.organization.profile > .ui.container > .ui.stackable > .ui.eleven, - // 用户 + /* 用户 */ .page-content.user.profile > .ui.container > .ui.stackable > .ui.twelve, - // 探索 + /* 探索 */ .page-content.explore.repositories > .ui.container { - // 排除用户的公开活动页 + /* 排除用户的公开活动页 */ > .flex-list:not(#activity-feed) { display: grid; > .flex-item { border: 1px solid ${themeVars.color.light.border}; border-radius: ${otherThemeVars.border.radius}; padding: 16px; - // 仓库头像 + /* 仓库头像 */ > .flex-item-leading { img, svg { color: ${themeVars.color.text.light.num1}; } } - // 仓库信息 + /* 仓库信息 */ > .flex-item-main { - // 仓库标题 + /* 仓库标题 */ > .flex-item-header { - // 仓库名称 + /* 仓库名称 */ > .flex-item-title { gap: 8px; - // 仓库中间的间隔线 + /* 仓库中间的间隔线 */ &:not(a) { color: ${themeVars.color.text.light.num1}; } } - // 仓库语言, 星标 + /* 仓库语言, 星标 */ > .flex-item-trailing { color: ${themeVars.color.text.light.num1}; gap: 16px; @@ -70,15 +71,15 @@ export const repoList = css` } } } - // 描述和更新时间 + /* 描述和更新时间 */ > .flex-item-body { margin-top: 8px; - // 更新时间 + /* 更新时间 */ &:last-child { font-size: 12px; } } - // 主题标签 + /* 主题标签 */ > .label-list { margin-top: 8px; } @@ -86,19 +87,19 @@ export const repoList = css` } } } - // 仓库列表列数 - // 组织 + /* 仓库列表列数 */ + /* 组织 */ .page-content.organization.profile > .ui.container > .ui.stackable > .ui.eleven > .flex-list { grid-template-columns: repeat(${orgRepoVar}, 1fr); gap: min(${orgRepoVar} * 8px, 16px); } - // 用户 - // 排除用户的公开活动页 + /* 用户 */ + /* 排除用户的公开活动页 */ .page-content.user.profile > .ui.container > .ui.stackable > .ui.twelve > .flex-list:not(#activity-feed) { grid-template-columns: repeat(${userRepoVar}, 1fr); gap: min(${userRepoVar} * 8px, 16px); } - // 探索 + /* 探索 */ .page-content.explore.repositories > .ui.container > .flex-list { grid-template-columns: repeat(${exploreRepoVar}, 1fr); gap: min(${exploreRepoVar} * 8px, 16px); @@ -110,9 +111,9 @@ const orgUserVar = fallbackVar(customThemeVars.org.userlistColumns, "2"); // 用户列表 export const userList = css` - // 组织 + /* 组织 */ .page-content.organization.members > .ui.container, - // 探索的用户和组织 + /* 探索的用户和组织 */ .page-content.explore.users > .ui.container { > .flex-list { display: grid; @@ -121,16 +122,16 @@ export const userList = css` border-radius: ${otherThemeVars.border.radius}; padding: 16px; > .flex-item-main { - // 用户名称 + /* 用户名称 */ > .flex-item-title { gap: 8px; margin-bottom: 8px; - // 用户标签 + /* 用户标签 */ > .label { font-size: 12px; } } - // 用户描述 + /* 用户描述 */ > .flex-item-body { font-size: 12px; svg { @@ -142,13 +143,13 @@ export const userList = css` } } } - // 用户列表列数 - // 组织 + /* 用户列表列数 */ + /* 组织 */ .page-content.organization.members > .ui.container > .flex-list { grid-template-columns: repeat(${orgUserVar}, 1fr); gap: min(${orgUserVar} * 8px, 16px); } - // 探索的用户和组织 + /* 探索的用户和组织 */ .page-content.explore.users > .ui.container > .flex-list { grid-template-columns: repeat(${exploreUserVar}, 1fr); gap: min(${exploreUserVar} * 8px, 16px); @@ -158,17 +159,17 @@ export const userList = css` // 手机下的仓库和用户列表 export const mobileList = css` @media (max-width: 767.98px) { - // 组织的仓库列表 + /* 组织的仓库列表 */ .page-content.organization.profile > .ui.container > .ui.stackable > .ui.eleven, - // 用户的仓库列表 + /* 用户的仓库列表 */ .page-content.user.profile > .ui.container > .ui.stackable > .ui.twelve, - // 探索的仓库列表 + /* 探索的仓库列表 */ .page-content.explore.repositories > .ui.container, - // 组织的成员列表 + /* 组织的成员列表 */ .page-content.organization.members >.ui.container, - // 探索的用户和组织列表 + /* 探索的用户和组织列表 */ .page-content.explore.users >.ui.container { - // 排除用户的公开活动页 + /* 排除用户的公开活动页 */ > .flex-list:not(#activity-feed) { grid-template-columns: 1fr; gap: 8px; @@ -179,17 +180,17 @@ export const mobileList = css` // 统一无搜索结果时的样式 export const notMatch = css` - // 组织的仓库列表 + /* 组织的仓库列表 */ .page-content.organization.profile > .ui.container > .ui.stackable > .ui.eleven, - // 用户的仓库列表 + /* 用户的仓库列表 */ .page-content.user.profile > .ui.container > .ui.stackable > .ui.twelve, - // 探索的仓库列表 + /* 探索的仓库列表 */ .page-content.explore.repositories > .ui.container, - // 组织的成员列表 + /* 组织的成员列表 */ .page-content.organization.members >.ui.container, - // 探索的用户和组织列表 + /* 探索的用户和组织列表 */ .page-content.explore.users >.ui.container { - // 排除用户的公开活动页 + /* 排除用户的公开活动页 */ > .flex-list:not(#activity-feed) { &:has(> div:only-child):not(:has(.flex-item-main)) { grid-template-columns: 1fr; diff --git a/styles/components/footer.ts b/styles/components/footer.ts index 33fd1f0..35e9240 100644 --- a/styles/components/footer.ts +++ b/styles/components/footer.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; export const footer = css` .page-footer { @@ -60,11 +61,11 @@ export const footer = css` color: ${themeVars.color.primary.self}; } } - // 主题按钮&菜单项 + /* 主题按钮&菜单项 */ .ui.dropdown .theme-menu-item { gap: 4px; } - // 主题菜单 + /* 主题菜单 */ .menu.theme-menu > .item > .theme-menu-item { padding: 0; } diff --git a/styles/components/heatmap.ts b/styles/components/heatmap.ts index 8c5caaf..fb30a2d 100644 --- a/styles/components/heatmap.ts +++ b/styles/components/heatmap.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; export const heatmap = css` #user-heatmap { @@ -39,20 +40,20 @@ export const heatmap = css` 0px 0px 0px 1px ${themeVars.color.light.border}, ${themeVars.github.shadow.resting.small}; border-radius: 12px; - // 覆盖热力图和图例的背景色 + /* 覆盖热力图和图例的背景色 */ .vch__day__square, .vch__legend__wrapper rect { - // 圆角 + /* 圆角 */ rx: 2.5px; ry: 2.5px; - // hover 时的圆角 + /* hover 时的圆角 */ border-radius: 0.75px; - // 宽度和高度可以用来控制间隔 + /* 宽度和高度可以用来控制间隔 */ width: 9px; height: 9px; - // 边框 + /* 边框 */ outline: 0.5px solid ${themeVars.github.contribution.default.borderColor.num0}; - // 边框向内偏移 + /* 边框向内偏移 */ outline-offset: -0.5px; &[style="fill: var(--color-secondary-alpha-60);"] { @@ -108,10 +109,10 @@ export const activity = css` border-radius: 9999px; } } - // 动态的主要内容 + /* 动态的主要内容 */ > .flex-item-main { gap: 8px !important; - // 动态的标题 + /* 动态的标题 */ > div:not([class]) { display: flex; align-items: baseline; @@ -119,9 +120,9 @@ export const activity = css` flex-wrap: wrap; > a { color: ${themeVars.color.text.self}; - // 不匹配作者 + /* 不匹配作者 */ &:not([title]) { - // 尽量只选中仓库名, 不匹配标签和分支 + /* 尽量只选中仓库名, 不匹配标签和分支 */ &:not([href*="tag"]):not([href*="branch"]) { color: ${themeVars.color.primary.self}; text-decoration: underline; @@ -133,7 +134,7 @@ export const activity = css` font-size: 12px; } } - // 动态的描述 + /* 动态的描述 */ > .tw-flex-col { gap: 0px !important; > .flex-text-block { @@ -159,7 +160,7 @@ export const activity = css` font-size: 12px; } } - // 动态的右侧 svg 图标 + /* 动态的右侧 svg 图标 */ .flex-item-trailing { align-self: center; svg { diff --git a/styles/components/index.ts b/styles/components/index.ts index 21074f4..7422db2 100644 --- a/styles/components/index.ts +++ b/styles/components/index.ts @@ -18,9 +18,7 @@ */ import "./actions"; -import "./chroma"; import "./dashboard"; -import "./editor"; import "./explore"; import "./footer"; import "./heatmap"; diff --git a/styles/components/issues/issue.ts b/styles/components/issues/issue.ts index ac87751..2c4b3e9 100644 --- a/styles/components/issues/issue.ts +++ b/styles/components/issues/issue.ts @@ -17,11 +17,12 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; -import { activeItemAfterStyle } from "styles/public/menu"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; +import { activeItemAfterStyle } from "styles/common"; export const button = css` - // 工单&PR标题右侧按钮 + /* 工单&PR标题右侧按钮 */ .repository.view.issue .issue-title-buttons > .ui.button { padding: 0 12px; height: 32px; @@ -31,21 +32,21 @@ export const button = css` export const babel = css` .issue-content-left { .badge { - // 时间线打开状态标签 + /* 时间线打开状态标签 */ &.tw-bg-green { background-color: ${themeVars.github.bgColor.success.emphasis} !important; } - // 时间线关闭状态标签 + /* 时间线关闭状态标签 */ &.tw-bg-red { background-color: ${themeVars.github.bgColor.done.emphasis} !important; } - // 时间线合并状态标签 + /* 时间线合并状态标签 */ &.tw-bg-purple { background-color: ${themeVars.github.bgColor.done.emphasis} !important; } } } - // 工单&PR状态标签 + /* 工单&PR状态标签 */ .ui.label.issue-state-label { border-radius: 25px !important; &.green { @@ -90,9 +91,9 @@ export const prBranch = css` export const dropdown = css` .repository { - // Issue/PR 列表下的所有筛选菜单 + /* Issue/PR 列表下的所有筛选菜单 */ &.issue-list .ui.dropdown .menu, .ui.menu .ui.dropdown .menu, - // Issue/PR 详情下的右侧的上半部分选项菜单 + /* Issue/PR 详情下的右侧的上半部分选项菜单 */ &.issue.view .issue-content-right .ui.dropdown .scrolling.menu { .item:hover:after { content: ""; @@ -105,7 +106,7 @@ export const dropdown = css` // PR 界面的 PR 操作评论 export const prMerge = css` .repository.view.issue .comment-list .timeline-item.pull-merge-box { - // 头像 + /* 头像 */ .timeline-avatar { border-radius: 9999px; width: 40px; @@ -117,11 +118,11 @@ export const prMerge = css` width: 24px; height: 24px; } - // PR 界面的 PR 操作评论 + /* PR 界面的 PR 操作评论 */ &.text { color: ${themeVars.color.white} !important; border-radius: ${otherThemeVars.border.radius}; - // 操作评论边框 + /* 操作评论边框 */ + .content > .ui.attached.segment { border-width: 1.5px; } @@ -182,7 +183,7 @@ export const prMerge = css` } } } - // 检查状态 + /* 检查状态 */ .commit-status-panel { .commit-status-header { background: ${themeVars.color.body}; @@ -195,7 +196,7 @@ export const prMerge = css` font-weight: 400; } } - // 检查状态列表 + /* 检查状态列表 */ .commit-status-list { background: ${themeVars.color.menu}; .commit-status-item { @@ -215,7 +216,7 @@ export const prMerge = css` } } } - // 合并信息和操作 + /* 合并信息和操作 */ .merge-section { color: ${themeVars.color.text.light.num1}; padding: 16px; diff --git a/styles/components/issues/issue_comment.ts b/styles/components/issues/issue_comment.ts index f780670..8e6de3c 100644 --- a/styles/components/issues/issue_comment.ts +++ b/styles/components/issues/issue_comment.ts @@ -17,20 +17,17 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; +import { botLabelStyle } from "styles/common"; -export const botLabelStyle = { - height: "20px", - padding: "0 6px!important", - marginLeft: "4px", -}; // 评论 export const comment = css` .comment .comment-container { img.ui.avatar { border-radius: 9999px; } - // 去除评论标题左侧指向头像的小箭头 + /* 去除评论标题左侧指向头像的小箭头 */ .comment-header, &:target .comment-header { &:before, @@ -38,7 +35,7 @@ export const comment = css` display: none; } } - // 评论焦点样式 + /* 评论焦点样式 */ &:target { .comment-container { border-color: ${themeVars.github.borderColor.accent.emphasis} !important; @@ -49,14 +46,14 @@ export const comment = css` padding: 4px 4px 4px 16px; min-height: 38px; .comment-header-left { - // bot 标签 + /* bot 标签 */ .ui.basic.label { ${botLabelStyle} } a:has(relative-time) { text-decoration: underline; } - // 已编辑按钮 + /* 已编辑按钮 */ .content-history-menu { color: ${themeVars.color.text.light.num1} !important; .menu .item { @@ -94,7 +91,7 @@ export const comment = css` color: inherit; } } - // 评论菜单的删除按钮 + /* 评论菜单的删除按钮 */ .menu .item.delete-comment { color: ${themeVars.color.red.self}; &:hover { @@ -104,7 +101,7 @@ export const comment = css` } } } - // 表情菜单按钮头部+底部 + /* 表情菜单按钮头部+底部 */ .ui.dropdown.action.select-reaction > a { display: flex; align-items: center; @@ -117,7 +114,7 @@ export const comment = css` height: 28px; width: 28px; } - // 底部表情栏 + /* 底部表情栏 */ .bottom-reactions { .ui.ui.ui.label { background-color: unset !important; @@ -136,11 +133,11 @@ export const comment = css` margin-left: 0; } } - // 显示表情菜单按钮 + /* 显示表情菜单按钮 */ .select-reaction { padding: 0; - // 两个表情按钮看着怪怪的, 很难受 - // visibility: visible; + /* 两个表情按钮看着怪怪的, 很难受 */ + /* visibility: visible; */ } } } diff --git a/styles/components/issues/issue_list.ts b/styles/components/issues/issue_list.ts index 90ec568..5393d0d 100644 --- a/styles/components/issues/issue_list.ts +++ b/styles/components/issues/issue_list.ts @@ -17,17 +17,17 @@ * limitations under the License. */ -import { extractVarName } from "src/functions"; -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { extractVarName, otherThemeVars, themeVars } from "src"; // 工单&PR 列表 export const issueList = css` - // 仓库页面的里程碑列表菜单栏 + /* 仓库页面的里程碑列表菜单栏 */ .page-content.repository.milestones, .page-content.repository.milestone-issue-list, .page-content.repository.issue-list { ${extractVarName(otherThemeVars.checkbox.size)}: 16px; - // 头部筛选菜单栏 + /* 头部筛选菜单栏 */ .issue-list-toolbar { align-items: center; align-content: center; @@ -40,7 +40,7 @@ export const issueList = css` padding: 8px; margin-top: 16px; .issue-list-toolbar-left { - // 复选框 + /* 复选框 */ input { margin: 0 8px !important; } @@ -93,13 +93,13 @@ export const issueList = css` } } } - // 里程碑详细页面的 Issue 列表 + /* 里程碑详细页面的 Issue 列表 */ .page-content.repository.milestone-issue-list, - // 顶部仪表板的 Issue 列表 + /* 顶部仪表板的 Issue 列表 */ .page-content.dashboard.issues, - // 用户订阅的 Issue 列表 + /* 用户订阅的 Issue 列表 */ .page-content.user.notification, - // 仓库 Issue 列表 + /* 仓库 Issue 列表 */ .page-content.repository.issue-list { .flex-list#issue-list { border: 1px solid ${themeVars.color.light.border}; @@ -128,7 +128,7 @@ export const issueList = css` margin-left: 16px; > .flex-text-inline { margin-top: 0px !important; - // 复选框 + /* 复选框 */ input { margin-right: 8px !important; } @@ -150,8 +150,8 @@ export const issueList = css` } } } - // 里程碑列表 - // [TODO] 暂时排除项目的列表 + /* 里程碑列表 */ + /* [TODO] 暂时排除项目的列表 */ .page-content.repository.milestones:not(.projects) .milestone-list { border: 1px solid ${themeVars.color.light.border}; border-bottom-left-radius: ${otherThemeVars.border.radius}; diff --git a/styles/components/issues/issue_sidebar.ts b/styles/components/issues/issue_sidebar.ts index 1f23786..3efd973 100644 --- a/styles/components/issues/issue_sidebar.ts +++ b/styles/components/issues/issue_sidebar.ts @@ -17,24 +17,26 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import type { StyleRule } from "@vanilla-extract/css"; +import { otherThemeVars, themeVars } from "src"; const sidebarPadding = { padding: "4px 8px", -}; +} satisfies StyleRule; // 侧边栏 export const issueSidebar = css` - // 创建PR页面 + /* 创建PR页面 */ .page-content.repository.diff.compare.pull, - // 工单&创建工单&PR页面侧边栏 + /* 工单&创建工单&PR页面侧边栏 */ .page-content.repository.issue { .issue-content { img.ui.avatar { border-radius: 9999px; } gap: 24px; - // 侧边栏 + /* 侧边栏 */ .issue-content-right { border: 0; font-size: 12px; @@ -45,13 +47,13 @@ export const issueSidebar = css` .ui.form, a.fixed-text.muted, span.text, - // 列表项为空时的文字 + /* 列表项为空时的文字 */ span.item.empty-list, p { color: ${themeVars.color.text.light.num1}; font-size: 12px; } - // WIP 前缀提示 + /* WIP 前缀提示 */ > a, .ui.dropdown.select-branch, .ui.form, @@ -65,7 +67,7 @@ export const issueSidebar = css` p { ${sidebarPadding}; } - // 允许维护者编辑 + /* 允许维护者编辑 */ > .ui.checkbox { margin: 4px 8px; strong { @@ -86,10 +88,10 @@ export const issueSidebar = css` margin-top: 0 !important; margin-bottom: 0 !important; } - // 评审人 + /* 评审人 */ .ui.relaxed.list { .item { - // 操作图标按钮 + /* 操作图标按钮 */ a.muted.icon { color: ${themeVars.color.text.light.num1}; &:hover { @@ -98,55 +100,55 @@ export const issueSidebar = css` } } } - // 标签菜单项 + /* 标签菜单项 */ .ui.dropdown > .menu > .scrolling.menu > .item:has(.item-secondary-info) { - // 修复标签菜单中描述文本过长没有换行挤掉标签的问题 + /* 修复标签菜单中描述文本过长没有换行挤掉标签的问题 */ display: grid !important; grid-template-columns: auto auto 1fr; - row-gap: 0px; // 去除行间距, 仅当有描述信息时才有间距(.tw-pl-\\\[20px\\\]) - // 如果是归档标签则隐藏 + row-gap: 0px; /* 去除行间距, 仅当有描述信息时才有间距(.tw-pl-\\\[20px\\\]) */ + /* 如果是归档标签则隐藏 */ &.tw-hidden { display: none !important; } - // 默认隐藏多余信息避免标签对齐问题 + /* 默认隐藏多余信息避免标签对齐问题 */ .item-secondary-info { display: none; - grid-column: 2 / -1; // 从第2列对齐 + grid-column: 2 / -1; /* 从第2列对齐 */ color: ${themeVars.color.text.light.num1}; > .tw-pl-\\\[20px\\\] { - // 已经与第二列对齐, 不需要额外的 padding + /* 已经与第二列对齐, 不需要额外的 padding */ padding-left: 0px !important; padding-top: 4px; - // 显示全部描述信息与 Github 保持一致 + /* 显示全部描述信息与 Github 保持一致 */ white-space: normal; small { font-size: 12px; } } > .archived-label-hint { - // 与父元素 item 的 padding 对齐 (dropdown.ts .ui.dropdown .menu > .item) + /* 与父元素 item 的 padding 对齐 (dropdown.ts .ui.dropdown .menu > .item) */ top: 6px; right: 8px; } - // 如果有描述信息则显示 + /* 如果有描述信息则显示 */ &:has(.tw-pl-\\\[20px\\\]) { display: block; > .archived-label-hint { - top: 4px; // 有描述信息的归档标签与标签对齐需要更高点 + top: 4px; /* 有描述信息的归档标签与标签对齐需要更高点 */ } } - // 如果有归档标签则显示 + /* 如果有归档标签则显示 */ &:has(.archived-label-hint > .ui.label) { display: block; } } } - // 修复菜单下拉打开时, 无法聚焦输入框 + /* 修复菜单下拉打开时, 无法聚焦输入框 */ .menu input { transition: none; } } - // 时间追踪 + /* 时间追踪 */ > div:not([class]):not([id]) { > .flex-text-block { color: ${themeVars.color.text.light.num1}; @@ -165,16 +167,16 @@ export const issueSidebar = css` } } } - // 选中日期颜色 + /* 选中日期颜色 */ .ui.form .due-date { color: ${themeVars.color.text.self}; } - // 分割线 + /* 分割线 */ > .divider { margin: 12px 0 12px 8px; width: calc(100% - 16px); } - // 订阅按钮 + /* 订阅按钮 */ .ui.watching .ui.button { padding: 0px 8px; height: 30px; @@ -183,15 +185,15 @@ export const issueSidebar = css` margin: 0 !important; } } - // PIN 按钮 + /* PIN 按钮 */ .form-fetch-action.single-button-form .ui.button, - // 底部操作按钮 + /* 底部操作按钮 */ > .ui.show-modal.button { border: 0; background: unset; font-weight: 400; ${sidebarPadding}; - // 好像是浏览器 BUG, 最后不生效, 必须 !important + /* 好像是浏览器 BUG, 最后不生效, 必须 !important */ margin: 0 !important; justify-content: left; &:hover { diff --git a/styles/components/issues/issue_timeline.ts b/styles/components/issues/issue_timeline.ts index d314254..ab64898 100644 --- a/styles/components/issues/issue_timeline.ts +++ b/styles/components/issues/issue_timeline.ts @@ -17,16 +17,17 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; -import { botLabelStyle } from "./issue_comment"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; +import { botLabelStyle } from "styles/common"; // 时间线 export const timeline = css` .repository.view.issue { .comment-list { - // 时间线本线 + /* 时间线本线 */ .timeline::before { - // 不遮挡归档信息框, 归档信息框背景色有透明度时会漏出线 + /* 不遮挡归档信息框, 归档信息框背景色有透明度时会漏出线 */ height: calc(100% - 62px); } .timeline-item, @@ -35,28 +36,28 @@ export const timeline = css` .comment-text-line { color: ${themeVars.color.text.light.num1}; } - // 事件 + /* 事件 */ &.event { - // 修复覆盖后的位置问题 + /* 修复覆盖后的位置问题 */ padding-left: 15px; - // 避免锚中批准的头像 + /* 避免锚中批准的头像 */ .avatar-with-link .avatar { width: 20px; height: 20px; } - // 批准时间的头像 - // 头部居中偏移量(头像高度 - 标准行信息高度) / 2: (40px - 32px) / 2 = 4px + /* 批准时间的头像 */ + /* 头部居中偏移量(头像高度 - 标准行信息高度) / 2: (40px - 32px) / 2 = 4px */ .timeline-avatar { top: -4px; } - // bot 标签 + /* bot 标签 */ .comment-text-line .ui.basic.label { ${botLabelStyle} } .badge { border: 2px solid ${themeVars.color.body}; } - // 仅匹配只有 badge + /* 仅匹配只有 badge */ [class="badge"] { background-color: ${themeVars.github.control.bgColor.rest}; svg { @@ -64,16 +65,16 @@ export const timeline = css` } } } - // 提交 + /* 提交 */ &.commits-list { - // 每个提交之间的间隔 + /* 每个提交之间的间隔 */ .flex-text-block { padding-top: 4px; } .badge svg { color: ${themeVars.color.text.light.num1}; } - // 仅覆盖左侧 commit 不覆盖右侧 SHA + /* 仅覆盖左侧 commit 不覆盖右侧 SHA */ a.muted { font-size: 12px; color: ${themeVars.color.text.light.num1}; diff --git a/styles/components/navbar.ts b/styles/components/navbar.ts index a039fef..0173941 100644 --- a/styles/components/navbar.ts +++ b/styles/components/navbar.ts @@ -17,12 +17,13 @@ * limitations under the License. */ -import { fallbackVar } from "src/functions"; -import { css, customThemeVars, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { fallbackVar } from "@vanilla-extract/css"; +import { customThemeVars, otherThemeVars, themeVars } from "src"; export const navbarRight = css` #navbar { - padding: 8px 16px; // 上下内边距 + .navbar-left & .navbar-right 的 min-height = 64px + padding: 8px 16px; /* 上下内边距 + .navbar-left & .navbar-right 的 min-height = 64px */ min-height: 64px; .navbar-left, .navbar-right { @@ -37,7 +38,7 @@ export const navbarRight = css` font-weight: 600; } &#navbar-logo { - // 与下方的用户切换头像对齐 + /* 与下方的用户切换头像对齐 */ padding-left: 6px; &:hover { background: unset; @@ -49,10 +50,10 @@ export const navbarRight = css` } } } - // 进入用户页面后, 避免注册, 登录和首页等意外覆盖 + /* 进入用户页面后, 避免注册, 登录和首页等意外覆盖 */ .navbar-right:has(.user-menu) { gap: 8px; - // 右侧按钮, 但不包括头像 + /* 右侧按钮, 但不包括头像 */ > .item:not(:last-child) { align-items: center; justify-content: center; @@ -63,7 +64,7 @@ export const navbarRight = css` height: 32px; min-width: 32px; min-height: 32px; - // 纠正内容保证居中 + /* 纠正内容保证居中 */ .tw-relative { height: 16px; width: 16px; @@ -71,7 +72,7 @@ export const navbarRight = css` .svg { color: ${themeVars.color.text.light.num1}; } - // 带下拉菜单的按钮 + /* 带下拉菜单的按钮 */ &.ui.dropdown { padding: 0 8px; .text { @@ -81,7 +82,7 @@ export const navbarRight = css` > svg { margin-right: 4px; } - // 三角号纠正高度保持居中 + /* 三角号纠正高度保持居中 */ .not-mobile { height: 16px; } @@ -92,21 +93,21 @@ export const navbarRight = css` } } .item.ui.dropdown { - // 头像菜单 + /* 头像菜单 */ &:last-child { padding: 0; .text { - // 不显示头像右侧的小箭头下拉菜单标识 + /* 不显示头像右侧的小箭头下拉菜单标识 */ > .not-mobile { display: none; } - // 手机下的用户名 + /* 手机下的用户名 */ > .only-mobile { margin-left: 12px; font-weight: 600; } .navbar-avatar { - // 头像 + /* 头像 */ img { border-radius: 9999px; height: 32px; @@ -115,14 +116,14 @@ export const navbarRight = css` max-width: 32px; margin: 0 !important; } - // 管理员标识 + /* 管理员标识 */ .navbar-admin-badge { height: 18px; min-width: 18px; bottom: calc(100% - 32px); left: calc(100% - 11px); padding: 2px; - border-color: ${themeVars.color.nav.bg}; // 锁定边框色, 避免鼠标悬浮时改变颜色 + border-color: ${themeVars.color.nav.bg}; /* 锁定边框色, 避免鼠标悬浮时改变颜色 */ } } } @@ -131,12 +132,13 @@ export const navbarRight = css` } } } - // 通知和计时器的圆点 + /* 通知和计时器的圆点 */ a.item { .notification_count, .header-stopwatch-dot { background-color: ${themeVars.github.bgColor.accent.emphasis}; border-radius: 9999px; + border-color: ${themeVars.color.nav.bg}; color: ${themeVars.color.white}; font-size: 9px; font-weight: 600; @@ -145,7 +147,7 @@ export const navbarRight = css` } } } - // 用户菜单 + /* 用户菜单 */ .navbar-right .user-menu { width: ${fallbackVar(customThemeVars.userMenuWidth, "192px")}; max-width: 320px; @@ -164,7 +166,7 @@ export const navbarRight = css` } } } - // 手机下的导航栏 + /* 手机下的导航栏 */ @media (max-width: 767.98px) { #navbar { &.navbar-menu-open { @@ -181,7 +183,7 @@ export const navbarRight = css` height: 32px; min-width: 32px; min-height: 32px; - // 纠正内容保证居中 + /* 纠正内容保证居中 */ .tw-relative { height: 16px; width: 16px; @@ -199,12 +201,12 @@ export const navbarRight = css` export const secondaryNav = css` .page-content > :first-child.secondary-nav { margin-bottom: 16px; - // 仪表板界面的二级导航栏用户菜单 + /* 仪表板界面的二级导航栏用户菜单 */ > .ui.secondary.stackable.menu { gap: 0px; min-height: 48px; > .item { - // 修复手机下的菜单按钮没有居中的问题 + /* 修复手机下的菜单按钮没有居中的问题 */ margin-top: auto; margin-bottom: auto; > .ui.dropdown > .text { diff --git a/styles/components/newrepo.ts b/styles/components/newrepo.ts index 5acf4b9..c0fa8b2 100644 --- a/styles/components/newrepo.ts +++ b/styles/components/newrepo.ts @@ -17,8 +17,8 @@ * limitations under the License. */ -import { css } from "src/types/vars"; -import { activeItemAfterStyle } from "styles/public/menu"; +import { css } from "@linaria/core"; +import { activeItemAfterStyle } from "styles/common"; // 新建仓库页面下拉菜单 export const newRepo = css` diff --git a/styles/components/notification.ts b/styles/components/notification.ts index 485b6b2..915b7d9 100644 --- a/styles/components/notification.ts +++ b/styles/components/notification.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; // 用户订阅/关注页面 export const notification = css` @@ -29,7 +30,7 @@ export const notification = css` > .divider { display: none; } - // 订阅列表 + /* 订阅列表 */ &:has(#issue-list) { > .tw-flex { align-items: center; @@ -41,7 +42,7 @@ export const notification = css` border-top-right-radius: ${otherThemeVars.border.radius}; height: 52px; padding: 8px; - // 左侧菜单 + /* 左侧菜单 */ > .tw-flex:first-child > .ui.compact.menu { align-items: center; border: 0; @@ -63,7 +64,7 @@ export const notification = css` } } } - // 右侧菜单 + /* 右侧菜单 */ > .tw-flex:last-child > .ui.menu { align-items: center; > .item { @@ -76,7 +77,7 @@ export const notification = css` } } } - // 关注列表 + /* 关注列表 */ > .flex-list:not([id]) { border: 1px solid ${themeVars.color.light.border}; border-radius: ${otherThemeVars.border.radius}; @@ -107,7 +108,7 @@ export const notification = css` } } } - // 通知列表 + /* 通知列表 */ &:has(#notification_table) { > .flex-text-block:first-child { background-color: ${themeVars.color.box.header}; @@ -118,7 +119,7 @@ export const notification = css` height: 52px; padding: 8px; margin-bottom: 0 !important; - // 左侧菜单 + /* 左侧菜单 */ > .ui.compact.menu { align-items: center; border: 0; @@ -144,12 +145,12 @@ export const notification = css` } } } - // 通知全部确认按钮 + /* 通知全部确认按钮 */ .ui.ui.ui.ui.mini.button { height: 32px; } } - // 通知列表 + /* 通知列表 */ #notification_table { border-top-left-radius: 0; border-top-right-radius: 0; diff --git a/styles/components/org.ts b/styles/components/org.ts index bc2d86c..7ad4bad 100644 --- a/styles/components/org.ts +++ b/styles/components/org.ts @@ -17,29 +17,30 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; export const org = css` .page-content.organization { - // 组织成员头像 + /* 组织成员头像 */ .members .ui.avatar { border-radius: 9999px; } - // 组织头像 + /* 组织头像 */ .org-avatar { margin: 8px 24px 16px 0px; } - // 组织信息 + /* 组织信息 */ #org-info { - margin-top: 8px; // 与头像对齐 + margin-top: 8px; /* 与头像对齐 */ gap: 8px; - // 组织名称 + /* 组织名称 */ > .ui.header { font-size: 24px; > .org-visibility { margin-left: 8px; } - // 组织页面的 RSS 订阅按钮 + /* 组织页面的 RSS 订阅按钮 */ .ui.label.button { padding: 4px 16px; .svg { @@ -51,11 +52,11 @@ export const org = css` } } } - // 组织描述 + /* 组织描述 */ > .markup { color: ${themeVars.color.text.light.num1}; } - // 组织信息 + /* 组织信息 */ > .meta { font-size: 12px; svg { diff --git a/styles/components/repo/clone.ts b/styles/components/repo/clone.ts index 20b465c..497890b 100644 --- a/styles/components/repo/clone.ts +++ b/styles/components/repo/clone.ts @@ -17,28 +17,29 @@ * limitations under the License. */ -import { css, customThemeVars, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { customThemeVars, otherThemeVars, themeVars } from "src"; // 克隆按钮的弹窗 export const clone = css` .tippy-box { .clone-panel-popup { - //标题和克隆地址 + /*标题和克隆地址 */ > .clone-panel-field { margin-left: 16px; margin-right: 16px; - //标题 + /* 标题 */ &:first-of-type { font-weight: 600; margin-top: 16px; } } - // 按钮组 + /* 按钮组 */ .clone-panel-tab { display: flex; gap: 8px; margin-left: 16px; - // 按钮 + /* 按钮 */ .item { color: ${themeVars.color.text.self}; font-weight: 600; @@ -65,7 +66,7 @@ export const clone = css` position: relative; } } - // 克隆地址 + /* 克隆地址 */ .ui.input.action { > input { border: 1px solid ${themeVars.color.light.border}; @@ -101,11 +102,11 @@ export const clone = css` } } } - // 面板操作列表之间的分割线 + /* 面板操作列表之间的分割线 */ .divider { margin: 0; } - // 面板操作列表 + /* 面板操作列表 */ .clone-panel-list { margin: 8px; .item { @@ -115,7 +116,7 @@ export const clone = css` margin: 0; gap: 4px; svg { - color: ${themeVars.color.text.light.num1} !important; // 覆盖 .gitea-vscodium 颜色 + color: ${themeVars.color.text.light.num1} !important; /* 覆盖 .gitea-vscodium 颜色 */ margin-right: 4px; } } diff --git a/styles/components/repo/commit.ts b/styles/components/repo/commit.ts index 124447d..94c0e35 100644 --- a/styles/components/repo/commit.ts +++ b/styles/components/repo/commit.ts @@ -17,24 +17,26 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; // 提交列表 export const commit = css` .page-content.repository.commits { - // 提交列表 (选择器保证同等优先级覆盖了 gitea 原生的样式) + /* 提交列表 (选择器保证同等优先级覆盖了 gitea 原生的样式) */ .ui.attached.table.segment.commit-table tbody.commit-list { - // 作者 + /* 作者 */ .author { img.ui.avatar { border-radius: 9999px; } - // 作者名称 + /* 作者名称 */ .author-wrapper { + display: flex; color: ${themeVars.color.text.light.num1}; } } - // SHA 标签 + /* SHA 标签 */ .sha { a.ui.label.commit-id-short { padding: 2px 8px; @@ -44,16 +46,17 @@ export const commit = css` margin-left: -8px; } } - // 提交信息 + /* 提交信息 */ .message { - // tag 标签 + /* tag 标签 */ a.ui.basic.label { border-radius: 9999px; border-width: 1.5px; padding: 3px 8px !important; + margin-left: 4px; } } - // 提交信息右侧 + /* 提交信息右侧 */ .tw-text-right { relative-time, svg { @@ -61,15 +64,15 @@ export const commit = css` } } tr { - // 整行悬停色 + /* 整行悬停色 */ &:hover { background-color: ${themeVars.color.hover.opaque}; } - // 偶数行悬停色 + /* 偶数行悬停色 */ &:nth-child(2n):hover { background-color: ${themeVars.color.hover.opaque} !important; } - // 尾行圆角 + /* 尾行圆角 */ &:last-child { td:first-child { border-bottom-left-radius: ${otherThemeVars.border.radius}; @@ -106,10 +109,10 @@ export const commitGraph = css` img.ui.avatar { border-radius: 9999px; } - // 提交图的 SHA 标签 + /* 提交图的 SHA 标签 */ li .ui.label.commit-id-short { height: 25px; - // 验证提交 SHA 标签 + /* 验证提交 SHA 标签 */ &.commit-is-signed { span.ui.label.commit-is-signed { height: 25px; diff --git a/styles/components/repo/diff.ts b/styles/components/repo/diff.ts index 092ac94..1ab5cec 100644 --- a/styles/components/repo/diff.ts +++ b/styles/components/repo/diff.ts @@ -17,30 +17,31 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; export const diff = css` - // 这里的折叠行和代码行高度与 GitHub 的 release 和 review 的差异对比时的高度一致, 不需要像 commit 中的差异对比那样行高过高 - // release 和 review 行高为 20px, commit 行高为 24px - // 折叠行 + /* 这里的折叠行和代码行高度与 GitHub 的 release 和 review 的差异对比时的高度一致, 不需要像 commit 中的差异对比那样行高过高 */ + /* release 和 review 行高为 20px, commit 行高为 24px */ + /* 折叠行 */ .tag-code { - // 多余的颜色 + /* 多余的颜色 */ background-color: unset; height: 28px; - // 展开按钮高度与折叠行一致 + /* 展开按钮高度与折叠行一致 */ .code-expander-buttons { .code-expander-button { height: 28px; } } - // 双向展开的按钮 + /* 双向展开的按钮 */ &:has(.code-expander-buttons[data-expand-direction="3"]) { height: 40px; .code-expander-button { height: 20px; } } - // 展开按钮 + /* 展开按钮 */ .code-expander-button { color: ${themeVars.color.text.light.num1}; &:hover { @@ -48,21 +49,21 @@ export const diff = css` color: ${themeVars.color.white}; } } - // 折叠行文本 + /* 折叠行文本 */ .code-inner { color: ${themeVars.color.text.light.num1}; } } - // 代码行 + /* 代码行 */ .lines-num, .lines-code { line-height: 20px; } - // 行号居中 + /* 行号居中 */ .lines-num { text-align: center !important; } - // 增加/删除行多余的颜色 + /* 增加/删除行多余的颜色 */ .code-diff-unified { .del-code, .add-code { @@ -70,21 +71,21 @@ export const diff = css` border-color: unset; } } - // 增加/删除相关代码背景色圆角 + /* 增加/删除相关代码背景色圆角 */ .added-code, .removed-code { border-radius: 3px; color: ${themeVars.color.text.self}; - // 覆盖掉 chroma 的颜色 + /* 覆盖掉 chroma 的颜色 */ * { color: ${themeVars.color.text.self} !important; } } - // 差异对比文件盒子 + /* 差异对比文件盒子 */ .diff-file-box { - // 差异对比文件头 + /* 差异对比文件头 */ .diff-file-header { - // 文件名 + /* 文件名 */ .diff-file-name { font-weight: 400; .fold-file.btn svg { @@ -101,11 +102,16 @@ export const diff = css` font-size: 12px; } } - // 操作按钮 + /* 操作按钮 */ .diff-file-header-actions { color: ${themeVars.color.text.light.num1}; font-size: 12px; font-weight: 400; + /* 增加/删除行, 基于 tailwindcss 的属性, 将来可能会失效 */ + .tw-text-diff-added-fg, + .tw-text-diff-removed-fg { + font-weight: 600; + } .diff-header-popup-btn { border-radius: ${otherThemeVars.border.radius}; padding: 5px !important; @@ -116,53 +122,53 @@ export const diff = css` } } } - // 差异对比文件盒子 + /* 差异对比文件盒子 */ .repository .diff-file-box { .code-diff { - // 隐藏多余的空白 - // 合并视图的第三列 + /* 隐藏多余的空白 */ + /* 合并视图的第三列 */ &.code-diff-unified colgroup col:nth-child(3), - // 拆分视图的第二列和第六列 + /* 拆分视图的第二列和第六列 */ &.code-diff-split colgroup col:nth-child(2), &.code-diff-split colgroup col:nth-child(6), td.lines-escape { - width: 0; // 不要使用 display: none; 否则会影响布局, 无内容时为 0, 有内容时为 20(猜测可能是根据内容宽度自动调整) - /* visibility: hidden; */ // 不要使用 visibility: hidden; 当 escape 有内容时会导致背景颜色丢失, escape 目前用于显示检测 unicode 编码错误的内容 + width: 0; /* 不要使用 display: none; 否则会影响布局, 无内容时为 0, 有内容时为 20(猜测可能是根据内容宽度自动调整) */ + /* visibility: hidden; // 不要使用 visibility: hidden; 当 escape 有内容时会导致背景颜色丢失, escape 目前用于显示检测 unicode 编码错误的内容 */ } - // 修复当 escape 有内容时, 宽度不够的问题 + /* 修复当 escape 有内容时, 宽度不够的问题 */ &:has(td.lines-escape:not(:empty)) { - // 合并视图的第三列 + /* 合并视图的第三列 */ &.code-diff-unified colgroup col:nth-child(3), - // 拆分视图的第二列和第六列 + /* 拆分视图的第二列和第六列 */ &.code-diff-split colgroup col:nth-child(2), &.code-diff-split colgroup col:nth-child(6), td.lines-escape { width: 20; } } - // Gitea 分列视图下默认 100% 宽度的目的是如果单文件只增加或只删除的情况下, 保持无内容的列的宽度一致, 始终保持左右两边的列宽度一致 - // 保持 Gitea 的默认设置, 不对行号宽度做处理 + /* Gitea 分列视图下默认 100% 宽度的目的是如果单文件只增加或只删除的情况下, 保持无内容的列的宽度一致, 始终保持左右两边的列宽度一致 */ + /* 保持 Gitea 的默认设置, 不对行号宽度做处理 */ /* &.code-diff-split table { width: auto; } */ - // 行号宽度 + /* 行号宽度 // 40px: 长度 = 9999 行 // 45px: 长度 = 99999 行 // 50px: 长度 = 999999 行 // GitHub 在 commit 中的行宽最小为 40px, 但会动态调整, 在 release 和 review 的差异对比中为 50px - // 这里折中为 45px 会根据代码行数动态调整, 45px 既不会在行数少时显得太宽, 也可以在大多数情况下保持宽度一致 + // 这里折中为 45px 会根据代码行数动态调整, 45px 既不会在行数少时显得太宽, 也可以在大多数情况下保持宽度一致 */ .lines-num { min-width: 45px; } - // 合并视图的第四列 + /* 合并视图的第四列 */ &.code-diff-unified colgroup col:nth-child(4), - // 拆分视图的第三列和第七列, -/+ 保持居中的宽度 + /* 拆分视图的第三列和第七列, -/+ 保持居中的宽度 */ &.code-diff-split colgroup col:nth-child(3), &.code-diff-split colgroup col:nth-child(7) { width: 20; } } - // 修复对比视图内容中的圆角和背景溢出 + /* 修复对比视图内容中的圆角和背景溢出 */ .file-body.file-code { border-radius: 0 0 ${otherThemeVars.border.radius} ${otherThemeVars.border.radius}; overflow: hidden; diff --git a/styles/components/repo/milestones.ts b/styles/components/repo/milestones.ts index ba8b1f6..a5b6ea5 100644 --- a/styles/components/repo/milestones.ts +++ b/styles/components/repo/milestones.ts @@ -17,24 +17,25 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; export const milestone = css` - // 里程碑头部 + /* 里程碑头部 */ .milestone-header { gap: 16px; - // 进度条 + /* 进度条 */ progress { height: 5px; width: 300px; max-width: 80vw; } } - // 里程碑 Issue 列表的进度条 + /* 里程碑 Issue 列表的进度条 */ .milestone-progress-big { height: 8px; } - // 里程碑 Issue 列表 + /* 里程碑 Issue 列表 */ .page-content.repository.milestone-issue-list { > .ui.container { > .flex-text-block:first-child { diff --git a/styles/components/repo/packages.ts b/styles/components/repo/packages.ts index e097ee6..26b9f40 100644 --- a/styles/components/repo/packages.ts +++ b/styles/components/repo/packages.ts @@ -17,12 +17,13 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; // 组织/仓库的软件包列表(包含用户但未测试) export const packagesList = css` .page-content.packages { - // 这里必须要用 >, 否则会影响到软件包详细信息页的样式 + /* 这里必须要用 >, 否则会影响到软件包详细信息页的样式 */ > .ui.container > div:not([class]) { border: 1px solid ${themeVars.color.light.border}; border-radius: ${otherThemeVars.border.radius}; @@ -40,7 +41,7 @@ export const packagesList = css` > a { min-height: 25px; } - // 软件包类型的标签 + /* 软件包类型的标签 */ .ui.label { gap: 4px; padding: 3px 6px; @@ -109,7 +110,7 @@ export const packagesDetail = css` > .divider { margin: 16px 0px; } - // 详情 + /* 详情 */ > .ui.relaxed.list { margin: 16px 0px; .item { @@ -117,7 +118,7 @@ export const packagesDetail = css` svg { color: ${themeVars.color.text.self}; } - // 应该只选中版本中的 a 标签 + /* 应该只选中版本中的 a 标签 */ &.tw-flex { justify-content: space-between; > a { @@ -131,7 +132,7 @@ export const packagesDetail = css` text-decoration: none; } } - // 不知道什么东西 + /* 不知道什么东西 */ &::after { display: none; } diff --git a/styles/components/repo/release.ts b/styles/components/repo/release.ts index ba91447..45a312e 100644 --- a/styles/components/repo/release.ts +++ b/styles/components/repo/release.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; // release 顶部栏左侧按钮组 export const releaseTagMenu = css` @@ -62,7 +63,7 @@ export const rightButton = css` // 标签页样式 export const tags = css` .page-content.repository.tags { - // 标签的选项取消下划线 + /* 标签的选项取消下划线 */ .tag-list-row { .tag-list-row-title { line-height: 1.5; @@ -92,7 +93,7 @@ export const releases = css` gap: 32px; margin: 32px 0 16px 0; .release-entry { - // 左侧发布元信息 + /* 左侧发布元信息 */ .meta { gap: 0.5rem; padding-top: 24px; @@ -113,7 +114,7 @@ export const releases = css` margin-top: 1px; } } - // 分支选择按钮 + /* 分支选择按钮 */ .ui.button.branch-dropdown-button { min-height: 20px; line-height: 20px; @@ -121,7 +122,7 @@ export const releases = css` font-size: 12px; } } - // 右侧发布详细信息 + /* 右侧发布详细信息 */ .segment.detail { padding: 16px; img.ui.avatar { @@ -130,12 +131,12 @@ export const releases = css` .svg { color: ${themeVars.color.text.light.num1}; } - // 标题 + /* 标题 */ .release-list-title { font-size: 32px; gap: 8px; } - // 提交信息 + /* 提交信息 */ p.text.grey { display: flex; gap: 6px; @@ -148,13 +149,13 @@ export const releases = css` color: ${themeVars.color.text.self}; } } - // 发布内容 + /* 发布内容 */ .markup { > *:first-child { margin-top: 24px !important; } } - // 分割线 + /* 分割线 */ .divider { position: relative; left: -16px; @@ -162,7 +163,7 @@ export const releases = css` border-top-width: 1px; margin: 24px 0 16px 0; } - // 下载列表 + /* 下载列表 */ .download { summary { font-size: 16px; @@ -181,7 +182,7 @@ export const releases = css` .flex-text-inline { gap: 8px; } - // 只选中左侧文件名称 + /* 只选中左侧文件名称 */ strong.flex-text-inline:hover { text-decoration: underline !important; } diff --git a/styles/components/repo/repo.ts b/styles/components/repo/repo.ts index 3c22e1f..f112ee8 100644 --- a/styles/components/repo/repo.ts +++ b/styles/components/repo/repo.ts @@ -17,21 +17,22 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; // 仓库头信息 export const repoHeader = css` .page-content.repository .repo-header { - // 点星/关注/克隆/RSS 按钮 + /* 点星/关注/克隆/RSS 按钮 */ .ui.compact.button { padding: 3px 12px; } - // 仓库名称 + /* 仓库名称 */ .flex-item { .flex-item-title { - // 间隔线颜色 + /* 间隔线颜色 */ color: ${themeVars.color.text.light.num1}; - // 仓库名称 + /* 仓库名称 */ a { display: flex; align-items: center; @@ -51,7 +52,7 @@ export const repoHeader = css` } } } - // 默认的 hover 为 primary 颜色, 修正 + /* 默认的 hover 为 primary 颜色, 修正 */ a:not(.label, .button):hover { color: ${themeVars.color.text.self} !important; } @@ -66,7 +67,7 @@ export const repoMenu = css` background-color: ${themeVars.color.box.header}; .item { color: ${themeVars.color.text.light.num1}; - height: 31px; // 文件列表下与右侧输入框对齐 + height: 31px; /* 文件列表下与右侧输入框对齐 */ b { color: ${themeVars.color.text.self}; margin: 0 2px; @@ -85,10 +86,10 @@ export const repoMenu = css` `; export const repoTopic = css` - // 理应只能覆盖探索/组织/用户下仓库的 topic 标签 - // 避免渲染到仓库的类型标签 + /* 理应只能覆盖探索/组织/用户下仓库的 topic 标签 */ + /* 避免渲染到仓库的类型标签 */ .flex-item-main > .label-list .ui.label, - // 仓库文件列表下的 topic 标签 + /* 仓库文件列表下的 topic 标签 */ #repo-topics .ui.label.repo-topic { border-radius: 9999px; font-size: 12px; diff --git a/styles/components/repo/repo_file_view.ts b/styles/components/repo/repo_file_view.ts index 43b205f..4dee903 100644 --- a/styles/components/repo/repo_file_view.ts +++ b/styles/components/repo/repo_file_view.ts @@ -17,35 +17,37 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; -import { activeItemAfterStyle } from "styles/public/menu"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; +import { activeItemAfterStyle } from "styles/common"; // 仓库打开文件时的视图 export const repoFileView = css` - // 隐藏主内容的下内容和页脚, 避免滚动文件树时滚动条遮挡 + /* 隐藏主内容的下内容和页脚, 避免滚动文件树时滚动条遮挡 */ body > .full.height:has(.repo-view-file-tree-container) { padding-bottom: 0; + .page-footer { display: none; } } - .page-content.repository.file.list { + .page-content.repository.file.list, + .page-content.repository.file.editor { &:has(.repo-view-file-tree-container) { - // 取消下间隔优化观看体验 + /* 取消下间隔优化观看体验 */ > .secondary-nav { margin-bottom: 0 !important; .ui.tabs.divider { margin-bottom: 0; } } - // 为文件树选中项目伪元素让出 8px 的空间 + /* 为文件树选中项目伪元素让出 8px 的空间 */ > .ui.container.fluid { margin-left: 8px; max-width: calc(100% - calc(2 * 8px)); } } .repo-view-container { - // 左侧文件树 + /* 左侧文件树 */ .repo-view-file-tree-container { height: 100vh; flex: 0 0 20%; @@ -67,7 +69,7 @@ export const repoFileView = css` font-size: 16px; margin: 16px 0; padding: 8px; - // 固定头部, 早期父元素有多余的页脚和内容高度导致滚动时无法固定, 修复后也可保留此属性无需删除 + /* 固定头部, 早期父元素有多余的页脚和内容高度导致滚动时无法固定, 修复后也可保留此属性无需删除 */ position: sticky; top: 0; &:after { @@ -100,7 +102,7 @@ export const repoFileView = css` } } } - // 右侧文件视图内容 + /* 右侧文件视图内容 */ .repo-view-content { padding-bottom: 40px; .repo-button-row { @@ -108,7 +110,7 @@ export const repoFileView = css` background: ${themeVars.color.box.header}; border: 1px solid ${themeVars.color.secondary.self}; border-radius: ${otherThemeVars.border.radius}; - height: 46px; // 固定高度匹配第二固定栏的 top 值 + height: 46px; /* 固定高度匹配第二固定栏的 top 值 */ margin: 16px 0; padding: 8px; position: sticky; @@ -117,7 +119,7 @@ export const repoFileView = css` .ui.button { min-height: 32px; } - // 打开文件树按钮 + /* 打开文件树按钮 */ .repo-view-file-tree-toggle { background: initial; border-color: #0000; @@ -127,11 +129,11 @@ export const repoFileView = css` background: ${themeVars.color.hover.self}; } } - // 分支选择按钮 + /* 分支选择按钮 */ .branch-dropdown-button { padding: 0 12px; } - // 路径 + /* 路径 */ .repo-path { gap: 4px; .section { @@ -149,13 +151,13 @@ export const repoFileView = css` } } .non-diff-file-content { - // 避免分支菜单遮挡 + /* 避免分支菜单遮挡 */ position: relative; z-index: 0; h4.file-header { padding: 8px 12px !important; position: sticky; - // 重叠边框线, 避免过粗 + /* 重叠边框线, 避免过粗 */ top: 45px; z-index: 1; .file-header-left { @@ -164,9 +166,9 @@ export const repoFileView = css` } .file-header-right { gap: 0px; - // 按钮组 + /* 按钮组 */ > .ui.buttons { - margin: 0 8px 0 0 !important; // 完全不知道为什么浏览器最终效果没生效, 只能 !important 了 + margin: 0 8px 0 0 !important; /* 完全不知道为什么浏览器最终效果没生效, 只能 !important 了 */ .ui.mini.button { min-height: 28px; height: 28px; @@ -174,7 +176,7 @@ export const repoFileView = css` padding: 0 8px; } } - // 右侧操作按钮 + /* 右侧操作按钮 */ > .btn-octicon { display: flex; align-items: center; @@ -194,7 +196,7 @@ export const repoFileView = css` &:last-of-type { border-top-right-radius: ${otherThemeVars.border.radius}; border-bottom-right-radius: ${otherThemeVars.border.radius}; - // 与无权限按钮之间的间距 + /* 与无权限按钮之间的间距 */ + .btn-octicon.disabled { margin-left: 8px; } @@ -207,7 +209,7 @@ export const repoFileView = css` } } } - // 头部提交信息 + /* 头部提交信息 */ .ui.segment#repo-file-commit-box { padding: 8px 12px; margin-bottom: 16px !important; @@ -217,7 +219,7 @@ export const repoFileView = css` .commit-summary { color: ${themeVars.color.text.light.num1}; } - // 作者 + /* 作者 */ .author-wrapper { display: flex; } @@ -227,7 +229,7 @@ export const repoFileView = css` height: 20px; } } - // 右侧提交时间 + /* 右侧提交时间 */ > .age { display: flex; align-items: center; @@ -241,17 +243,158 @@ export const repoFileView = css` // 避免手机/平板下路径容器过长导致换行, 取消固定 export const repoFileViewMobile = css` @media (max-width: 1023.98px) { - .page-content.repository.file.list .repo-view-container .repo-view-content { - .repo-button-row { - height: auto; - position: static; - z-index: 0; - } - .non-diff-file-content { - h4.file-header { - top: 0; + .page-content.repository.file.list, + .page-content.repository.file.editor { + .repo-view-container .repo-view-content { + .repo-button-row { + height: auto; + position: static; + z-index: 0; + } + .non-diff-file-content { + h4.file-header { + top: 0; + } } } } } `; + +// 代码编辑器 +export const codeEditorContainer = css` + .code-editor-container { + /* Gitea 限制最小高度为 90vh, 导致手机下留白过多, 但意义不明? */ + min-height: auto; + /* 搜索面板 */ + .cm-panel.cm-search { + background-color: ${themeVars.color.box.header}; + padding: 8px; + gap: 0; + .cm-textfield { + background-color: ${themeVars.color.body}; + margin: 4px 8px 4px 0px; + } + .cm-button { + background-color: ${themeVars.color.body}; + padding: 4px 8px; + margin: 4px 8px 4px 0px; + text-transform: capitalize; + &:hover { + background-color: ${themeVars.color.button}; + } + &:active { + background-image: none; + background-color: ${themeVars.color.hover.self}; + } + } + > label { + margin: 4px 8px 4px 0px; + font-size: 12px; + font-weight: 600; + text-transform: capitalize; + } + /* 关闭按钮 */ + button[name="close"] { + color: ${themeVars.color.text.self}; + width: 14px; + height: 14px; + } + } + /* 编辑区 */ + .cm-scroller, + .ͼ1 .cm-scroller { + font-family: + ui-monospace, + SFMono-Regular, + SF Mono, + Menlo, + Consolas, + Liberation Mono, + monospace; + } + } +`; + +// 文件编辑器 +export const fileEditor = css` + .page-content.repository.file.editor { + .repo-view-content { + /* 编辑器 */ + .ui.edit.form { + /* 路径栏 */ + .repo-editor-header { + margin: 16px 0; + min-height: 32px; + /* 路径 */ + .breadcrumb { + gap: 8px; + /* 路径段和分隔符 */ + .section, + .breadcrumb-divider { + font-size: 16px; + } + > .section:first-child { + font-weight: 600; + } + input { + margin-right: 0px !important; + } + svg { + color: ${themeVars.color.text.light.num1}; + } + span:has(svg) { + display: flex; + align-items: center; + } + } + } + /* 编辑器操作栏 */ + .ui.top.attached.header { + padding: 8px; + /* 左侧编辑/预览切换按钮 */ + .ui.compact.small.menu.small-menu-items { + /* 切换样式在 compact_menu.ts 中 */ + .item svg { + display: none; + } + } + /* 右侧操作项 */ + .code-editor-options { + /* 图标按钮 */ + .ui.compact.icon.button { + padding: 7px; + svg { + width: 14px; + height: 14px; + min-width: 14px; + min-height: 14px; + } + } + /* 选择下拉菜单 */ + select { + background: ${themeVars.color.body}; + font-size: 12px; + padding: 7px 20px 7px 12px; + } + } + } + } + } + } +`; + +// 提交表单(编译修改时底部的提交信息) +export const commitForm = css` + .repository.file.editor .commit-form-wrapper { + .commit-avatar { + border-radius: 9999px; + } + .commit-form.avatar-content-left-arrow { + &::before, + &::after { + display: none; + } + } + } +`; diff --git a/styles/components/repo/repo_files.ts b/styles/components/repo/repo_files.ts index 2fd8557..4cd744f 100644 --- a/styles/components/repo/repo_files.ts +++ b/styles/components/repo/repo_files.ts @@ -17,20 +17,21 @@ * limitations under the License. */ -import { animationDown } from "src/core/styles"; -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; +import { animationDown } from "styles/common"; // 文件列表页面下的分支按钮 export const branchButton = css` .page-content.repository.file.list { .ui.dropdown.branch-selector-dropdown > .menu > .menu { - // 显示默认分支的标签 + /* 显示默认分支的标签 */ .ui.label { background-color: ${themeVars.color.menu}; border: 1px solid ${themeVars.color.light.border}; margin-top: 1px; margin-left: auto; - margin-right: 20px; // gitea 有 RSS 留出足够的空间 + margin-right: 20px; /* gitea 有 RSS 留出足够的空间 */ } } } @@ -52,12 +53,12 @@ export const syncFork = css` export const fileSearch = css` .file-search-popup.file-search-popup.file-search-popup { ${animationDown}; - // 统一所有下拉菜单的样式 + /* 统一所有下拉菜单的样式 */ background-color: ${themeVars.color.menu}; border: unset; border-radius: 12px; box-shadow: ${themeVars.github.shadow.floating.small}; - z-index: 2; // 避免文件内容浏览界面中的固定导航栏遮挡 + z-index: 2; /* 避免文件内容浏览界面中的固定导航栏遮挡 */ .file-search-results { padding: 12px; .item { @@ -82,11 +83,11 @@ export const fileSearch = css` `; // 仓库文件列表 export const repoFiles = css` - // 文件列表和提交列表的按钮组 + /* 文件列表和提交列表的按钮组 */ .repo-button-row { margin: 16px 0; .repo-button-row-right { - // 转到文件搜索框 + /* 转到文件搜索框 */ .repo-file-search-container .ui.input { min-height: 32px; height: 32px; @@ -94,7 +95,7 @@ export const repoFiles = css` background: unset; } } - // 添加文件按钮 + /* 添加文件按钮 */ .repo-add-file { padding: 0px 26px 0px 12px; .menu > .item { @@ -110,10 +111,10 @@ export const repoFiles = css` .repository.file.list { #repo-files-table { margin: 16px 0; - // 头部最后一次提交 + /* 头部最后一次提交 */ .repo-file-line { padding-right: 16px; - // 父目录 + /* 父目录 */ &.parent-link { gap: 0.5rem; padding-left: 16px; @@ -121,7 +122,7 @@ export const repoFiles = css` margin-right: 2px; } } - // 最后一次提交 + /* 最后一次提交 */ &.repo-file-last-commit { min-height: 3.725rem; .latest-commit { @@ -135,14 +136,14 @@ export const repoFiles = css` width: 20px; height: 20px; } - // 作者 + /* 作者 */ .author-wrapper { display: flex; &:hover { color: ${themeVars.color.text.self}; } } - // 提交哈希值 + /* 提交哈希值 */ .ui.label { display: none; } @@ -152,7 +153,7 @@ export const repoFiles = css` } } } - // 文件列表 + /* 文件列表 */ .repo-file-item { .repo-file-cell { height: 40px; @@ -180,7 +181,7 @@ export const repoFiles = css` .file-header-left { padding: 6px 8px !important; line-height: 1.45; - // 伪元素宽度等于按钮宽度而不是父元素宽度 + /* 伪元素宽度等于按钮宽度而不是父元素宽度 */ position: relative; &:hover { background: ${themeVars.github.control.transparent.bgColor.hover}; diff --git a/styles/components/repo/repo_sidebar.ts b/styles/components/repo/repo_sidebar.ts index be917e1..6c47d75 100644 --- a/styles/components/repo/repo_sidebar.ts +++ b/styles/components/repo/repo_sidebar.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; // 仓库代码布局调整, 侧边栏宽度调整 export const repoGrid = css` @@ -37,7 +38,7 @@ export const repoGrid = css` export const repoSidebarTop = css` .page-content.repository.file.list { .repo-home-sidebar-top { - // 搜索代码 + /* 搜索代码 */ .ui.input > input { background: unset; } @@ -46,11 +47,11 @@ export const repoSidebarTop = css` } .flex-item { padding: 10px 0 0 0; - // 仓库描述本身 + /* 仓库描述本身 */ .flex-item-title { margin-top: 10px; } - // 仓库描述内容 + /* 仓库描述内容 */ .flex-item-body { > .tw-flex:first-child { margin-top: 16px !important; @@ -108,7 +109,7 @@ export const repoSidebarBottom = css` font-size: 12px; } } - // 编程语言 + /* 编程语言 */ .language-stats { height: 8px; margin-bottom: 0px; diff --git a/styles/components/setting.ts b/styles/components/setting.ts index ab29bb3..d427c28 100644 --- a/styles/components/setting.ts +++ b/styles/components/setting.ts @@ -17,9 +17,10 @@ * limitations under the License. */ -import { type StyleRule } from "@vanilla-extract/css"; -import { css, themeVars } from "src/types/vars"; -import { primaryHoverStyle, primaryStyle } from "styles/public/button"; +import { css } from "@linaria/core"; +import type { StyleRule } from "@vanilla-extract/css"; +import { themeVars } from "src"; +import { primaryButtonHoverStyle, primaryButtonStyle } from "styles/common"; const tinyStyle = { color: themeVars.github.button.primary.fgColor.accent, @@ -35,12 +36,12 @@ const tinyHoverStyle = { // 设置界面下的按钮 export const button = css` - // 不包含管理员的设置界面 + /* 不包含管理员的设置界面 */ .user-main-content, .repo-setting-content, .user-setting-content, .org-setting-content { - // 主色调按钮替换为普通按钮 + /* 主色调按钮替换为普通按钮 */ .ui.primary.button { color: ${themeVars.color.text.light.self}; background-color: ${themeVars.color.button}; @@ -53,7 +54,7 @@ export const button = css` background-color: ${themeVars.github.button.default.bgColor.active}; } } - // 迷你按钮替换为自定义的主色调按钮 (例: SSH 验证按钮) + /* 迷你按钮替换为自定义的主色调按钮 (例: SSH 验证按钮) */ .ui.primary.button.tiny { ${tinyStyle} &:hover { @@ -64,21 +65,21 @@ export const button = css` } } } - // 所有设置界面 + /* 所有设置界面 */ .user-main-content, .repo-setting-content, .user-setting-content, .org-setting-content, .admin-setting-content { - // 右上角迷你按钮替换会主色调按钮 + /* 右上角迷你按钮替换会主色调按钮 */ .ui.attached.header > .ui.right { .ui.primary.button.tiny { - ${primaryStyle} + ${primaryButtonStyle} padding: 3px 12px; min-height: 20px; line-height: 20px; &:hover { - ${primaryHoverStyle} + ${primaryButtonHoverStyle} } &:active { background-color: ${themeVars.github.button.primary.bgColor.active}; @@ -86,7 +87,7 @@ export const button = css` } } } - // 管理员设置界面下的自定义主色调按钮 + /* 管理员设置界面下的自定义主色调按钮 */ .admin-setting-content { .ui.primary.button { ${tinyStyle} @@ -97,7 +98,7 @@ export const button = css` } &:active { background-color: ${themeVars.github.button.primary.bgColor.active}; - // 保持鼠标移开时边框颜色和文字颜色不变 + /* 保持鼠标移开时边框颜色和文字颜色不变 */ border-color: ${themeVars.github.button.primary.borderColor.hover}; color: ${themeVars.github.button.primary.fgColor.rest}; } @@ -111,9 +112,9 @@ export const button = css` `; export const label = css` - // Runner 标签 + /* Runner 标签 */ .runner-container { - // 普通标签, runner 状态: 离线, runner 标签 + /* 普通标签, runner 状态: 离线, runner 标签 */ .ui.label { border: 1px solid ${themeVars.color.light.border}; } diff --git a/styles/components/signin.ts b/styles/components/signin.ts index 346b093..2cc1e63 100644 --- a/styles/components/signin.ts +++ b/styles/components/signin.ts @@ -17,7 +17,7 @@ * limitations under the License. */ -import { css } from "src/types/vars"; +import { css } from "@linaria/core"; // 注册/登录界面 export const signIn = css` diff --git a/styles/components/user.ts b/styles/components/user.ts index 22d9c72..ab08073 100644 --- a/styles/components/user.ts +++ b/styles/components/user.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; // 用户点星仓库列表 export const stars = css` @@ -29,27 +30,27 @@ export const stars = css` &:first-child { padding-top: 14px; } - // 仓库头像 + /* 仓库头像 */ > .flex-item-leading { img, svg { color: ${themeVars.color.text.light.num1}; } } - // 仓库信息 + /* 仓库信息 */ > .flex-item-main { - // 仓库标题 + /* 仓库标题 */ > .flex-item-header { - // 仓库名称 + /* 仓库名称 */ > .flex-item-title { font-size: 20px; gap: 8px; - // 仓库中间的间隔线 + /* 仓库中间的间隔线 */ &:not(a) { color: ${themeVars.color.primary.self}; } } - // 仓库语言, 星标 + /* 仓库语言, 星标 */ > .flex-item-trailing { color: ${themeVars.color.text.light.num1}; gap: 16px; @@ -61,15 +62,15 @@ export const stars = css` } } } - // 描述和更新时间 + /* 描述和更新时间 */ > .flex-item-body { margin-top: 10px; - // 更新时间 + /* 更新时间 */ &:last-child { font-size: 12px; } } - // 主题标签 + /* 主题标签 */ > .label-list { margin-top: 10px; } diff --git a/styles/public/attached.ts b/styles/public/attached.ts index c2ead2e..40d9fb8 100644 --- a/styles/public/attached.ts +++ b/styles/public/attached.ts @@ -17,17 +17,18 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; export const attached = css` - // 设置右面板的内容 + /* 设置右面板的内容 */ .user-main-content, .repo-setting-content, .user-setting-content, .org-setting-content, .admin-setting-content, - // 仓库动态页面 - // 新建页面内容 + /* 仓库动态页面 */ + /* 新建页面内容 */ .page-content.repository.new-repo, .page-content.repository.new.migrate, .page-content.repository.new.fork, @@ -56,7 +57,7 @@ export const attached = css` border-top-left-radius: 0 !important; border-top-right-radius: 0 !important; } - // 隐藏的元素下面的元素, 目前仅适用于在后台控制中的自我检查 + /* 隐藏的元素下面的元素, 目前仅适用于在后台控制中的自我检查 */ &.tw-hidden + .ui.attached.segment { border-top-width: 1px !important; border-top-left-radius: ${otherThemeVars.border.radius} !important; diff --git a/styles/public/base.ts b/styles/public/base.ts index 9542c88..be822c7 100644 --- a/styles/public/base.ts +++ b/styles/public/base.ts @@ -17,20 +17,20 @@ * limitations under the License. */ -import { css } from "src/types/vars"; +import { css } from "@linaria/core"; export const body = css` body { line-height: 1.5; } a { - text-underline-offset: 0.2rem; // 0.2rem 可以始终保持下划线不受 overflow: hidden 的影响 + text-underline-offset: 0.2rem; /* 0.2rem 可以始终保持下划线不受 overflow: hidden 的影响 */ } - // 默认代码块 + /* 默认代码块 */ code:not(.code-inner) { padding: 0.2em 0.4em; } - // 快捷键提示(输入框内) + /* 快捷键提示(输入框内) */ kbd { background-color: #0000; font-size: 12px; diff --git a/styles/public/button.ts b/styles/public/button.ts index 0e6d7b7..c506252 100644 --- a/styles/public/button.ts +++ b/styles/public/button.ts @@ -17,21 +17,9 @@ * limitations under the License. */ -import { type StyleRule } from "@vanilla-extract/css"; -import { css, themeVars } from "src/types/vars"; - -export const primaryStyle = { - color: themeVars.github.button.primary.fgColor.rest, - backgroundColor: themeVars.github.button.primary.bgColor.rest, - borderColor: themeVars.github.button.primary.borderColor.rest, - boxShadow: themeVars.github.shadow.resting.small, -} satisfies StyleRule; - -export const primaryHoverStyle = { - color: themeVars.github.button.primary.fgColor.rest, - backgroundColor: themeVars.github.button.primary.bgColor.hover, - borderColor: themeVars.github.button.primary.borderColor.hover, -} satisfies StyleRule; +import { css } from "@linaria/core"; +import { themeVars } from "src"; +import { primaryButtonHoverStyle, primaryButtonStyle } from "styles/common"; // 普通按钮和主色调按钮 export const baseButton = css` @@ -46,33 +34,34 @@ export const baseButton = css` .ui.button:not(.primary):not(.red) svg { color: ${themeVars.color.text.light.num1}; } - // 主色调按钮保持白色 - .ui.primary.buttons .button svg { - color: ${themeVars.color.white}; - } + /* 主色调按钮 */ .ui.primary { &.button, - // 按钮组, PR 里的压缩合并按钮 + /* 按钮组, PR 里的压缩合并按钮 */ &.buttons .button { - ${primaryStyle} + ${primaryButtonStyle} &:hover { - ${primaryHoverStyle} + ${primaryButtonHoverStyle} } &:active { + ${primaryButtonHoverStyle} background-color: ${themeVars.github.button.primary.bgColor.active}; } + svg { + color: ${themeVars.github.button.primary.fgColor.rest}; + } } - // 按钮组整体有阴影 + /* 按钮组整体有阴影 */ &.buttons { box-shadow: ${themeVars.github.shadow.resting.small}; .button { - // 按钮组里的按钮无阴影 + /* 按钮组里的按钮无阴影 */ box-shadow: none; } } } - // 主色调基本按钮和普通按钮一样 - // 作者的关注按钮 + /* 主色调基本按钮和普通按钮一样 */ + /* 作者的关注按钮 */ .ui.basic.primary.button { background-color: ${themeVars.color.button}; color: ${themeVars.color.text.self}; @@ -112,7 +101,7 @@ export const redButton = css` .ui.basic.red.button { color: ${themeVars.github.button.danger.fgColor.rest}; background-color: ${themeVars.github.button.danger.bgColor.rest}; - // 一些按钮边框色为红色, 比如危险操作区, 统一为暗色边框和 github 一致 + /* 一些按钮边框色为红色, 比如危险操作区, 统一为暗色边框和 github 一致 */ border-color: ${themeVars.color.light.border}; &:hover { color: ${themeVars.github.button.danger.fgColor.hover}; @@ -131,18 +120,18 @@ export const redButton = css` // 修复按钮高度 export const fixButtonHeight = css` - // 修复一些主色调或者其他小按钮的高度避免过高 + /* 修复一些主色调或者其他小按钮的高度避免过高 */ .ui.small.buttons .button, .ui.ui.ui.ui.small.button { min-height: 26px; height: 32px; } - // 修复仓库页仓库操作按钮高度对齐和修正 + /* 修复仓库页仓库操作按钮高度对齐和修正 */ .repo-button-row .ui.button { min-height: 32px; height: 32px; } - // 修复因上面小按钮高度导致仓库星标克隆等按钮高度过高 + /* 修复因上面小按钮高度导致仓库星标克隆等按钮高度过高 */ .repo-header { .ui.ui.ui.ui.small.compact.button, .ui.labeled.button > .label { @@ -158,11 +147,11 @@ export const fixButtonHeight = css` `; export const fixButton = css` - // 修复关注&派生 hover 意外点亮右侧 label 左边框 + /* 修复关注&派生 hover 意外点亮右侧 label 左边框 */ .ui.ui.ui.ui.small.button { z-index: 0; } - // 代码复制按钮 + /* 代码复制按钮 */ .ui.button.code-copy { padding: 4px 6px; min-height: 28px; diff --git a/styles/public/dropdown/branch_dropdown.ts b/styles/public/dropdown/branch_dropdown.ts index 53a1654..99e0577 100644 --- a/styles/public/dropdown/branch_dropdown.ts +++ b/styles/public/dropdown/branch_dropdown.ts @@ -17,9 +17,10 @@ * limitations under the License. */ -import { animationDown } from "src/core/styles"; -import { fallbackVar } from "src/functions"; -import { css, customThemeVars, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { fallbackVar } from "@vanilla-extract/css"; +import { customThemeVars, otherThemeVars, themeVars } from "src"; +import { animationDown } from "styles/common"; // 分支菜单 export const branchDropdown = css` @@ -30,7 +31,7 @@ export const branchDropdown = css` ${animationDown}; height: 32px; } - // 分支/标签切换 + /* 分支/标签切换 */ > .branch-tag-tab { > .branch-tag-item { font-weight: 500; @@ -61,7 +62,7 @@ export const branchDropdown = css` // 手机页面下的分支菜单 export const branchDropdownMobile = css` @media (max-width: 767.98px) { - // 修复手机下分支菜单宽度过宽 + /* 修复手机下分支菜单宽度过宽 */ .ui.dropdown.branch-selector-dropdown > .menu { width: auto; } diff --git a/styles/public/dropdown/dropdown.ts b/styles/public/dropdown/dropdown.ts index d07c3c0..4774f82 100644 --- a/styles/public/dropdown/dropdown.ts +++ b/styles/public/dropdown/dropdown.ts @@ -17,21 +17,25 @@ * limitations under the License. */ -import { animationDown, animationUp } from "src/core/styles"; -import { css, otherThemeVars, themeVars } from "src/types/vars"; -import { activeItemAfterStyle } from "styles/public/menu"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; +import { activeItemAfterStyle, animationDown, animationUp } from "styles/common"; export const dropdown = css` .ui.dropdown, .ui.menu .ui.dropdown { .menu { ${animationDown}; - // 统一所有下拉菜单的样式 - background-color: ${themeVars.color.menu} !important; - border: unset !important; + /* 统一所有下拉菜单的样式 */ + background-color: ${themeVars.color.menu}; + border: none !important; border-radius: 12px !important; - box-shadow: ${themeVars.github.shadow.floating.small} !important; - // 忽略隐藏 + box-shadow: ${themeVars.github.shadow.floating.small}; + /* 修复 lightingcss 导致的优先级问题 */ + &.scrolling { + box-shadow: none !important; + } + /* 忽略隐藏 */ > .item:not(.tw-hidden) { display: flex !important; align-items: center; @@ -45,14 +49,14 @@ export const dropdown = css` } &:not(.emoji):first-of-type { margin-top: 8px; - // 工单详细页面的标签菜单中的清除选中标签按钮 + /* 工单详细页面的标签菜单中的清除选中标签按钮 */ &.clear-selection { margin-top: 0px; } } - // 不知道为什么提交差异对比页面操作中的 cherrypick 按钮无法被选中 + /* 不知道为什么提交差异对比页面操作中的 cherrypick 按钮无法被选中 */ &.cherry-pick-button, - // 下一个 item 是最后一个并且被隐藏时, 目前仅在顶部导航栏工单和 PR 仪表板的菜单中出现 + /* 下一个 item 是最后一个并且被隐藏时, 目前仅在顶部导航栏工单和 PR 仪表板的菜单中出现 */ &:has(+ .tw-hidden:last-of-type), &:not(.emoji):last-of-type { margin-bottom: 8px; @@ -77,18 +81,18 @@ export const dropdown = css` margin-top: 2px; margin-right: 2px; } - // 复选框对齐 + /* 复选框对齐 */ .ui.checkbox input[type="checkbox"] { top: 3px; } - // 修复 Wiki 页面下搜索框中搜索时, 显示隐藏的项目 + /* 修复 Wiki 页面下搜索框中搜索时, 显示隐藏的项目 */ &.filtered { display: none !important; } } - // 当筛选后, 让菜单提供边距, 因为无法确定保留的是菜单中哪个 item - // 不是所有菜单都提供边距方式, 原因为比如会导致分支菜单中的查看所有分支上间隔缺失, 这种方式单独为 Wiki 菜单做处理 - // 有筛选(.filtered)且有筛选结果(.selected)时提供菜单边距, 没结果时提供会导致多余的菜单边框线 + /* 当筛选后, 让菜单提供边距, 因为无法确定保留的是菜单中哪个 item */ + /* 不是所有菜单都提供边距方式, 原因为比如会导致分支菜单中的查看所有分支上间隔缺失, 这种方式单独为 Wiki 菜单做处理 */ + /* 有筛选(.filtered)且有筛选结果(.selected)时提供菜单边距, 没结果时提供会导致多余的菜单边框线 */ &:has(> .item.filtered):has(> .item.selected) { padding: 8px 0px; > .item { @@ -108,14 +112,14 @@ export const dropdown = css` } } } - // 向下弹出的下拉菜单向下偏移 + /* 向下弹出的下拉菜单向下偏移 */ .ui.dropdown:not(.upward), .ui.menu .ui.dropdown:not(.upward) { > .menu { margin-top: 4px !important; } } - // 向上弹出的下拉菜单向上偏移 + /* 向上弹出的下拉菜单向上偏移 */ .ui.dropdown.upward, .ui.menu .ui.dropdown.upward { > .menu { @@ -123,41 +127,41 @@ export const dropdown = css` margin-bottom: 4px !important; } } - // 修复 wiki 的页面下拉菜单圆角 + /* 修复 wiki 的页面下拉菜单圆角 */ .ui.floating.dropdown > .menu { border-radius: 12px !important; } - // 修复嵌套菜单的圆角问题, wiki 页面和组织页面的用户下拉菜单 + /* 修复嵌套菜单的圆角问题, wiki 页面和组织页面的用户下拉菜单 */ .ui.dropdown .menu { .scrolling.menu { border-radius: 0 0 12px 12px !important; } - // 修复仪表板切换用户按钮菜单下无创建组织按钮时的菜单圆角 + /* 修复仪表板切换用户按钮菜单下无创建组织按钮时的菜单圆角 */ &.context-user-switch { .scrolling.menu:last-child { border-radius: 0 0 12px 12px !important; } } } - // 修复下拉菜单元素溢出问题 - // 用户菜单 + /* 修复下拉菜单元素溢出问题 */ + /* 用户菜单 */ .user-menu>.item, - // Issue/PR 菜单 + /* Issue/PR 菜单 */ .ui.menu .ui.dropdown.item .menu .item { - width: calc(100% - 16px); // 减去上方 item 的 margin 左右边距 + width: calc(100% - 16px); /* 减去上方 item 的 margin 左右边距 */ } - // 去掉下拉菜单的边框线 - // 设置里的下拉菜单 + /* 去掉下拉菜单的边框线 */ + /* 设置里的下拉菜单 */ .ui.selection.dropdown .menu > .item { border: unset; } - // 修复一些菜单下的菜单元素溢出问题 - // 目前主要为分支菜单 + /* 修复一些菜单下的菜单元素溢出问题 */ + /* 目前主要为分支菜单 */ .ui.dropdown .menu .menu { border-radius: 12px !important; } - // 修复按钮阴影被覆盖缺少边框线的问题 - // 仓库动态页面的右侧按钮, 比如时间周期 + /* 修复按钮阴影被覆盖缺少边框线的问题 */ + /* 仓库动态页面的右侧按钮, 比如时间周期 */ .ui.floating.dropdown .menu { box-shadow: ${themeVars.github.shadow.floating.small} !important; } diff --git a/styles/public/dropdown/emoji_dropdown.ts b/styles/public/dropdown/emoji_dropdown.ts index 9f5db0b..d8a1a6c 100644 --- a/styles/public/dropdown/emoji_dropdown.ts +++ b/styles/public/dropdown/emoji_dropdown.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; // 包含表情的下拉菜单 export const emojiDropdown = css` diff --git a/styles/public/dropdown/selection_dropdown.ts b/styles/public/dropdown/selection_dropdown.ts index 7112402..1b6b539 100644 --- a/styles/public/dropdown/selection_dropdown.ts +++ b/styles/public/dropdown/selection_dropdown.ts @@ -17,12 +17,13 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; -import { activeItemAfterStyle } from "styles/public/menu"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; +import { activeItemAfterStyle } from "styles/common"; // 选择框的下拉菜单看起来像普通按钮 export const selectionDropdown = css` - // 排除可以选择的输入搜索框和创建仓库的拥有者 + /* 排除可以选择的输入搜索框和创建仓库的拥有者 */ .ui.selection.dropdown:not(.search):not(.ellipsis-text-items), .ui.selection.dropdown.active:not(.search):not(.ellipsis-text-items) { background-color: ${themeVars.color.button}; @@ -38,23 +39,35 @@ export const selectionDropdown = css` background: ${themeVars.color.hover.self}; border-color: ${themeVars.color.light.border}; } - // 悬停提供伪元素 + /* 悬停提供伪元素 */ .item:hover:after { content: ""; ${activeItemAfterStyle}; } } - // 修复顶部导航栏工单管理/请求合并页面搜索框旁的选择下拉框按钮内容过窄 + /* 修复 Gitea 1.26 增加的阴影样式 */ + .ui.selection.dropdown, + .ui.selection.dropdown.active { + /* 修复 Gitea 1.26 多余的阴影 */ + &:hover { + box-shadow: none; + /* 修复 Gitea 1.26 覆盖的阴影 */ + .menu { + box-shadow: ${themeVars.github.shadow.floating.small}; + } + } + } + /* 修复顶部导航栏工单管理/请求合并页面搜索框旁的选择下拉框按钮内容过窄 */ .list-header-search .ui.action.input > .dropdown.small { padding: 8px 40px 8px 16px; } - // 发布版本页面的分支按钮, 覆盖 Gitea 的样式, 避免按钮元素高度不一致 + /* 发布版本页面的分支按钮, 覆盖 Gitea 的样式, 避免按钮元素高度不一致 */ .repository.new.release .target .selection.dropdown { padding-top: 8px; padding-bottom: 8px; } - // 这个按钮项目前只在创建仓库的拥有者 - // 不实现伪元素, 因为 .item 设置溢出的元素会被截断 + /* 这个按钮项目前只在创建仓库的拥有者 */ + /* 不实现伪元素, 因为 .item 设置溢出的元素会被截断 */ .ui.selection.dropdown.ellipsis-text-items, .ui.selection.dropdown.activeellipsis-text-items { &:focus { @@ -66,43 +79,43 @@ export const selectionDropdown = css` border-color: ${themeVars.color.light.border}; } } - // 选择输入框效果和输入框 focus 效果一样 + /* 选择输入框效果和输入框 focus 效果一样 */ .ui.selection.dropdown.active.search { background: ${themeVars.color.body}; - // 向内部添加一个 1px 的边框 + /* 向内部添加一个 1px 的边框 */ box-shadow: inset 0 0 0 1px ${themeVars.github.borderColor.accent.emphasis}; outline: none; } - // 覆盖选择输入框向上弹出时的 hover 效果, 原阴影会覆盖加厚的边框线 + /* 覆盖选择输入框向上弹出时的 hover 效果, 原阴影会覆盖加厚的边框线 */ .ui.selection.dropdown.active.search.upward:hover { box-shadow: inset 0 0 0 1px ${themeVars.github.borderColor.accent.emphasis}; } - // 由于之前的排除导致样式优先级变高, 小按钮去除圆角 + /* 由于之前的排除导致样式优先级变高, 小按钮去除圆角 */ .ui.action.input > .dropdown.small:not(:first-child) { border-radius: 0; } - // 排除一些小按钮, 例如软件包类型, 通常相邻有元素 + /* 排除一些小按钮, 例如软件包类型, 通常相邻有元素 */ .ui.selection.dropdown.active:not(.small) { border-bottom-left-radius: ${otherThemeVars.border.radius} !important; border-bottom-right-radius: ${otherThemeVars.border.radius} !important; } - // 修复因为上面的排除导致的圆角问题 - // 具体工单页面下依赖菜单选择框 + /* 修复因为上面的排除导致的圆角问题 */ + /* 具体工单页面下依赖菜单选择框 */ #new-dependency-drop-list.ui.selection.dropdown.active, - // 提交图分支选择框 + /* 提交图分支选择框 */ #git-graph-container #flow-select-refs-dropdown { border-bottom-right-radius: 0 !important; } - // 修复选择框的下拉菜单向上显示时的样式问题 + /* 修复选择框的下拉菜单向上显示时的样式问题 */ .ui.upward.selection.dropdown.visible:not(.small), .ui.active.upward.selection.dropdown:not(.small) { border-top-left-radius: ${otherThemeVars.border.radius} !important; border-top-right-radius: ${otherThemeVars.border.radius} !important; } - // 工单标签菜单中的标签换行和颜色 - // 标签页面的标签选择框 + /* 工单标签菜单中的标签换行和颜色 */ + /* 标签页面的标签选择框 */ .page-content.repository.labels .ui.selection.dropdown.active, - // 创建仓库页面的标签选择框 + /* 创建仓库页面的标签选择框 */ .page-content.repository.new-repo .ui.search.selection.dropdown { > .menu > .item { flex-direction: column; @@ -115,9 +128,9 @@ export const selectionDropdown = css` `; export const fixSelectionDropdown = css` - // 具体工单页面下依赖菜单选择框 + /* 具体工单页面下依赖菜单选择框 */ #new-dependency-drop-list.ui.selection.dropdown { - // 高度对齐问题, 应该与 input 框高度一致 + /* 高度对齐问题, 应该与 input 框高度一致 */ min-height: 32px; } `; diff --git a/styles/public/input.ts b/styles/public/input.ts index bce0a26..0f8aa28 100644 --- a/styles/public/input.ts +++ b/styles/public/input.ts @@ -17,14 +17,15 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; export const input = css` textarea, - // 排除复选框和单选框 + /* 排除复选框和单选框 */ input:not([type=checkbox],[type=radio]), .ui.input input:not([type=checkbox],[type=radio]), - // 排除可以选择的输入搜索框 + /* 排除可以选择的输入搜索框 */ .ui.form input:not([type]):not(.search), .ui.form select, .ui.form textarea, @@ -44,9 +45,9 @@ export const input = css` padding: 8px 12px; &:focus, &:focus-visible { - background: ${themeVars.color.body} !important; + background: ${themeVars.color.body}; border-color: ${themeVars.github.borderColor.accent.emphasis}; - // 向内部添加一个 1px 的边框 + /* 向内部添加一个 1px 的边框 */ box-shadow: inset 0 0 0 1px ${themeVars.github.borderColor.accent.emphasis}; outline: none; } @@ -54,19 +55,19 @@ export const input = css` .ui.input { height: 32px; } - // 由于输入框高度, 需要输入框在表单中垂直居中 - // 管理员页面仓库搜索表单 + /* 由于输入框高度, 需要输入框在表单中垂直居中 */ + /* 管理员页面仓库搜索表单 */ .ui.form#repo-search-form { align-items: center; } - // 下拉菜单的输入框 + /* 下拉菜单的输入框 */ .ui.dropdown.dropdown .menu > .input { margin: 12px 10px; } `; // 复选框和单选框 export const checkBoxAndRadio = css` - // 复选框 + /* 复选框 */ input[type="checkbox"], .ui.checkbox input[type="checkbox"] { background-color: ${themeVars.color.body}; @@ -80,7 +81,7 @@ export const checkBoxAndRadio = css` background-color: ${themeVars.github.fgColor.onEmphasis}; } } - // 单选框 + /* 单选框 */ input[type="radio"], .ui.checkbox input[type="radio"] { background-color: ${themeVars.color.body}; diff --git a/styles/public/label/label.ts b/styles/public/label/label.ts index 9b9460b..29f00d5 100644 --- a/styles/public/label/label.ts +++ b/styles/public/label/label.ts @@ -17,11 +17,9 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; - -export const labelStyle = { - padding: "0px 6px", -}; +import { css } from "@linaria/core"; +import { themeVars } from "src"; +import { labelStyle } from "styles/common"; export const label = css` .ui.label { @@ -31,7 +29,7 @@ export const label = css` /* a 标签比如仓库点星等按钮旁边的数字标签按钮,提交图中的 tag 标签 */ div.label, span.label, - // 包含多个标签的元素, 比如 Issue/PR 详情页中的时间线上的标签 + /* 包含多个标签的元素, 比如 Issue/PR 详情页中的时间线上的标签 */ span.labels-list a.label { &.ui.ui.ui { border-radius: 9999px; @@ -40,7 +38,7 @@ export const label = css` &.mini { line-height: 16px; } - // 多个标签的组合标签的圆角修复 + /* 多个标签的组合标签的圆角修复 */ &.scope-parent { .scope-left { border-top-right-radius: 0; diff --git a/styles/public/label/repo_label.ts b/styles/public/label/repo_label.ts index c0d658b..731dab6 100644 --- a/styles/public/label/repo_label.ts +++ b/styles/public/label/repo_label.ts @@ -17,12 +17,13 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; // 仓库标签 (私有/公开/内部) export const repoLabel = css` span, - // 用户切换面板的标签 + /* 用户切换面板的标签 */ .org-visibility div { &.ui.basic.label { background-color: unset; diff --git a/styles/public/label/sha_label.ts b/styles/public/label/sha_label.ts index 9b236c8..badba0c 100644 --- a/styles/public/label/sha_label.ts +++ b/styles/public/label/sha_label.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; // 提交中的 SHA 标签 export const shaLabel = css` @@ -28,12 +29,12 @@ export const shaLabel = css` color: ${themeVars.color.text.light.num1}; font-size: 12px; font-weight: 500; - // 仪表盘页的提交 SHA 标签居中对齐 + /* 仪表盘页的提交 SHA 标签居中对齐 */ margin-top: 2px; &:hover { background-color: ${themeVars.color.label.hoverBg}; } - // 验证提交 SHA 标签 + /* 验证提交 SHA 标签 */ &.commit-is-signed { border: unset !important; background-color: unset !important; @@ -49,16 +50,16 @@ export const shaLabel = css` } } } - // 修复带验证的提交 SHA 标签的高度 + /* 修复带验证的提交 SHA 标签的高度 */ .ui.label.commit-id-short { height: 25px; } - // 验证提交附带的图标 + /* 验证提交附带的图标 */ span.ui.label.commit-is-signed { height: 25px; min-width: 35px; justify-content: center; - // 验证信任 + /* 验证信任 */ &.sign-trusted { border: 1.5px solid ${themeVars.color.green.badge.self} !important; color: ${themeVars.color.green.badge.self} !important; @@ -66,7 +67,7 @@ export const shaLabel = css` background-color: ${themeVars.color.green.badge.hover.bg} !important; } } - // 验证未信任 + /* 验证未信任 */ &.sign-untrusted { border: 1.5px solid ${themeVars.color.yellow.badge.self} !important; color: ${themeVars.color.yellow.badge.self} !important; @@ -74,7 +75,7 @@ export const shaLabel = css` background-color: ${themeVars.color.yellow.badge.hover.bg} !important; } } - // 验证未匹配 + /* 验证未匹配 */ &.sign-unmatched { border: 1.5px solid ${themeVars.color.orange.badge.self} !important; color: ${themeVars.color.orange.badge.self} !important; @@ -82,7 +83,7 @@ export const shaLabel = css` background-color: ${themeVars.color.orange.badge.hover.bg} !important; } } - // 验证警告 + /* 验证警告 */ &.sign-warning { border: 1.5px solid ${themeVars.color.red.badge.self} !important; color: ${themeVars.color.red.badge.self} !important; diff --git a/styles/public/label/task_status_label.ts b/styles/public/label/task_status_label.ts index 3d168fe..47d7e40 100644 --- a/styles/public/label/task_status_label.ts +++ b/styles/public/label/task_status_label.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; // 任务状态标签, 目前仅在管理员页面 Runner 状态中看到 export const taskStatusLabel = css` diff --git a/styles/public/menu/compact_menu.ts b/styles/public/menu/compact_menu.ts index 924ca63..59fb0fb 100644 --- a/styles/public/menu/compact_menu.ts +++ b/styles/public/menu/compact_menu.ts @@ -17,32 +17,35 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; // 单行双选项菜单 export const smallCompactMenu = css` - // 订阅/关注切换菜单(应只选中订阅/关注页面, 不能选中通知页面) + /* 编辑/预览切换菜单(仓库编辑文件时的编辑器操作栏左侧) */ + .page-content.repository.file.editor .repo-view-content .ui.edit.form .ui.top.attached.header, + /* 订阅/关注切换菜单(应只选中订阅/关注页面, 不能选中通知页面) */ .page-content.user.notification > .ui.container:has(.flex-list), - // 里程碑/标签切换菜单(里程碑页) + /* 里程碑/标签切换菜单(里程碑页) */ .page-content.repository.milestones .list-header, - // 里程碑/标签切换菜单(新建里程碑页) + /* 里程碑/标签切换菜单(新建里程碑页) */ .page-content.repository.new.milestone .issue-navbar, - // 里程碑/标签切换菜单(标签页) + /* 里程碑/标签切换菜单(标签页) */ .page-content.repository.labels .issue-navbar { .ui.compact.small.menu.small-menu-items { - background: ${themeVars.color.hover.self} !important; - border: 0; + background: ${themeVars.github.controlTrack.bgColor.rest} !important; + border: 1px solid ${themeVars.color.light.border}; font-size: 14px; gap: 8px; height: 32px; min-height: 32px !important; > .item { background: unset !important; - border: 1px solid ${themeVars.color.hover.self}; + border: 1px solid ${themeVars.github.controlTrack.bgColor.rest}; border-radius: ${otherThemeVars.border.radius}; padding: 6px 12px !important; &.active { - background: ${themeVars.color.menu} !important; + background: ${themeVars.github.controlKnob.bgColor.rest} !important; border-color: ${themeVars.color.light.border}; font-weight: 600; } @@ -54,8 +57,8 @@ export const smallCompactMenu = css` padding: 4px 12px !important; height: calc(100% - 8px); position: relative; - // 该方案只适用于 2 个 item 的情况 - // left / right 数值为 gap 数值的一半 + /* 该方案只适用于 2 个 item 的情况 */ + /* left / right 数值为 gap 数值的一半 */ &:first-child { left: 4px; } diff --git a/styles/public/menu/index.ts b/styles/public/menu/index.ts index e53baec..cf967c2 100644 --- a/styles/public/menu/index.ts +++ b/styles/public/menu/index.ts @@ -22,16 +22,3 @@ import "./menu"; import "./pagination_menu"; import "./secondary_menu"; import "./vertical_menu"; - -import { type StyleRule } from "@vanilla-extract/css"; -import { otherThemeVars, themeVars } from "src/types/vars"; - -export const activeItemAfterStyle = { - backgroundColor: themeVars.github.borderColor.accent.emphasis, - borderRadius: otherThemeVars.border.radius, - height: "24px", - left: "-8px", - position: "absolute", - top: "calc(50% - 12px)", - width: "4px", -} satisfies StyleRule; diff --git a/styles/public/menu/menu.ts b/styles/public/menu/menu.ts index 827869f..88c79fa 100644 --- a/styles/public/menu/menu.ts +++ b/styles/public/menu/menu.ts @@ -17,8 +17,9 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; -import { labelStyle } from "styles/public/label/label"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; +import { labelStyle } from "styles/common"; export const menu = css` .ui.menu { @@ -27,7 +28,7 @@ export const menu = css` .menu .item svg { color: ${themeVars.color.text.light.num1}; } - // 菜单默认悬浮色更改 + /* 菜单默认悬浮色更改 */ .ui.menu a.item, .ui.secondary.pointing.menu a.item, .ui.secondary.menu .dropdown.item { @@ -35,14 +36,14 @@ export const menu = css` background: ${themeVars.github.control.transparent.bgColor.hover}; } } - // 一些水平小型菜单的颜色更改 + /* 一些水平小型菜单的颜色更改 */ .small-menu-items .item { background-color: ${themeVars.color.body} !important; &:hover { background: ${themeVars.github.control.transparent.bgColor.hover} !important; } } - // 一些菜单的悬浮色更改 + /* 一些菜单的悬浮色更改 */ .ui.segment .ui.tabular.menu, .header-wrapper .ui.tabular.menu, .ui.secondary.pointing.menu { @@ -53,7 +54,7 @@ export const menu = css` } } } - // 菜单标签样式 + /* 菜单标签样式 */ .ui.menu .item > .label:not(.floating) { ${labelStyle} } diff --git a/styles/public/menu/pagination_menu.ts b/styles/public/menu/pagination_menu.ts index b543a1d..959caba 100644 --- a/styles/public/menu/pagination_menu.ts +++ b/styles/public/menu/pagination_menu.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; // 分页菜单 export const paginationMenu = css` @@ -33,13 +34,13 @@ export const paginationMenu = css` min-height: 32px; height: 32px; justify-content: center; - // 避免一些 hover 效果调整内容 + /* 避免一些 hover 效果调整内容 */ padding: 5px 10px !important; &.active { background: ${themeVars.github.bgColor.accent.emphasis}; color: ${themeVars.color.white}; } - // 设置透明边框线避免 hover 时元素大小变化 + /* 设置透明边框线避免 hover 时元素大小变化 */ &:not(.active) { border: 1px solid #ffffff00; &:hover { @@ -54,7 +55,7 @@ export const paginationMenu = css` color: ${themeVars.color.primary.self}; } } - // 对齐文字 + /* 对齐文字 */ svg { margin-top: 2px; } diff --git a/styles/public/menu/secondary_menu.ts b/styles/public/menu/secondary_menu.ts index c3f2e1e..f295ce7 100644 --- a/styles/public/menu/secondary_menu.ts +++ b/styles/public/menu/secondary_menu.ts @@ -17,21 +17,26 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; export const secondaryMenu = css` - // 二级菜单, 比如 Issue/PR/Actions 的筛选菜单 + /* 二级菜单, 比如 Issue/PR/Actions 的筛选菜单 */ .ui.secondary.menu { .item { padding: 0px 12px; height: 32px; font-weight: 500; + &.active, + &:first-child { + border-radius: ${otherThemeVars.border.radius}; + } } a.item:hover { background: ${themeVars.github.control.transparent.bgColor.hover}; } } - // 二级导航栏, 比如仓库的导航栏, 仓库列表的导航栏, 探索的类型导航栏 + /* 二级导航栏, 比如仓库的导航栏, 仓库列表的导航栏, 探索的类型导航栏 */ .ui.secondary.pointing.menu { .overflow-menu-items { gap: 4px; @@ -43,7 +48,7 @@ export const secondaryMenu = css` } } .item { - font-weight: 400; // 二级导航栏不需要加粗 + font-weight: 400; /* 二级导航栏不需要加粗 */ } .active.item, .dropdown.item, @@ -56,9 +61,9 @@ export const secondaryMenu = css` } } .active.item { - // 取消激活时的下划线, 需要为透明, 保持间距 + /* 取消激活时的下划线, 需要为透明, 保持间距 */ border-color: #ffffff00; - // 模仿 github 的下划线 + /* 模仿 github 的下划线 */ span:after { content: ""; background: ${themeVars.github.underlineNav.borderColor.active}; @@ -73,7 +78,7 @@ export const secondaryMenu = css` } } } - // 修复仓库页面下的二级导航栏的下划线因浏览器 BUG 导致显示的异常问题(导致下划线和分割线重叠变粗) + /* 修复仓库页面下的二级导航栏的下划线因浏览器 BUG 导致显示的异常问题(导致下划线和分割线重叠变粗) */ .page-content.repository .ui.secondary.pointing.menu { border-bottom: none !important; } diff --git a/styles/public/menu/vertical_menu.ts b/styles/public/menu/vertical_menu.ts index 4a52f79..6fa9c6c 100644 --- a/styles/public/menu/vertical_menu.ts +++ b/styles/public/menu/vertical_menu.ts @@ -17,17 +17,18 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; -import { activeItemAfterStyle } from "."; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; +import { activeItemAfterStyle } from "styles/common"; export const verticalMenu = css` - // 垂直菜单, 用于左侧边栏 - // 设置页面中的菜单, Actions 工作流菜单, WorkflowRuns Job 菜单 + /* 垂直菜单, 用于左侧边栏 */ + /* 设置页面中的菜单, Actions 工作流菜单, WorkflowRuns Job 菜单 */ .ui.vertical.menu { - // 去除边框, 和背景色同色 + /* 去除边框, 和背景色同色 */ background: ${themeVars.color.body}; border: 0; - // 设置页面的菜单头部 + /* 设置页面的菜单头部 */ .header.item { color: ${themeVars.color.text.light.num1} !important; font-size: 1.5rem; @@ -35,11 +36,11 @@ export const verticalMenu = css` background: unset; margin-bottom: 0.5rem; } - // 菜单项被悬停时的背景色, 限制a标签, 避免为子菜单多余渲染 + /* 菜单项被悬停时的背景色, 限制a标签, 避免为子菜单多余渲染 */ a.item:hover { background: ${themeVars.github.control.transparent.bgColor.hover}; } - // 菜单项 + /* 菜单项 */ .item, .item > summary { font-size: 1.1rem; @@ -47,7 +48,7 @@ export const verticalMenu = css` border-radius: ${otherThemeVars.border.radius}; padding: 6px 8px; } - // Actions 菜单的圆角覆盖 + /* Actions 菜单的圆角覆盖 */ > .item, > .active.item { &:first-child, @@ -55,37 +56,37 @@ export const verticalMenu = css` border-radius: ${otherThemeVars.border.radius}; } } - // 去除菜单项的边框线 + /* 去除菜单项的边框线 */ .item:before { background: unset; } - // 激活的菜单项 + /* 激活的菜单项 */ .active.item, .active.item > summary { font-weight: 600; border-radius: ${otherThemeVars.border.radius}; } - // 添加伪元素, 用于指示当前激活的菜单项 + /* 添加伪元素, 用于指示当前激活的菜单项 */ .active.item:after { content: ""; ${activeItemAfterStyle}; } - // 部分菜单项的子菜单 + /* 部分菜单项的子菜单 */ details.item { - // 子菜单的标题 + /* 子菜单的标题 */ summary:hover { background: ${themeVars.github.control.transparent.bgColor.hover}; } - // 子菜单的选项 + /* 子菜单的选项 */ .menu .item { color: ${themeVars.color.text.self}; } - // 子菜单的选项被激活 + /* 子菜单的选项被激活 */ &:has(.active.item) { > summary { font-weight: 600; background: ${themeVars.color.active}; - // 收回状态,悬停色 + /* 收回状态,悬停色 */ &:hover { background: ${themeVars.github.control.transparent.bgColor.hover}; } @@ -94,7 +95,7 @@ export const verticalMenu = css` content: ""; ${activeItemAfterStyle}; } - // 子菜单的选项 + /* 子菜单的选项 */ .active.item { background: ${themeVars.color.active}; font-weight: 400; @@ -102,7 +103,7 @@ export const verticalMenu = css` background: ${themeVars.github.control.transparent.bgColor.hover}; } } - // 子菜单展开时 + /* 子菜单展开时 */ &[open] { > summary { background: unset; diff --git a/styles/public/modal.ts b/styles/public/modal.ts index bec926b..fb411c1 100644 --- a/styles/public/modal.ts +++ b/styles/public/modal.ts @@ -17,8 +17,9 @@ * limitations under the License. */ -import { animationDown } from "src/core/styles"; -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; +import { animationDown } from "styles/common"; export const modal = css` .ui.modal { diff --git a/styles/public/other.ts b/styles/public/other.ts index a0b433b..94d94e6 100644 --- a/styles/public/other.ts +++ b/styles/public/other.ts @@ -17,11 +17,12 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; export const text = css` - // 默认颜色是 --color-text-light, 主题下此颜色是亮白色, 修改为灰色 - // release 页面下一些描述信息的文本颜色 + /* 默认颜色是 --color-text-light, 主题下此颜色是亮白色, 修改为灰色 */ + /* release 页面下一些描述信息的文本颜色 */ .tw-text-text-light { color: ${themeVars.color.text.light.num1} !important; } @@ -35,26 +36,26 @@ export const listHeader = css` `; export const svg = css` - // 已标星的图标 + /* 已标星的图标 */ .octicon-star-fill { color: ${themeVars.github.button.star.iconColor} !important; } - // VSCode 图标 + /* VSCode 图标 */ .gitea-vscode { color: #007acc !important; } - // VSCodium 图标 + /* VSCodium 图标 */ .gitea-vscodium { color: #429cf0 !important; } - // 重新打开工单按钮设置为绿色 + /* 重新打开工单按钮设置为绿色 */ .tw-text-green { .octicon-issue-reopened, &.octicon-issue-reopened { color: ${themeVars.github.fgColor.success} !important; } } - // 关闭工单按钮设置为紫色 + /* 关闭工单按钮设置为紫色 */ .tw-text-red { .octicon-issue-closed, &.octicon-issue-closed { @@ -91,11 +92,11 @@ export const toggle = css` bottom: 1.5px; } } - // 滑块在左 + /* 滑块在左 */ input ~ label:after { left: 1.5px; } - // 滑块在右 + /* 滑块在右 */ input:checked ~ label:after { left: 19.5px; } diff --git a/styles/public/radius.ts b/styles/public/radius.ts index 889cdd0..203dc4d 100644 --- a/styles/public/radius.ts +++ b/styles/public/radius.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, otherThemeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars } from "src"; // 全部圆角替换 export const radius = css` @@ -45,7 +46,7 @@ export const radius = css` .ui.input { textarea, - // 排除复选框和单选框 + /* 排除复选框和单选框 */ input:not([type=checkbox],[type=radio]) { border-radius: ${otherThemeVars.border.radius}; } @@ -97,7 +98,7 @@ export const radiusImportant = css` .ui.secondary.vertical.menu > .item { border-radius: ${otherThemeVars.border.radius} !important; } - // 目前为仓库列表/探索的二级菜单, 改版需要替换为全圆角 + /* 目前为仓库列表/探索的二级菜单, 改版需要替换为全圆角 */ .ui.secondary.tabular.menu .item { border-radius: ${otherThemeVars.border.radius} !important; &.active, @@ -272,8 +273,7 @@ export const radiusBottomRight = css` // only-child 顺序最后生效 export const onlyChild = css` - .ui.vertical.menu > .active.item:only-child, - .ui.segments:not(.horizontal) > .segment:only-child { + :is(.ui.vertical.menu > .active.item:only-child, .ui.segments:not(.horizontal) > .segment:only-child) { border-radius: ${otherThemeVars.border.radius}; } @@ -293,12 +293,12 @@ export const onlyChild = css` // 修复一些情况下圆角边框线被覆盖的问题 export const fixRadius = css` - // 评论列表标题 + /* 评论列表标题 */ .repository.view.issue .comment-list .comment > .content > div:first-child { border-top-left-radius: ${otherThemeVars.border.radius}; border-top-right-radius: ${otherThemeVars.border.radius}; } - // 评论列表内容 + /* 评论列表内容 */ .repository.view.issue .comment-list .comment > .content > div:last-child { border-bottom-left-radius: ${otherThemeVars.border.radius}; border-bottom-right-radius: ${otherThemeVars.border.radius}; @@ -307,7 +307,7 @@ export const fixRadius = css` // 修复一些根本无法理解的生效顺序 export const fixWhyRadius = css` - // Issue 菜单第一个按钮 + /* Issue 菜单第一个按钮 */ .ui.secondary.menu .item { border-radius: ${otherThemeVars.border.radius}; } diff --git a/styles/public/table.ts b/styles/public/table.ts index d01c257..d40a419 100644 --- a/styles/public/table.ts +++ b/styles/public/table.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { themeVars } from "src"; export const table = css` .ui.table > tr > td, diff --git a/styles/public/tippy.ts b/styles/public/tippy.ts index 81e8524..0350a00 100644 --- a/styles/public/tippy.ts +++ b/styles/public/tippy.ts @@ -17,8 +17,9 @@ * limitations under the License. */ -import { animation, animationDown } from "src/core/styles"; -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; +import { animation, animationDown } from "styles/common"; // 一些界面内的提示框, 比如克隆按钮, PR信息, Runner信息 等 export const tippyBox = css` @@ -27,9 +28,9 @@ export const tippyBox = css` border-radius: ${otherThemeVars.border.radius}; overflow: hidden; ${animationDown}; - // 克隆菜单和PR提示框为 default + /* 克隆菜单和PR提示框为 default */ &[data-theme="default"], - // 带标题的提示框 (Runner信息) + /* 带标题的提示框 (Runner信息) */ &[data-theme="box-with-header"] { border: unset; box-shadow: ${themeVars.github.shadow.floating.small}; @@ -46,7 +47,7 @@ export const tippyBox = css` } } } - // 差异对比中文件路径行右侧的三个点菜单 + /* 差异对比中文件路径行右侧的三个点菜单 */ &[data-theme="menu"] { .tippy-content { padding: 8px; @@ -60,7 +61,7 @@ export const tippyBox = css` } } } - // 专门用于提示信息的提示框, 比如提交的具体时间, 任务状态等 + /* 专门用于提示信息的提示框, 比如提交的具体时间, 任务状态等 */ &[data-theme="tooltip"] { ${animation}; .tippy-content { diff --git a/styles/public/transition.ts b/styles/public/transition.ts index eecbf0a..0ea97ff 100644 --- a/styles/public/transition.ts +++ b/styles/public/transition.ts @@ -17,23 +17,23 @@ * limitations under the License. */ -import { css } from "src/types/vars"; +import { css } from "@linaria/core"; // 简单的渐变过渡 export const transition = css` - // 差异对比的代码折叠按钮 + /* 差异对比的代码折叠按钮 */ .code-expander-button, - // 仓库 README 头部的按钮 + /* 仓库 README 头部的按钮 */ .file-header-left, .file-header-right, - // 仪表板仓库列表 + /* 仪表板仓库列表 */ .ui.attached.segment.table ul li, - // Issue 列表 + /* Issue 列表 */ .issue-list-toolbar .item, .flex-list#issue-list > .flex-item, - // 分页菜单 + /* 分页菜单 */ .ui.borderless.pagination.menu .item, - // 迁移的元素 + /* 迁移的元素 */ #navbar .item, .header-wrapper .ui.tabular.menu .item, .job-step-summary, @@ -57,8 +57,8 @@ export const transition = css` .ui.secondary.menu .item { transition: 80ms cubic-bezier(0.33, 1, 0.68, 1); } - // Gitea 表单元素原始过渡覆盖 - // 排除复选框和单选框 + /* Gitea 表单元素原始过渡覆盖 */ + /* 排除复选框和单选框 */ input:not([type="checkbox"], [type="radio"]), textarea, tr, @@ -78,4 +78,12 @@ export const transition = css` .ui.form input[type="url"] { transition: 80ms cubic-bezier(0.33, 1, 0.68, 1); } + .ui.button { + transition: + color 80ms cubic-bezier(0.65, 0, 0.35, 1), + fill 80ms cubic-bezier(0.65, 0, 0.35, 1), + background-color 80ms cubic-bezier(0.65, 0, 0.35, 1), + border-color 80ms cubic-bezier(0.65, 0, 0.35, 1); + transition-duration: 80ms; + } `; diff --git a/styles/templates/repo/commit_sign_badge.ts b/styles/templates/repo/commit_sign_badge.ts index 4492ee9..2513479 100644 --- a/styles/templates/repo/commit_sign_badge.ts +++ b/styles/templates/repo/commit_sign_badge.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; export const commitSignBadge = css` a.ui.label.commit-id-short.github-theme-commit-sha { @@ -42,7 +43,7 @@ export const commitSignBadge = css` font-weight: 500; padding: 0px 8px; height: 26px; - min-width: 85px; // 非等宽字体导致不对齐, 目前看到最大长度为 83px + min-width: 85px; /* 非等宽字体导致不对齐, 目前看到最大长度为 83px */ display: flex; align-items: center; justify-content: center; diff --git a/styles/templates/repo/commits_list.ts b/styles/templates/repo/commits_list.ts index 6c7943c..a527783 100644 --- a/styles/templates/repo/commits_list.ts +++ b/styles/templates/repo/commits_list.ts @@ -17,7 +17,8 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; const primary = "primary" as const; const secondary = "secondary" as const; diff --git a/styles/templates/repo/view_content.ts b/styles/templates/repo/view_content.ts index f2d6b65..876555e 100644 --- a/styles/templates/repo/view_content.ts +++ b/styles/templates/repo/view_content.ts @@ -17,11 +17,12 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; export const repoButtonRow = css` .github-theme-templates { - // 仓库按钮行 + /* 仓库按钮行 */ &.repo-button-row { margin: 0 0 16px 0; .repo-button-row-left .repository-summary { @@ -47,7 +48,7 @@ export const repoButtonRow = css` } } .repo-button-row-right { - // 添加文件按钮菜单 + /* 添加文件按钮菜单 */ .repo-add-file > .menu { min-width: 152px; } diff --git a/styles/templates/repo/view_list.ts b/styles/templates/repo/view_list.ts index 32dd5d7..6946e34 100644 --- a/styles/templates/repo/view_list.ts +++ b/styles/templates/repo/view_list.ts @@ -17,18 +17,19 @@ * limitations under the License. */ -import { css, otherThemeVars, themeVars } from "src/types/vars"; +import { css } from "@linaria/core"; +import { otherThemeVars, themeVars } from "src"; export const repoFileLastCommit = css` - // 仓库页和文件列表文件夹页的最后一次提交 + /* 仓库页和文件列表文件夹页的最后一次提交 */ .repository.file.list #repo-files-table .github-theme-templates.repo-file-line.repo-file-last-commit { padding-right: 10px; - // 提交时间 + /* 提交时间 */ .github-latest-time { color: ${themeVars.color.text.light.num1}; font-size: 12px; } - // 提交历史按钮 + /* 提交历史按钮 */ .github-latest-commit { display: inline-flex; align-items: center; diff --git a/theme.config.ts b/theme.config.ts new file mode 100644 index 0000000..c4a7f53 --- /dev/null +++ b/theme.config.ts @@ -0,0 +1,74 @@ +/*! + * Copyright (c) https://github.com/lutinglt + * + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineThemeConfig } from "src"; +import * as githubDark from "./themes/githubDark"; +import * as githubLight from "./themes/githubLight"; +import * as githubPink from "./themes/githubPink"; + +export default defineThemeConfig([ + { + themeSeriesName: "base", + themes: { + dark: { theme: githubDark.githubDark }, + light: { theme: githubLight.githubLight }, + "soft-dark": { theme: githubDark.githubSoftDark }, + }, + }, + { + themeSeriesName: "colorblind", + autoTheme: { displayName: "Auto Protanopia And Deuteranopia", colorblindType: "red-green" }, + themes: { + dark: { + displayName: "Dark Protanopia And Deuteranopia", + colorblindType: "red-green", + theme: githubDark.githubColorblindDark, + }, + light: { + displayName: "Light Protanopia And Deuteranopia", + colorblindType: "red-green", + theme: githubLight.githubColorblindLight, + }, + }, + }, + { + themeSeriesName: "tritanopia", + autoTheme: { displayName: "Auto Tritanopia", colorblindType: "blue-yellow" }, + themes: { + dark: { + displayName: "Dark Tritanopia", + colorblindType: "blue-yellow", + theme: githubDark.githubTritanopiaDark, + }, + light: { + displayName: "Light Tritanopia", + colorblindType: "blue-yellow", + theme: githubLight.githubTritanopiaLight, + }, + }, + }, + { + themeSeriesName: "pink", + themes: { + dark: { theme: githubPink.githubPinkDark }, + light: { theme: githubPink.githubPinkLight }, + "soft-dark": { theme: githubPink.githubPinkSoftDark }, + }, + }, +]); diff --git a/themes/colorblind-dark.css.ts b/themes/colorblind-dark.css.ts deleted file mode 100644 index 5ce3322..0000000 --- a/themes/colorblind-dark.css.ts +++ /dev/null @@ -1,105 +0,0 @@ -/*! - * Copyright (c) https://github.com/lutinglt - * - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @author lutinglt - */ - -import { defineTheme, themeVars, type Chroma } from "src"; -import { github2ThemeColor, type GithubColor } from "src/core/github"; -import { prettylights2Chroma, type prettylightsColor } from "src/core/prettylights"; -import { darkGithubColors } from "themes/dark"; - -export const colorblindDarkGithubColors: GithubColor = { - isDarkTheme: true, - avatar: darkGithubColors.avatar, - display: darkGithubColors.display, - diffBlob: { - addtionNum: { bgColor: "#58a6ff4d" }, - addtionWord: { bgColor: "#388bfd66" }, - deletionNum: { bgColor: "#db6d284d" }, - deletionWord: { bgColor: "#db6d2866" }, - hunkNum: { bgColor: { rest: "#2f3742" } }, - }, - fgColor: { - ...darkGithubColors.fgColor, - danger: "#f0883e", - success: "#58a6ff", - }, - bgColor: { - ...darkGithubColors.bgColor, - danger: { emphasis: "#bd561d", muted: "#db6d281a" }, - success: { emphasis: "#1f6feb", muted: "#388bfd33" }, - }, - borderColor: { - ...darkGithubColors.borderColor, - success: { emphasis: "#1f6feb" }, - }, - button: { - primary: { - fgColor: { accent: "#58a6ff", rest: "#ffffff" }, - bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#2a7aef", active: "#3685f3" }, - }, - danger: { - fgColor: { rest: "#f0883e", hover: "#ffffff" }, - bgColor: { hover: "#9b4215", active: themeVars.github.bgColor.danger.emphasis }, - }, - star: darkGithubColors.button.star, - }, - control: darkGithubColors.control, - shadow: darkGithubColors.shadow, - overlay: darkGithubColors.overlay, - underlineNav: darkGithubColors.underlineNav, - contribution: darkGithubColors.contribution, -}; - -export const colorblindDarkPrettylights: prettylightsColor = { - syntax: { - brackethighlighter: { angle: "#9198a1", unmatched: "#db6d28" }, - carriage: { return: { bg: "#9b4215", text: "#f0f6fc" } }, - comment: "#9198a1", - constant: "#79c0ff", - constantOtherReferenceLink: "#a5d6ff", - entity: "#d2a8ff", - entityTag: "#a5d6ff", - invalid: { illegal: { bg: "#762d0a", text: "#f0f6fc" } }, - keyword: "#f0883e", - markup: { - bold: "#f0f6fc", - changed: { bg: "#5a1e02", text: "#ffdfb6" }, - deleted: { bg: "#5a1e02", text: "#ffdfb6" }, - heading: "#1f6feb", - ignored: { bg: "#1158c7", text: "#f0f6fc" }, - inserted: { bg: "#0c2d6b", text: "#cae8ff" }, - italic: "#f0f6fc", - list: "#f2cc60", - }, - metaDiffRange: "#d2a8ff", - storageModifierImport: "#f0f6fc", - string: "#a5d6ff", - stringRegexp: "#a5d6ff", - sublimelinterGutterMark: "#3d444d", - variable: "#ffa657", - }, -}; - -export const colorblindDarkColors = github2ThemeColor(colorblindDarkGithubColors); -export const colorblindDarkChroma: Chroma = prettylights2Chroma(colorblindDarkPrettylights); - -export default defineTheme(colorblindDarkColors, colorblindDarkChroma); diff --git a/themes/colorblind-light.css.ts b/themes/colorblind-light.css.ts deleted file mode 100644 index a2df1a6..0000000 --- a/themes/colorblind-light.css.ts +++ /dev/null @@ -1,102 +0,0 @@ -/*! - * Copyright (c) https://github.com/lutinglt - * - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @author lutinglt - */ - -import { defineTheme, themeVars, type Chroma } from "src"; -import { github2ThemeColor, type GithubColor } from "src/core/github"; -import { prettylights2Chroma, type prettylightsColor } from "src/core/prettylights"; -import { lightGithubColors } from "themes/light"; - -export const colorblindLightGithubColors: GithubColor = { - isDarkTheme: false, - avatar: lightGithubColors.avatar, - display: lightGithubColors.display, - diffBlob: { - addtionNum: { bgColor: "#b6e3ff" }, - addtionWord: { bgColor: "#b6e3ff" }, - deletionNum: { bgColor: "#ffd8b5" }, - deletionWord: { bgColor: "#ffd8b5" }, - hunkNum: { bgColor: { rest: "#e6eaef" } }, - }, - fgColor: { - ...lightGithubColors.fgColor, - danger: "#bc4c00", - success: "#0969da", - }, - bgColor: { - ...lightGithubColors.bgColor, - danger: { emphasis: "#bc4c00", muted: "#fff1e5" }, - success: { emphasis: "#0969da", muted: "#ddf4ff" }, - }, - borderColor: { - ...lightGithubColors.borderColor, - success: { emphasis: "#0969da" }, - }, - button: { - primary: { - fgColor: { accent: "#0969da", rest: "#ffffff" }, - bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#0864d1", active: "#075fc8" }, - }, - danger: { fgColor: { rest: "#bc4c00", hover: "#ffffff" }, bgColor: { hover: "#bc4c00", active: "#953800" } }, - star: lightGithubColors.button.star, - }, - control: lightGithubColors.control, - shadow: lightGithubColors.shadow, - overlay: lightGithubColors.overlay, - underlineNav: lightGithubColors.underlineNav, - contribution: lightGithubColors.contribution, -}; - -export const colorblindLightPrettylights: prettylightsColor = { - syntax: { - brackethighlighter: { angle: "#59636e", unmatched: "#762c00" }, - carriage: { return: { bg: "#bc4c00", text: "#f6f8fa" } }, - comment: "#59636e", - constant: "#0550ae", - constantOtherReferenceLink: "#0a3069", - entity: "#6639ba", - entityTag: "#0550ae", - invalid: { illegal: { bg: "#762c00", text: "#f6f8fa" } }, - keyword: "#bc4c00", - markup: { - bold: "#1f2328", - changed: { bg: "#ffd8b5", text: "#953800" }, - deleted: { bg: "#fff1e5", text: "#762c00" }, - heading: "#0550ae", - ignored: { bg: "#0550ae", text: "#d1d9e0" }, - inserted: { bg: "#ddf4ff", text: "#0550ae" }, - italic: "#1f2328", - list: "#3b2300", - }, - metaDiffRange: "#8250df", - storageModifierImport: "#1f2328", - string: "#0a3069", - stringRegexp: "#0550ae", - sublimelinterGutterMark: "#818b98", - variable: "#953800", - }, -}; - -export const colorblindLightColors = github2ThemeColor(colorblindLightGithubColors); -export const colorblindLightChroma: Chroma = prettylights2Chroma(colorblindLightPrettylights); - -export default defineTheme(colorblindLightColors, colorblindLightChroma); diff --git a/themes/dark.css.ts b/themes/dark.css.ts deleted file mode 100644 index 63b8bbe..0000000 --- a/themes/dark.css.ts +++ /dev/null @@ -1,119 +0,0 @@ -/*! - * Copyright (c) https://github.com/lutinglt - * - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @author lutinglt - */ - -import { defineTheme, themeVars } from "src"; -import { github2ThemeColor, type GithubColor } from "src/core/github"; - -export const darkGithubColors: GithubColor = { - isDarkTheme: true, - avatar: { - bgColor: "#ffffff1a", - borderColor: "#ffffff26", - }, - display: { - blue: { fgColor: "#4493f8" }, - brown: { fgColor: "#b69a6d" }, - cyan: { fgColor: "#07ace4" }, - indigo: { fgColor: "#9899ec" }, - lemon: { fgColor: "#ba9b12" }, - olive: { fgColor: "#a2a626" }, - teal: { fgColor: "#1cb0ab" }, - }, - diffBlob: { - addtionNum: { bgColor: "#3fb9504d" }, - addtionWord: { bgColor: "#2ea04366" }, - deletionNum: { bgColor: "#f851494d" }, - deletionWord: { bgColor: "#f8514966" }, - hunkNum: { bgColor: { rest: "#0c2d6b" } }, - }, - fgColor: { - accent: "#4493f8", - attention: "#d29922", - danger: "#f85149", - default: "#f0f6fc", - disabled: "#656c76", - done: "#ab7df8", - muted: "#9198a1", - neutral: "#9198a1", - severe: "#db6d28", - sponsors: "#db61a2", - success: "#3fb950", - black: "#010409", - white: "#ffffff", - onEmphasis: "#f0f6fc", - }, - bgColor: { - accent: { emphasis: "#1f6feb", muted: "#388bfd1a" }, - attention: { emphasis: "#9e6a03", muted: "#bb800926" }, - danger: { emphasis: "#da3633", muted: "#f851491a" }, - default: "#0d1117", - done: { emphasis: "#8957e5" }, - emphasis: "#3d444d", - muted: "#151b23", - neutral: { muted: "#656c7633", emphasis: "#656c76" }, - success: { emphasis: "#238636", muted: "#2ea04326" }, - inset: "#010409", - }, - borderColor: { - accent: { emphasis: "#1f6feb" }, - attention: { emphasis: "#9e6a03" }, - default: "#3d444d", - done: { emphasis: "#8957e5" }, - success: { emphasis: "#238636" }, - muted: "#3d444db3", - translucent: "#ffffff26", - emphasis: "#656c76", - }, - button: { - primary: { - fgColor: { accent: "#3fb950", rest: "#ffffff" }, - bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#29903b", active: "#2e9a40" }, - }, - danger: { - fgColor: { rest: "#fa5e55", hover: "#ffffff" }, - bgColor: { hover: "#b62324", active: themeVars.github.bgColor.danger.emphasis }, - }, - star: { iconColor: "#e3b341" }, - }, - control: { - bgColor: { active: "#2a313c", hover: "#262c36", rest: "#212830" }, - transparent: { bgColor: { active: "#656c7640", hover: "#656c7633", selected: "#656c761a" } }, - }, - shadow: { - floating: { small: "#01040966" }, - inset: "#0104093d", - resting: { small: "#01040999", medium: "#010409cc" }, - }, - overlay: { backdrop: { bgColor: "#21283066" }, bgColor: "#010409" }, - underlineNav: { borderColor: { active: "#f78166" } }, - contribution: { - default: { - bgColor: { num0: "#151b23", num1: "#033a16", num2: "#196c2e", num3: "#2ea043", num4: "#56d364" }, - borderColor: { num0: "#0104090d" }, - }, - }, -}; - -export const darkColors = github2ThemeColor(darkGithubColors); - -export default defineTheme(darkColors); diff --git a/themes/githubDark.ts b/themes/githubDark.ts new file mode 100644 index 0000000..2d62ed9 --- /dev/null +++ b/themes/githubDark.ts @@ -0,0 +1,457 @@ +/*! + * Copyright (c) https://github.com/lutinglt + * + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author lutinglt + */ + +import type { GithubColor, GitHubSyntax } from "src"; +import { defineTheme, github2ThemeColor, themeVars } from "src"; + +/** GitHub 深色主题 */ +export const githubDarkGithubColors: GithubColor = { + isDarkTheme: true, + avatar: { bgColor: "#ffffff1a", borderColor: "#ffffff26" }, + display: { + blue: { fgColor: "#4493f8" }, + brown: { fgColor: "#b69a6d" }, + cyan: { fgColor: "#07ace4" }, + indigo: { fgColor: "#9899ec" }, + lemon: { fgColor: "#ba9b12" }, + olive: { fgColor: "#a2a626" }, + teal: { fgColor: "#1cb0ab" }, + }, + diffBlob: { + addtionNum: { bgColor: "#3fb9504d" }, + addtionWord: { bgColor: "#2ea04366" }, + deletionNum: { bgColor: "#f851494d" }, + deletionWord: { bgColor: "#f8514966" }, + hunkNum: { bgColor: { rest: "#0c2d6b" } }, + }, + fgColor: { + accent: "#4493f8", + attention: "#d29922", + danger: "#f85149", + default: "#f0f6fc", + disabled: "#656c76", + done: "#ab7df8", + muted: "#9198a1", + neutral: "#9198a1", + severe: "#db6d28", + sponsors: "#db61a2", + success: "#3fb950", + black: "#010409", + white: "#ffffff", + onEmphasis: "#f0f6fc", + }, + bgColor: { + accent: { emphasis: "#1f6feb", muted: "#388bfd1a" }, + attention: { emphasis: "#9e6a03", muted: "#bb800926" }, + danger: { emphasis: "#da3633", muted: "#f851491a" }, + default: "#0d1117", + done: { emphasis: "#8957e5" }, + emphasis: "#3d444d", + muted: "#151b23", + neutral: { muted: "#656c7633", emphasis: "#656c76" }, + success: { emphasis: "#238636", muted: "#2ea04326" }, + inset: "#010409", + }, + borderColor: { + accent: { emphasis: "#1f6feb" }, + attention: { emphasis: "#9e6a03" }, + default: "#3d444d", + done: { emphasis: "#8957e5" }, + success: { emphasis: "#238636" }, + muted: "#3d444db3", + translucent: "#ffffff26", + emphasis: "#656c76", + }, + button: { + primary: { + fgColor: { accent: "#3fb950", rest: "#ffffff" }, + bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#29903b", active: "#2e9a40" }, + }, + danger: { + fgColor: { rest: "#fa5e55", hover: "#ffffff" }, + bgColor: { hover: "#b62324", active: themeVars.github.bgColor.danger.emphasis }, + }, + star: { iconColor: "#e3b341" }, + }, + control: { + bgColor: { active: "#2a313c", hover: "#262c36", rest: "#212830" }, + transparent: { bgColor: { active: "#656c7640", hover: "#656c7633", selected: "#656c761a" } }, + }, + controlTrack: { bgColor: { rest: "#010409" } }, + controlKnob: { bgColor: { rest: "#262c36" } }, + shadow: { + floating: { small: "#01040966" }, + inset: "#0104093d", + resting: { small: "#01040999", medium: "#010409cc" }, + }, + overlay: { backdrop: { bgColor: "#21283066" }, bgColor: "#010409" }, + underlineNav: { borderColor: { active: "#f78166" } }, + contribution: { + default: { + bgColor: { num0: "#151b23", num1: "#033a16", num2: "#196c2e", num3: "#2ea043", num4: "#56d364" }, + borderColor: { num0: "#0104090d" }, + }, + }, +}; +/** GitHub 深色主题语法高亮 */ +export const githubDarkSyntax: GitHubSyntax = { + prettyLights: { + syntax: { + brackethighlighter: { angle: "#9198a1", unmatched: "#f85149" }, + carriage: { return: { bg: "#b62324", text: "#f0f6fc" } }, + comment: "#9198a1", + constant: "#79c0ff", + constantOtherReferenceLink: "#a5d6ff", + entity: "#d2a8ff", + entityTag: "#7ee787", + invalid: { illegal: { bg: "#8e1519", text: "#f0f6fc" } }, + keyword: "#ff7b72", + markup: { + bold: "#f0f6fc", + changed: { bg: "#5a1e02", text: "#ffdfb6" }, + deleted: { bg: "#67060c", text: "#ffdcd7" }, + heading: "#1f6feb", + ignored: { bg: "#1158c7", text: "#f0f6fc" }, + inserted: { bg: "#033a16", text: "#aff5b4" }, + italic: "#f0f6fc", + list: "#f2cc60", + }, + metaDiffRange: "#d2a8ff", + storageModifierImport: "#f0f6fc", + string: "#a5d6ff", + stringRegexp: "#7ee787", + sublimelinterGutterMark: "#3d444d", + variable: "#ffa657", + }, + }, + codeMirror: { + syntax: { + fgColor: { + comment: "#656c76", + constant: "#79c0ff", + entity: "#d2a8ff", + keyword: "#ff7b72", + storage: "#ff7b72", + string: "#a5d6ff", + support: "#79c0ff", + variable: "#ffa657", + }, + }, + }, +}; +/** GitHub 柔和深色主题 */ +export const githubSoftDarkGithubColors: GithubColor = { + isDarkTheme: true, + avatar: { bgColor: "#cdd9e51a", borderColor: "#cdd9e526" }, + display: githubDarkGithubColors.display, + diffBlob: { + addtionNum: { bgColor: "#57ab5a4d" }, + addtionWord: { bgColor: "#46954a66" }, + deletionNum: { bgColor: "#e5534b4d" }, + deletionWord: { bgColor: "#e5534b66" }, + hunkNum: { bgColor: { rest: "#143d79" } }, + }, + fgColor: { + accent: "#478be6", + attention: "#c69026", + danger: "#e5534b", + default: "#d1d7e0", + disabled: "#656c76", + done: "#986ee2", + muted: "#9198a1", + neutral: "#9198a1", + severe: "#cc6b2c", + sponsors: "#c96198", + success: "#57ab5a", + black: "#010409", + white: "#cdd9e5", + onEmphasis: "#f0f6fc", + }, + bgColor: { + accent: { emphasis: "#316dca", muted: "#4184e41a" }, + attention: { emphasis: "#966600", muted: "#ae7c1426" }, + danger: { emphasis: "#c93c37", muted: "#e5534b1a" }, + default: "#212830", + done: { emphasis: "#8256d0" }, + emphasis: "#3d444d", + muted: "#262c36", + neutral: githubDarkGithubColors.bgColor.neutral, + success: { emphasis: "#347d39", muted: "#46954a26" }, + inset: "#151b23", + }, + borderColor: { + accent: { emphasis: "#316dca" }, + attention: { emphasis: "#966600" }, + default: "#3d444d", + done: { emphasis: "#8256d0" }, + success: { emphasis: "#347d39" }, + muted: "#3d444db3", + translucent: "#cdd9e526", + emphasis: "#656c76", + }, + button: { + primary: { + fgColor: { accent: "#57ab5a", rest: "#ffffff" }, + bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#3b8640", active: "#428f46" }, + }, + danger: { + fgColor: { rest: "#ea5c53", hover: "#ffffff" }, + bgColor: { hover: "#ad2e2c", active: themeVars.github.bgColor.danger.emphasis }, + }, + star: { iconColor: "#daaa3f" }, + }, + control: { + bgColor: { active: "#3d444d", hover: "#2f3742", rest: "#2a313c" }, + transparent: { bgColor: { active: "#656c7633", hover: "#656c7626", selected: "#656c761a" } }, + }, + controlTrack: { bgColor: { rest: "#151b23" } }, + controlKnob: { bgColor: { rest: "#2a313c" } }, + shadow: githubDarkGithubColors.shadow, + overlay: { backdrop: { bgColor: "#262c3666" }, bgColor: "#2a313c" }, + underlineNav: { borderColor: { active: "#ec775c" } }, + contribution: { + default: { + bgColor: { num0: "#2a313c", num1: "#1b4721", num2: "#2b6a30", num3: "#46954a", num4: "#6bc46d" }, + borderColor: { num0: "#0104090d" }, + }, + }, +}; +/** GitHub 柔和深色主题语法高亮 */ +export const githubSoftDarkSyntax: GitHubSyntax = { + prettyLights: { + syntax: { + brackethighlighter: { angle: "#9198a1", unmatched: "#e5534b" }, + carriage: { return: { bg: "#ad2e2c", text: "#f0f6fc" } }, + comment: "#9198a1", + constant: "#6cb6ff", + constantOtherReferenceLink: "#96d0ff", + entity: "#dcbdfb", + entityTag: "#8ddb8c", + invalid: { illegal: { bg: "#922323", text: "#f0f6fc" } }, + keyword: "#f47067", + markup: { + bold: "#f0f6fc", + changed: { bg: "#682d0f", text: "#ffddb0" }, + deleted: { bg: "#78191b", text: "#ffd8d3" }, + heading: "#316dca", + ignored: { bg: "#255ab2", text: "#f0f6fc" }, + inserted: { bg: "#1b4721", text: "#b4f1b4" }, + italic: "#f0f6fc", + list: "#eac55f", + }, + metaDiffRange: "#dcbdfb", + storageModifierImport: "#f0f6fc", + string: "#96d0ff", + stringRegexp: "#8ddb8c", + sublimelinterGutterMark: "#3d444d", + variable: "#f69d50", + }, + }, + codeMirror: { + syntax: { + fgColor: { + comment: "#656c76", + constant: "#6cb6ff", + entity: "#dcbdfb", + keyword: "#f47067", + storage: "#f47067", + string: "#96d0ff", + support: "#6cb6ff", + variable: "#f69d50", + }, + }, + }, +}; +/** GitHub 深色主题红绿色盲变体 */ +export const githubColorblindDarkGithubColors: GithubColor = { + isDarkTheme: true, + avatar: githubDarkGithubColors.avatar, + display: githubDarkGithubColors.display, + diffBlob: { + addtionNum: { bgColor: "#58a6ff4d" }, + addtionWord: { bgColor: "#388bfd66" }, + deletionNum: { bgColor: "#db6d284d" }, + deletionWord: { bgColor: "#db6d2866" }, + hunkNum: { bgColor: { rest: "#2f3742" } }, + }, + fgColor: { + ...githubDarkGithubColors.fgColor, + danger: "#f0883e", + success: "#58a6ff", + }, + bgColor: { + ...githubDarkGithubColors.bgColor, + danger: { emphasis: "#bd561d", muted: "#db6d281a" }, + success: { emphasis: "#1f6feb", muted: "#388bfd33" }, + }, + borderColor: { + ...githubDarkGithubColors.borderColor, + success: { emphasis: "#1f6feb" }, + }, + button: { + primary: { + fgColor: { accent: "#58a6ff", rest: "#ffffff" }, + bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#2a7aef", active: "#3685f3" }, + }, + danger: { + fgColor: { rest: "#f0883e", hover: "#ffffff" }, + bgColor: { hover: "#9b4215", active: themeVars.github.bgColor.danger.emphasis }, + }, + star: githubDarkGithubColors.button.star, + }, + control: githubDarkGithubColors.control, + controlTrack: githubDarkGithubColors.controlTrack, + controlKnob: githubDarkGithubColors.controlKnob, + shadow: githubDarkGithubColors.shadow, + overlay: githubDarkGithubColors.overlay, + underlineNav: githubDarkGithubColors.underlineNav, + contribution: githubDarkGithubColors.contribution, +}; +/** GitHub 深色主题红绿色盲变体语法高亮 */ +export const githubColorblindDarkSyntax: GitHubSyntax = { + prettyLights: { + syntax: { + brackethighlighter: { angle: "#9198a1", unmatched: "#db6d28" }, + carriage: { return: { bg: "#9b4215", text: "#f0f6fc" } }, + comment: "#9198a1", + constant: "#79c0ff", + constantOtherReferenceLink: "#a5d6ff", + entity: "#d2a8ff", + entityTag: "#a5d6ff", + invalid: { illegal: { bg: "#762d0a", text: "#f0f6fc" } }, + keyword: "#f0883e", + markup: { + bold: "#f0f6fc", + changed: { bg: "#5a1e02", text: "#ffdfb6" }, + deleted: { bg: "#5a1e02", text: "#ffdfb6" }, + heading: "#1f6feb", + ignored: { bg: "#1158c7", text: "#f0f6fc" }, + inserted: { bg: "#0c2d6b", text: "#cae8ff" }, + italic: "#f0f6fc", + list: "#f2cc60", + }, + metaDiffRange: "#d2a8ff", + storageModifierImport: "#f0f6fc", + string: "#a5d6ff", + stringRegexp: "#a5d6ff", + sublimelinterGutterMark: "#3d444d", + variable: "#ffa657", + }, + }, + codeMirror: { + syntax: { + fgColor: { + ...githubDarkSyntax.codeMirror.syntax.fgColor, + variable: "#ffa657", + }, + }, + }, +}; +/** GitHub 深色主题蓝黄色盲变体 */ +export const githubTritanopiaDarkGithubColors: GithubColor = { + ...githubColorblindDarkGithubColors, + diffBlob: { + ...githubColorblindDarkGithubColors.diffBlob, + deletionNum: githubDarkGithubColors.diffBlob.deletionNum, + deletionWord: githubDarkGithubColors.diffBlob.deletionWord, + }, + fgColor: { + ...githubColorblindDarkGithubColors.fgColor, + danger: githubDarkGithubColors.fgColor.danger, + }, + bgColor: { + ...githubColorblindDarkGithubColors.bgColor, + danger: githubDarkGithubColors.bgColor.danger, + }, + button: { + ...githubColorblindDarkGithubColors.button, + danger: githubDarkGithubColors.button.danger, + }, +}; +/** GitHub 深色主题蓝黄色盲变体语法高亮 */ +export const githubTritanopiaDarkSyntax: GitHubSyntax = { + prettyLights: { + syntax: { + ...githubDarkSyntax.prettyLights.syntax, + markup: { + ...githubDarkSyntax.prettyLights.syntax.markup, + changed: { bg: "#67060c", text: "#ffdcd7" }, + inserted: githubColorblindDarkSyntax.prettyLights.syntax.markup.inserted, + }, + stringRegexp: githubColorblindDarkSyntax.prettyLights.syntax.stringRegexp, + variable: "#ffa198", + }, + }, + codeMirror: { + syntax: { + fgColor: { + comment: "#656c76", + constant: "#79c0ff", + entity: "#d2a8ff", + keyword: "#ff7b72", + storage: "#ff7b72", + string: "#a5d6ff", + support: "#79c0ff", + variable: "#ffa198", + }, + }, + }, +}; + +/** GitHub 深色主题颜色 */ +export const githubDarkColors = github2ThemeColor(githubDarkGithubColors); +/** GitHub 柔和深色主题颜色 */ +export const githubSoftDarkColors = github2ThemeColor(githubSoftDarkGithubColors); +/** GitHub 深色主题 红绿色盲变体颜色 */ +export const githubColorblindDarkColors = github2ThemeColor(githubColorblindDarkGithubColors); +/** GitHub 深色主题 蓝黄色盲变体颜色 */ +export const githubTritanopiaDarkColors = github2ThemeColor(githubTritanopiaDarkGithubColors); + +/** GitHub 深色主题 */ +export const githubDark = defineTheme({ + themeColor: githubDarkColors, + syntaxType: "github", + syntaxColors: githubDarkSyntax, + githubColors: githubDarkGithubColors, +}); +/** GitHub 柔和深色主题 */ +export const githubSoftDark = defineTheme({ + themeColor: githubSoftDarkColors, + syntaxType: "github", + syntaxColors: githubSoftDarkSyntax, + githubColors: githubSoftDarkGithubColors, +}); +/** GitHub 深色主题 红绿色盲变体*/ +export const githubColorblindDark = defineTheme({ + themeColor: githubColorblindDarkColors, + syntaxType: "github", + syntaxColors: githubColorblindDarkSyntax, + githubColors: githubColorblindDarkGithubColors, +}); +/** GitHub 深色主题 蓝黄色盲变体 */ +export const githubTritanopiaDark = defineTheme({ + themeColor: githubTritanopiaDarkColors, + syntaxType: "github", + syntaxColors: githubTritanopiaDarkSyntax, + githubColors: githubTritanopiaDarkGithubColors, +}); diff --git a/themes/githubLight.ts b/themes/githubLight.ts new file mode 100644 index 0000000..d2da687 --- /dev/null +++ b/themes/githubLight.ts @@ -0,0 +1,319 @@ +/*! + * Copyright (c) https://github.com/lutinglt + * + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author lutinglt + */ + +import type { GithubColor, GitHubSyntax } from "src"; +import { defineTheme, github2ThemeColor, themeVars } from "src"; + +/** GitHub 浅色主题 */ +export const githubLightGithubColors: GithubColor = { + isDarkTheme: false, + avatar: { bgColor: "#ffffff", borderColor: "#1f232826" }, + display: { + blue: { fgColor: "#0969da" }, + brown: { fgColor: "#755f43" }, + cyan: { fgColor: "#006a80" }, + indigo: { fgColor: "#494edf" }, + lemon: { fgColor: "#786002" }, + olive: { fgColor: "#56682c" }, + teal: { fgColor: "#106e75" }, + }, + diffBlob: { + addtionNum: { bgColor: "#aceebb" }, + addtionWord: { bgColor: "#aceebb" }, + deletionNum: { bgColor: "#ffcecb" }, + deletionWord: { bgColor: "#ffcecb" }, + hunkNum: { bgColor: { rest: "#b6e3ff" } }, + }, + fgColor: { + accent: "#0969da", + attention: "#9a6700", + danger: "#d1242f", + default: "#1f2328", + disabled: "#818b98", + done: "#8250df", + muted: "#59636e", + neutral: "#59636e", + severe: "#bc4c00", + sponsors: "#bf3989", + success: "#1a7f37", + black: "#1f2328", + white: "#ffffff", + onEmphasis: "#ffffff", + }, + bgColor: { + accent: { emphasis: "#0969da", muted: "#ddf4ff" }, + attention: { emphasis: "#9a6700", muted: "#fff8c5" }, + danger: { emphasis: "#cf222e", muted: "#ffebe9" }, + default: "#ffffff", + done: { emphasis: "#8250df" }, + emphasis: "#25292e", + muted: "#f6f8fa", + neutral: { muted: "#818b981f", emphasis: "#59636e" }, + success: { emphasis: "#1f883d", muted: "#dafbe1" }, + inset: "#f6f8fa", + }, + borderColor: { + accent: { emphasis: "#0969da" }, + attention: { emphasis: "#9a6700" }, + default: "#d1d9e0", + done: { emphasis: "#8250df" }, + success: { emphasis: "#1a7f37" }, + muted: "#d1d9e0b3", + translucent: "#1f232826", + emphasis: "#818b98", + }, + button: { + primary: { + fgColor: { accent: "#1a7f37", rest: "#ffffff" }, + bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#1c8139", active: "#197935" }, + }, + danger: { fgColor: { rest: "#d1242f", hover: "#ffffff" }, bgColor: { hover: "#cf222e", active: "#a40e26" } }, + star: { iconColor: "#eac54f" }, + }, + control: { + bgColor: { active: "#e6eaef", hover: "#eff2f5", rest: "#f6f8fa" }, + transparent: { bgColor: { active: "#818b9826", hover: "#818b981a", selected: "#818b9826" } }, + }, + controlTrack: { bgColor: { rest: "#e6eaef" } }, + controlKnob: { bgColor: { rest: "#ffffff" } }, + shadow: { + floating: { small: "#25292e0a" }, + inset: "#1f23280a", + resting: { small: "#1f23280f", medium: "#25292e1f" }, + }, + overlay: { backdrop: { bgColor: "#c8d1da66" }, bgColor: "#ffffff" }, + underlineNav: { borderColor: { active: "#fd8c73" } }, + contribution: { + default: { + bgColor: { num0: "#eff2f5", num1: "#aceebb", num2: "#4ac26b", num3: "#2da44e", num4: "#116329" }, + borderColor: { num0: "#1f23280d" }, + }, + }, +}; +/** GitHub 浅色主题语法高亮 */ +export const githubLightSyntax: GitHubSyntax = { + prettyLights: { + syntax: { + brackethighlighter: { angle: "#59636e", unmatched: "#82071e" }, + carriage: { return: { bg: "#cf222e", text: "#f6f8fa" } }, + comment: "#59636e", + constant: "#0550ae", + constantOtherReferenceLink: "#0a3069", + entity: "#6639ba", + entityTag: "#0550ae", + invalid: { illegal: { bg: "#82071e", text: "#f6f8fa" } }, + keyword: "#cf222e", + markup: { + bold: "#1f2328", + changed: { bg: "#ffd8b5", text: "#953800" }, + deleted: { bg: "#ffebe9", text: "#82071e" }, + heading: "#0550ae", + ignored: { bg: "#0550ae", text: "#d1d9e0" }, + inserted: { bg: "#dafbe1", text: "#116329" }, + italic: "#1f2328", + list: "#3b2300", + }, + metaDiffRange: "#8250df", + storageModifierImport: "#1f2328", + string: "#0a3069", + stringRegexp: "#116329", + sublimelinterGutterMark: "#818b98", + variable: "#953800", + }, + }, + codeMirror: { + syntax: { + fgColor: { + comment: "#1f2328", + constant: "#0550ae", + entity: "#8250df", + keyword: "#cf222e", + storage: "#cf222e", + string: "#0a3069", + support: "#0550ae", + variable: "#953800", + }, + }, + }, +}; +/** GitHub 浅色主题 红绿色盲变体 */ +export const githubColorblindLightGithubColors: GithubColor = { + isDarkTheme: false, + avatar: githubLightGithubColors.avatar, + display: githubLightGithubColors.display, + diffBlob: { + addtionNum: { bgColor: "#b6e3ff" }, + addtionWord: { bgColor: "#b6e3ff" }, + deletionNum: { bgColor: "#ffd8b5" }, + deletionWord: { bgColor: "#ffd8b5" }, + hunkNum: { bgColor: { rest: "#e6eaef" } }, + }, + fgColor: { + ...githubLightGithubColors.fgColor, + danger: "#bc4c00", + success: "#0969da", + }, + bgColor: { + ...githubLightGithubColors.bgColor, + danger: { emphasis: "#bc4c00", muted: "#fff1e5" }, + success: { emphasis: "#0969da", muted: "#ddf4ff" }, + }, + borderColor: { + ...githubLightGithubColors.borderColor, + success: { emphasis: "#0969da" }, + }, + button: { + primary: { + fgColor: { accent: "#0969da", rest: "#ffffff" }, + bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#0864d1", active: "#075fc8" }, + }, + danger: { fgColor: { rest: "#bc4c00", hover: "#ffffff" }, bgColor: { hover: "#bc4c00", active: "#953800" } }, + star: githubLightGithubColors.button.star, + }, + control: githubLightGithubColors.control, + controlTrack: githubLightGithubColors.controlTrack, + controlKnob: githubLightGithubColors.controlKnob, + shadow: githubLightGithubColors.shadow, + overlay: githubLightGithubColors.overlay, + underlineNav: githubLightGithubColors.underlineNav, + contribution: githubLightGithubColors.contribution, +}; +/** GitHub 浅色主题 红绿色盲变体语法高亮 */ +export const githubColorblindLightSyntax: GitHubSyntax = { + prettyLights: { + syntax: { + brackethighlighter: { angle: "#59636e", unmatched: "#762c00" }, + carriage: { return: { bg: "#bc4c00", text: "#f6f8fa" } }, + comment: "#59636e", + constant: "#0550ae", + constantOtherReferenceLink: "#0a3069", + entity: "#6639ba", + entityTag: "#0550ae", + invalid: { illegal: { bg: "#762c00", text: "#f6f8fa" } }, + keyword: "#bc4c00", + markup: { + bold: "#1f2328", + changed: { bg: "#ffd8b5", text: "#953800" }, + deleted: { bg: "#fff1e5", text: "#762c00" }, + heading: "#0550ae", + ignored: { bg: "#0550ae", text: "#d1d9e0" }, + inserted: { bg: "#ddf4ff", text: "#0550ae" }, + italic: "#1f2328", + list: "#3b2300", + }, + metaDiffRange: "#8250df", + storageModifierImport: "#1f2328", + string: "#0a3069", + stringRegexp: "#0550ae", + sublimelinterGutterMark: "#818b98", + variable: "#953800", + }, + }, + codeMirror: { + syntax: { + fgColor: { + comment: "#1f2328", + constant: "#0550ae", + entity: "#8250df", + keyword: "#bc4c00", + storage: "#bc4c00", + string: "#0a3069", + support: "#0550ae", + variable: "#953800", + }, + }, + }, +}; +/** GitHub 浅色主题 蓝黄色盲变体 */ +export const githubTritanopiaLightGithubColors: GithubColor = { + ...githubColorblindLightGithubColors, + diffBlob: { + ...githubColorblindLightGithubColors.diffBlob, + deletionNum: githubLightGithubColors.diffBlob.deletionNum, + deletionWord: githubLightGithubColors.diffBlob.deletionWord, + }, + fgColor: { + ...githubColorblindLightGithubColors.fgColor, + danger: githubLightGithubColors.fgColor.danger, + }, + bgColor: { + ...githubColorblindLightGithubColors.bgColor, + danger: githubLightGithubColors.bgColor.danger, + }, + button: { + ...githubColorblindLightGithubColors.button, + danger: githubLightGithubColors.button.danger, + }, +}; +/** GitHub 浅色主题 蓝黄色盲变体语法高亮 */ +export const githubTritanopiaLightSyntax: GitHubSyntax = { + prettyLights: { + syntax: { + ...githubLightSyntax.prettyLights.syntax, + markup: { + ...githubLightSyntax.prettyLights.syntax.markup, + changed: { bg: "#ffcecb", text: "#a40e26" }, + inserted: githubColorblindLightSyntax.prettyLights.syntax.markup.inserted, + }, + stringRegexp: githubColorblindLightSyntax.prettyLights.syntax.stringRegexp, + variable: "#a40e26", + }, + }, + codeMirror: { + syntax: { + fgColor: { + ...githubLightSyntax.codeMirror.syntax.fgColor, + variable: "#a40e26", + }, + }, + }, +}; + +/** GitHub 浅色主题颜色 */ +export const githubLightColors = github2ThemeColor(githubLightGithubColors); +/** GitHub 浅色主题 红绿色盲变体颜色 */ +export const githubColorblindLightColors = github2ThemeColor(githubColorblindLightGithubColors); +/** GitHub 浅色主题 蓝黄色盲变体颜色 */ +export const githubTritanopiaLightColors = github2ThemeColor(githubTritanopiaLightGithubColors); + +/** GitHub 浅色主题 */ +export const githubLight = defineTheme({ + themeColor: githubLightColors, + syntaxType: "github", + syntaxColors: githubLightSyntax, + githubColors: githubLightGithubColors, +}); +/** GitHub 浅色主题 红绿色盲变体 */ +export const githubColorblindLight = defineTheme({ + themeColor: githubColorblindLightColors, + syntaxType: "github", + syntaxColors: githubColorblindLightSyntax, + githubColors: githubColorblindLightGithubColors, +}); +/** GitHub 浅色主题 蓝黄色盲变体 */ +export const githubTritanopiaLight = defineTheme({ + themeColor: githubTritanopiaLightColors, + syntaxType: "github", + syntaxColors: githubTritanopiaLightSyntax, + githubColors: githubTritanopiaLightGithubColors, +}); diff --git a/themes/githubPink.ts b/themes/githubPink.ts new file mode 100644 index 0000000..0b72d59 --- /dev/null +++ b/themes/githubPink.ts @@ -0,0 +1,97 @@ +/*! + * Copyright (c) https://github.com/lutinglt + * + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author lutinglt + */ + +import type { DisplayColor } from "src"; +import { defineTheme, display2GithubColor, github2ThemeColor } from "src"; +import { + githubDarkGithubColors, + githubDarkSyntax, + githubSoftDarkGithubColors, + githubSoftDarkSyntax, +} from "themes/githubDark"; +import { githubLightGithubColors, githubLightSyntax } from "themes/githubLight"; + +/** GitHub 粉色深色主题色阶 */ +export const githubPinkDarkDisplayColors: DisplayColor = { + num0: "#2d1524", + num1: "#451c35", + num2: "#65244a", + num3: "#842a5d", + num4: "#ac2f74", + num5: "#d34591", + num6: "#e57bb2", + num7: "#ec8dbd", + num8: "#f4a9cd", + num9: "#f9bed9", +}; +/** GitHub 粉色深色主题 */ +export const githubPinkDarkGithubColors = display2GithubColor(githubPinkDarkDisplayColors, githubDarkGithubColors); +/** GitHub 粉色柔和深色主题 */ +export const pinkSoftDarkGithubColors = display2GithubColor( + githubPinkDarkDisplayColors, + githubSoftDarkGithubColors, + true +); +/** GitHub 粉色浅色主题色阶*/ +export const githubPinkLightDisplayColors: DisplayColor = { + num0: "#ffe5f1", + num1: "#fdc9e2", + num2: "#f8a5cf", + num3: "#f184bc", + num4: "#e55da5", + num5: "#ce2c85", + num6: "#b12f79", + num7: "#8e2e66", + num8: "#6e2b53", + num9: "#4d233d", +}; +/** GitHub 粉色浅色主题*/ +export const githubPinkLightGithubColors = display2GithubColor(githubPinkLightDisplayColors, githubLightGithubColors); + +/** GitHub 粉色深色主题颜色 */ +export const githubPinkDarkColors = github2ThemeColor(githubPinkDarkGithubColors); +export const pinkSoftDarkColors = github2ThemeColor(pinkSoftDarkGithubColors); +/** GitHub 粉色浅色主题颜色 */ +export const githubPinkLightColors = github2ThemeColor(githubPinkLightGithubColors); + +/** Gitea GitHub Theme 拓展 GitHub 粉色深色主题 */ +export const githubPinkDark = defineTheme({ + themeColor: githubPinkDarkColors, + syntaxType: "github", + syntaxColors: githubDarkSyntax, + githubColors: githubPinkDarkGithubColors, +}); +/** Gitea GitHub Theme 拓展 GitHub 粉色柔和深色主题 */ +export const githubPinkSoftDark = defineTheme({ + themeColor: pinkSoftDarkColors, + syntaxType: "github", + syntaxColors: githubSoftDarkSyntax, + githubColors: pinkSoftDarkGithubColors, +}); +/** Gitea GitHub Theme 拓展 GitHub 粉色浅色主题 */ +export const githubPinkLight = defineTheme({ + themeColor: githubPinkLightColors, + syntaxType: "github", + syntaxColors: githubLightSyntax, + githubColors: githubPinkLightGithubColors, +}); diff --git a/themes/light.css.ts b/themes/light.css.ts deleted file mode 100644 index 78843b5..0000000 --- a/themes/light.css.ts +++ /dev/null @@ -1,116 +0,0 @@ -/*! - * Copyright (c) https://github.com/lutinglt - * - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @author lutinglt - */ - -import { defineTheme, themeVars } from "src"; -import { github2ThemeColor, type GithubColor } from "src/core/github"; - -export const lightGithubColors: GithubColor = { - isDarkTheme: false, - avatar: { - bgColor: "#ffffff", - borderColor: "#1f232826", - }, - display: { - blue: { fgColor: "#0969da" }, - brown: { fgColor: "#755f43" }, - cyan: { fgColor: "#006a80" }, - indigo: { fgColor: "#494edf" }, - lemon: { fgColor: "#786002" }, - olive: { fgColor: "#56682c" }, - teal: { fgColor: "#106e75" }, - }, - diffBlob: { - addtionNum: { bgColor: "#aceebb" }, - addtionWord: { bgColor: "#aceebb" }, - deletionNum: { bgColor: "#ffcecb" }, - deletionWord: { bgColor: "#ffcecb" }, - hunkNum: { bgColor: { rest: "#b6e3ff" } }, - }, - fgColor: { - accent: "#0969da", - attention: "#9a6700", - danger: "#d1242f", - default: "#1f2328", - disabled: "#818b98", - done: "#8250df", - muted: "#59636e", - neutral: "#59636e", - severe: "#bc4c00", - sponsors: "#bf3989", - success: "#1a7f37", - black: "#1f2328", - white: "#ffffff", - onEmphasis: "#ffffff", - }, - bgColor: { - accent: { emphasis: "#0969da", muted: "#ddf4ff" }, - attention: { emphasis: "#9a6700", muted: "#fff8c5" }, - danger: { emphasis: "#cf222e", muted: "#ffebe9" }, - default: "#ffffff", - done: { emphasis: "#8250df" }, - emphasis: "#25292e", - muted: "#f6f8fa", - neutral: { muted: "#818b981f", emphasis: "#59636e" }, - success: { emphasis: "#1f883d", muted: "#dafbe1" }, - inset: "#f6f8fa", - }, - borderColor: { - accent: { emphasis: "#0969da" }, - attention: { emphasis: "#9a6700" }, - default: "#d1d9e0", - done: { emphasis: "#8250df" }, - success: { emphasis: "#1a7f37" }, - muted: "#d1d9e0b3", - translucent: "#1f232826", - emphasis: "#818b98", - }, - button: { - primary: { - fgColor: { accent: "#1a7f37", rest: "#ffffff" }, - bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#1c8139", active: "#197935" }, - }, - danger: { fgColor: { rest: "#d1242f", hover: "#ffffff" }, bgColor: { hover: "#cf222e", active: "#a40e26" } }, - star: { iconColor: "#eac54f" }, - }, - control: { - bgColor: { active: "#e6eaef", hover: "#eff2f5", rest: "#f6f8fa" }, - transparent: { bgColor: { active: "#818b9826", hover: "#818b981a", selected: "#818b9826" } }, - }, - shadow: { - floating: { small: "#25292e0a" }, - inset: "#1f23280a", - resting: { small: "#1f23280f", medium: "#25292e1f" }, - }, - overlay: { backdrop: { bgColor: "#c8d1da66" }, bgColor: "#ffffff" }, - underlineNav: { borderColor: { active: "#fd8c73" } }, - contribution: { - default: { - bgColor: { num0: "#eff2f5", num1: "#aceebb", num2: "#4ac26b", num3: "#2da44e", num4: "#116329" }, - borderColor: { num0: "#1f23280d" }, - }, - }, -}; - -export const lightColors = github2ThemeColor(lightGithubColors); - -export default defineTheme(lightColors); diff --git a/themes/soft-dark.css.ts b/themes/soft-dark.css.ts deleted file mode 100644 index 0945a94..0000000 --- a/themes/soft-dark.css.ts +++ /dev/null @@ -1,140 +0,0 @@ -/*! - * Copyright (c) https://github.com/lutinglt - * - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @author lutinglt - */ - -import { defineTheme, themeVars, type Chroma } from "src"; -import { github2ThemeColor, type GithubColor } from "src/core/github"; -import { prettylights2Chroma, type prettylightsColor } from "src/core/prettylights"; -import { darkGithubColors } from "themes/dark"; - -export const softDarkGithubColors: GithubColor = { - isDarkTheme: true, - avatar: { - bgColor: "#cdd9e51a", - borderColor: "#cdd9e526", - }, - display: darkGithubColors.display, - diffBlob: { - addtionNum: { bgColor: "#57ab5a4d" }, - addtionWord: { bgColor: "#46954a66" }, - deletionNum: { bgColor: "#e5534b4d" }, - deletionWord: { bgColor: "#e5534b66" }, - hunkNum: { bgColor: { rest: "#143d79" } }, - }, - fgColor: { - accent: "#478be6", - attention: "#c69026", - danger: "#e5534b", - default: "#d1d7e0", - disabled: "#656c76", - done: "#986ee2", - muted: "#9198a1", - neutral: "#9198a1", - severe: "#cc6b2c", - sponsors: "#c96198", - success: "#57ab5a", - black: "#010409", - white: "#cdd9e5", - onEmphasis: "#f0f6fc", - }, - bgColor: { - accent: { emphasis: "#316dca", muted: "#4184e41a" }, - attention: { emphasis: "#966600", muted: "#ae7c1426" }, - danger: { emphasis: "#c93c37", muted: "#e5534b1a" }, - default: "#212830", - done: { emphasis: "#8256d0" }, - emphasis: "#3d444d", - muted: "#262c36", - neutral: darkGithubColors.bgColor.neutral, - success: { emphasis: "#347d39", muted: "#46954a26" }, - inset: "#151b23", - }, - borderColor: { - accent: { emphasis: "#316dca" }, - attention: { emphasis: "#966600" }, - default: "#3d444d", - done: { emphasis: "#8256d0" }, - success: { emphasis: "#347d39" }, - muted: "#3d444db3", - translucent: "#cdd9e526", - emphasis: "#656c76", - }, - button: { - primary: { - fgColor: { accent: "#57ab5a", rest: "#ffffff" }, - bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#3b8640", active: "#428f46" }, - }, - danger: { - fgColor: { rest: "#ea5c53", hover: "#ffffff" }, - bgColor: { hover: "#ad2e2c", active: themeVars.github.bgColor.danger.emphasis }, - }, - star: { iconColor: "#daaa3f" }, - }, - control: { - bgColor: { active: "#3d444d", hover: "#2f3742", rest: "#2a313c" }, - transparent: { bgColor: { active: "#656c7633", hover: "#656c7626", selected: "#656c761a" } }, - }, - shadow: darkGithubColors.shadow, - overlay: { backdrop: { bgColor: "#262c3666" }, bgColor: "#2a313c" }, - underlineNav: { borderColor: { active: "#ec775c" } }, - contribution: { - default: { - bgColor: { num0: "#2a313c", num1: "#1b4721", num2: "#2b6a30", num3: "#46954a", num4: "#6bc46d" }, - borderColor: { num0: "#0104090d" }, - }, - }, -}; - -export const softDarkPrettylights: prettylightsColor = { - syntax: { - brackethighlighter: { angle: "#9198a1", unmatched: "#e5534b" }, - carriage: { return: { bg: "#ad2e2c", text: "#f0f6fc" } }, - comment: "#9198a1", - constant: "#6cb6ff", - constantOtherReferenceLink: "#96d0ff", - entity: "#dcbdfb", - entityTag: "#8ddb8c", - invalid: { illegal: { bg: "#922323", text: "#f0f6fc" } }, - keyword: "#f47067", - markup: { - bold: "#f0f6fc", - changed: { bg: "#682d0f", text: "#ffddb0" }, - deleted: { bg: "#78191b", text: "#ffd8d3" }, - heading: "#316dca", - ignored: { bg: "#255ab2", text: "#f0f6fc" }, - inserted: { bg: "#1b4721", text: "#b4f1b4" }, - italic: "#f0f6fc", - list: "#eac55f", - }, - metaDiffRange: "#dcbdfb", - storageModifierImport: "#f0f6fc", - string: "#96d0ff", - stringRegexp: "#8ddb8c", - sublimelinterGutterMark: "#3d444d", - variable: "#f69d50", - }, -}; - -export const softDarkColors = github2ThemeColor(softDarkGithubColors); -export const softDarkChroma: Chroma = prettylights2Chroma(softDarkPrettylights); - -export default defineTheme(softDarkColors, softDarkChroma); diff --git a/themes/tritanopia-dark.css.ts b/themes/tritanopia-dark.css.ts deleted file mode 100644 index 7edc63e..0000000 --- a/themes/tritanopia-dark.css.ts +++ /dev/null @@ -1,68 +0,0 @@ -/*! - * Copyright (c) https://github.com/lutinglt - * - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @author lutinglt - */ - -import { defineTheme, type Chroma } from "src"; -import { darkPrettylights } from "src/core/chroma"; -import { github2ThemeColor, type GithubColor } from "src/core/github"; -import { prettylights2Chroma, type prettylightsColor } from "src/core/prettylights"; -import { colorblindDarkGithubColors, colorblindDarkPrettylights } from "themes/colorblind-dark"; -import { darkGithubColors } from "themes/dark"; - -export const tritanopiaDarkGithubColors: GithubColor = { - ...colorblindDarkGithubColors, - diffBlob: { - ...colorblindDarkGithubColors.diffBlob, - deletionNum: darkGithubColors.diffBlob.deletionNum, - deletionWord: darkGithubColors.diffBlob.deletionWord, - }, - fgColor: { - ...colorblindDarkGithubColors.fgColor, - danger: darkGithubColors.fgColor.danger, - }, - bgColor: { - ...colorblindDarkGithubColors.bgColor, - danger: darkGithubColors.bgColor.danger, - }, - button: { - ...colorblindDarkGithubColors.button, - danger: darkGithubColors.button.danger, - }, -}; - -export const tritanopiaDarkPrettylights: prettylightsColor = { - syntax: { - ...darkPrettylights.syntax, - markup: { - ...darkPrettylights.syntax.markup, - changed: { bg: "#67060c", text: "#ffdcd7" }, - inserted: colorblindDarkPrettylights.syntax.markup.inserted, - }, - stringRegexp: colorblindDarkPrettylights.syntax.stringRegexp, - variable: "#ffa198", - }, -}; - -export const tritanopiaDarkColors = github2ThemeColor(tritanopiaDarkGithubColors); -export const tritanopiaDarkChroma: Chroma = prettylights2Chroma(tritanopiaDarkPrettylights); - -export default defineTheme(tritanopiaDarkColors, tritanopiaDarkChroma); diff --git a/themes/tritanopia-light.css.ts b/themes/tritanopia-light.css.ts deleted file mode 100644 index 65ed017..0000000 --- a/themes/tritanopia-light.css.ts +++ /dev/null @@ -1,68 +0,0 @@ -/*! - * Copyright (c) https://github.com/lutinglt - * - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @author lutinglt - */ - -import { defineTheme, type Chroma } from "src"; -import { lightPrettylights } from "src/core/chroma"; -import { github2ThemeColor, type GithubColor } from "src/core/github"; -import { prettylights2Chroma, type prettylightsColor } from "src/core/prettylights"; -import { colorblindLightGithubColors, colorblindLightPrettylights } from "themes/colorblind-light"; -import { lightGithubColors } from "themes/light"; - -export const tritanopiaLightGithubColors: GithubColor = { - ...colorblindLightGithubColors, - diffBlob: { - ...colorblindLightGithubColors.diffBlob, - deletionNum: lightGithubColors.diffBlob.deletionNum, - deletionWord: lightGithubColors.diffBlob.deletionWord, - }, - fgColor: { - ...colorblindLightGithubColors.fgColor, - danger: lightGithubColors.fgColor.danger, - }, - bgColor: { - ...colorblindLightGithubColors.bgColor, - danger: lightGithubColors.bgColor.danger, - }, - button: { - ...colorblindLightGithubColors.button, - danger: lightGithubColors.button.danger, - }, -}; - -export const tritanopiaLightPrettylights: prettylightsColor = { - syntax: { - ...lightPrettylights.syntax, - markup: { - ...lightPrettylights.syntax.markup, - changed: { bg: "#ffcecb", text: "#a40e26" }, - inserted: colorblindLightPrettylights.syntax.markup.inserted, - }, - stringRegexp: colorblindLightPrettylights.syntax.stringRegexp, - variable: "#a40e26", - }, -}; - -export const tritanopiaLightColors = github2ThemeColor(tritanopiaLightGithubColors); -export const tritanopiaLightChroma: Chroma = prettylights2Chroma(tritanopiaLightPrettylights); - -export default defineTheme(tritanopiaLightColors, tritanopiaLightChroma); diff --git a/tsconfig.json b/tsconfig.json index 1ca1e58..f7e8886 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -34,8 +34,8 @@ "*": ["./*"], "src/*": ["./src/*"], "styles/*": ["./styles/*"], - "themes/*": ["./themes/*", "./themes/*.css"] + "themes/*": ["./themes/*"] } }, - "include": ["src", "styles", "themes", "vite.config.ts"] + "include": ["src", "styles", "themes", "vite.config.ts", "theme.config.ts", "eslint.config.ts"] } diff --git a/vite.config.ts b/vite.config.ts index 04ac0c6..e98a144 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -17,18 +17,14 @@ * limitations under the License. */ -import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin"; -import linaria from "@wyw-in-js/vite"; +import wyw from "@wyw-in-js/vite"; import * as dotenv from "dotenv"; -import { Features } from "lightningcss"; +import * as lightningcss from "lightningcss"; import fs from "node:fs"; -import { createRequire } from "node:module"; import path from "node:path"; -import * as sass from "sass-embedded"; import { defineConfig } from "vite"; -import { themeInput, themePlugin } from "./src/core/vite"; +import { giteaGitHubThemePlugin } from "./src/vite-plugin"; -const require = createRequire(import.meta.url); dotenv.config({ quiet: true }); // 版本号: 版本号.YYMMDD @@ -38,53 +34,33 @@ const year = now.getFullYear().toString().slice(-2); const month = (now.getMonth() + 1).toString().padStart(2, "0"); const day = now.getDate().toString().padStart(2, "0"); -const outDir = "dist"; // 输出目录 -const themesDir = "themes"; // 颜色主题目录 - -export default defineConfig(({ mode }) => { - return { - define: { - __THEME_VERSION__: JSON.stringify(`${pkg.version}.${year}${month}${day}`), +export default defineConfig({ + define: { + __THEME_VERSION__: JSON.stringify(`${pkg.version}.${year}${month}${day}`), + }, + resolve: { + alias: { + src: path.resolve(__dirname, "src"), + styles: path.resolve(__dirname, "styles"), + themes: path.resolve(__dirname, "themes"), }, - resolve: { - alias: { - src: path.resolve(__dirname, "src"), - styles: path.resolve(__dirname, "styles"), - themes: path.resolve(__dirname, "themes"), - }, - extensions: [".js", ".ts", ".css.ts"], + extensions: [".js", ".ts", ".css.ts"], + }, + css: { + transformer: "lightningcss", + lightningcss: { + exclude: lightningcss.Features.LightDark, // 不生成 LightningCSS 的主题变量 }, - css: { - transformer: "lightningcss", - lightningcss: { - minify: true, - exclude: Features.LightDark, // 不生成 lightningcss 的主题变量 - }, - }, - plugins: [ - linaria({ - include: ["**/*.ts"], - babelOptions: { - presets: ["@babel/preset-typescript"], - }, - preprocessor: (_selector, cssText) => sass.compileString(cssText).css, // 默认为全局样式并使用 sass-embedded 预处理 css - tagResolver: (source, tag) => - // 识别从 src 导出的 css 标签,使用 @linaria/core/processors/css 处理 - source === "src/types/vars" && tag === "css" ? require.resolve("@linaria/core/processors/css") : null, - }), - vanillaExtractPlugin(), - themePlugin(), - ], - build: { - cssMinify: "lightningcss", - cssCodeSplit: true, - outDir: outDir, - rollupOptions: { - input: themeInput(outDir, themesDir, mode), - output: { - assetFileNames: "[name].[ext]", - }, - }, - }, - }; + }, + plugins: [ + wyw({ + babelOptions: { presets: ["@babel/preset-typescript"] }, + // 默认为全局样式 + preprocessor: (_selector, cssText) => + // 当 CSS 嵌套的父选择器是选择器列表(逗号分隔)时, LightningCSS 编译嵌套必须使用 :is() 这是 CSS Nesting 规范定义的语义 + // LightningCSS 没有提供"展开嵌套但不使用 :is()"的选项, :is() 会提升选择器的优先级 + lightningcss.transform({ filename: "wyw-in-js.css", code: Buffer.from(cssText) }).code.toString(), + }), + giteaGitHubThemePlugin(), + ], });