nodejs -> bun

This commit is contained in:
lutinglt committed 2026-06-04 21:40:52 +08:00
1 parent 2c09dd3335
commit c87cb41fb0
102 files changed
+611 -708

No files matched your search

+5 -5
View File
@@ -25,16 +25,16 @@ jobs:
- "vite.config.ts" - "vite.config.ts"
- "package.json" - "package.json"
- uses: actions/setup-node@v6 - uses: oven-sh/setup-bun@v2
with: with:
node-version: 24 bun-version: "1.3.14"
- name: Build theme - name: Build theme
id: build id: build
if: steps.changes.outputs.src == 'true' if: steps.changes.outputs.src == 'true'
run: | run: |
npm install bun install
npm run build:ci bun bundle:ci
- name: Upload css assets - name: Upload css assets
if: steps.build.outcome == 'success' if: steps.build.outcome == 'success'
@@ -54,7 +54,7 @@ jobs:
id: locales id: locales
if: steps.build.outcome =='success' if: steps.build.outcome =='success'
continue-on-error: true continue-on-error: true
run: npm run update:locale run: bun update:locale
- name: Upload locales assets - name: Upload locales assets
if: steps.locales.outcome =='success' if: steps.locales.outcome =='success'
+4 -4
View File
@@ -11,13 +11,13 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
- uses: actions/setup-node@v6 - uses: oven-sh/setup-bun@v2
with: with:
node-version: 24 bun-version: "1.3.14"
- name: Build theme - name: Build theme
run: | run: |
npm install bun install
npm run release bun release
- name: Create release - name: Create release
run: | run: |
tar -zcf dist/theme-github-base.tar.gz \ tar -zcf dist/theme-github-base.tar.gz \
+2
View File
@@ -1,5 +1,7 @@
dist dist
node_modules node_modules
bun.lock
bun.lockb
package-lock.json package-lock.json
.env .env
.VSCodeCounter .VSCodeCounter
+5
View File
@@ -1,3 +1,8 @@
### ⚠️ Breaking Changes
- Starting from this version, CSS nesting will no longer be expanded, which will reduce the volume by 40% and improve
loading speed,ensure styles are applied correctly by keeping Chrome/Edge >= 120, Firefox >= 121, Safari >= 16.5.
### ✨ Feature ### ✨ Feature
- Add high contrast color themes. - Add high contrast color themes.
+5 -5
View File
@@ -37,8 +37,8 @@ accepted.
> [!IMPORTANT] > [!IMPORTANT]
> >
> Because the project uses new CSS features, ensure styles are applied correctly by keeping Chrome/Edge >= 105, > Because the project uses new CSS features, ensure styles are applied correctly by keeping Chrome/Edge >= 120,
> Firefox >= 121, Safari >= 15.4 > Firefox >= 121, Safari >= 16.5
1. Download the latest CSS theme file from the release page and place it in the `data/gitea/public/assets/css` directory 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) (This directory may not be available by default and needs to be manually created)
@@ -214,13 +214,13 @@ Add the following code at the beginning or end of the theme's CSS file
You might want to use the development version of the theme instead of the released version You might want to use the development version of the theme instead of the released version
Please ensure you have Node.js environment installed, Node.js 24.12.0 or above is recommended Please ensure you have Bun environment installed, Bun 1.3.14 or above is recommended
```bash ```bash
git clone https://github.com/lutinglt/gitea-github-theme.git git clone https://github.com/lutinglt/gitea-github-theme.git
cd gitea-github-theme cd gitea-github-theme
npm install bun install
npm run build bun bundle
``` ```
After compilation, theme files will be generated in the `dist` directory. You can place the theme files into the After compilation, theme files will be generated in the `dist` directory. You can place the theme files into the
+4 -4
View File
@@ -35,7 +35,7 @@ Gitea 理论上小版本号变更不会修改前端布局, 所以主题的小版
> [!IMPORTANT] > [!IMPORTANT]
> >
> 因为项目使用了 CSS 新特性, 确保样式正确应用需保持 Chrome/Edge >= 105, Firefox >= 121, Safari >= 15.4 > 因为项目使用了 CSS 新特性, 确保样式正确应用需保持 Chrome/Edge >= 120, Firefox >= 121, Safari >= 16.5
1. 在发布页下载最新的 CSS 主题文件放入 `data/gitea/public/assets/css` 目录下 (默认可能没有此目录需手动创建) 1. 在发布页下载最新的 CSS 主题文件放入 `data/gitea/public/assets/css` 目录下 (默认可能没有此目录需手动创建)
2. 修改 `data/gitea/conf/app.ini`,并将 CSS 文件名去掉 `theme-` 的名称附加到 `[ui]` 下的 `THEMES` 末尾 2. 修改 `data/gitea/conf/app.ini`,并将 CSS 文件名去掉 `theme-` 的名称附加到 `[ui]` 下的 `THEMES` 末尾
@@ -208,13 +208,13 @@ THEMES = github-catppuccin-auto, github-catppuccin-latte, github-catppuccin-frap
也许你会想使用开发中的主题, 而不是发布的主题 也许你会想使用开发中的主题, 而不是发布的主题
请确保你已经安装了 Node.js 环境, 推荐使用 Node.js 24.12.0 或以上版本 请确保你已经安装了 Bun 环境, 推荐使用 Bun 1.3.14 或以上版本
```bash ```bash
git clone https://github.com/lutinglt/gitea-github-theme.git git clone https://github.com/lutinglt/gitea-github-theme.git
cd gitea-github-theme cd gitea-github-theme
npm install bun install
npm run build bun bundle
``` ```
编译完成后, 会在 `dist` 目录下生成主题文件, 你可以将主题文件放入 `gitea/public/assets/css` 目录下, 然后在 编译完成后, 会在 `dist` 目录下生成主题文件, 你可以将主题文件放入 `gitea/public/assets/css` 目录下, 然后在
+3
View File
@@ -0,0 +1,3 @@
# bunfig.toml
[install]
registry = "https://registry.npmjs.org"
+23 -16
View File
@@ -1,5 +1,14 @@
{ {
"name": "gitea-github-theme", "name": "@lutinglt/gitea-github-theme",
"exports": {
"./theme.config.ts": "./theme.config.ts",
"./core": "./src/index.ts",
"./vite-plugin": "./src/vite-plugin/index.ts",
"./styles": "./styles/index.ts",
"./styles/common": "./styles/common/index.ts",
"./themes": "./themes/index.ts",
"./primer": "./primer/index.ts"
},
"version": "1.26.2", "version": "1.26.2",
"license": "Apache-2.0", "license": "Apache-2.0",
"author": { "author": {
@@ -8,20 +17,19 @@
}, },
"type": "module", "type": "module",
"scripts": { "scripts": {
"test": "vitest", "lint": "bun eslint .",
"lint": "eslint .", "format": "bun prettier --write .",
"format": "prettier --write .", "bundle": "tsgo -b -v && bunx --bun vite build",
"build": "tsgo -b -v && vite build", "commit": "bun format && bun lint && bun test && bun bundle",
"commit": "npm run format && npm run lint && npm run test && npm run build", "version": "bun scripts/version.ts",
"version": "node scripts/version.ts", "release": "bun bundle && bun update:locale",
"release": "npm run build && npm run update:locale", "sync:theme": "bun scripts/syncTheme.ts",
"sync:theme": "node scripts/syncTheme.ts", "update:primer": "bun scripts/buildPrimerTSToken.ts",
"update:primer": "node scripts/buildPrimerTSToken.ts", "update:locale": "bun scripts/translate.ts",
"update:locale": "node scripts/translate.ts", "update:gitea": "bun scripts/updateGitea.ts",
"update:gitea": "node scripts/updateGitea.ts", "install:clean": "rm -rf node_modules bun.lock bun.lockb && bun install",
"install:clean": "npm cache clean --force && rm -rf node_modules package-lock.json && npm install", "bundle:ci": "bun lint && bun vitest && bun bundle",
"build:ci": "npm run lint && npm run test && npm run build", "bundle:dev": "bun bundle && bun sync:theme"
"build:dev": "npm run build && npm run sync:theme"
}, },
"devDependencies": { "devDependencies": {
"@catppuccin/palette": "^1.8.0", "@catppuccin/palette": "^1.8.0",
@@ -41,7 +49,6 @@
"prettier-plugin-organize-imports": "^4.3.0", "prettier-plugin-organize-imports": "^4.3.0",
"style-dictionary": "^5.4.1", "style-dictionary": "^5.4.1",
"typescript-eslint": "^8.59.1", "typescript-eslint": "^8.59.1",
"typescript-plugin-css-modules": "^5.2.0",
"undici": "^7.0.0", "undici": "^7.0.0",
"vite": "^8.0.5", "vite": "^8.0.5",
"vitest": "^4.1.7" "vitest": "^4.1.7"
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import type { MapLeafNodes } from "@gitea-github-theme/core"; import type { MapLeafNodes } from "@lutinglt/gitea-github-theme/core";
import dark from "./dark"; import dark from "./dark";
import darkColorblind from "./dark-colorblind"; import darkColorblind from "./dark-colorblind";
+1 -1
View File
@@ -21,7 +21,7 @@ import dotenv from "dotenv";
import child_process from "node:child_process"; import child_process from "node:child_process";
import fs from "node:fs"; import fs from "node:fs";
import path from "node:path"; import path from "node:path";
import { pkg, rootDir, setGlobalProxy } from "./utils.ts"; import { pkg, rootDir, setGlobalProxy } from "./utils";
dotenv.config({ quiet: true }); dotenv.config({ quiet: true });
setGlobalProxy(); setGlobalProxy();
+1 -1
View File
@@ -19,7 +19,7 @@
import fs from "node:fs"; import fs from "node:fs";
import path from "node:path"; import path from "node:path";
import { pkg, rootDir, setGlobalProxy } from "./utils.ts"; import { pkg, rootDir, setGlobalProxy } from "./utils";
setGlobalProxy(); setGlobalProxy();
+1 -1
View File
@@ -20,7 +20,7 @@
import path from "node:path"; import path from "node:path";
import { fileURLToPath } from "node:url"; import { fileURLToPath } from "node:url";
import { ProxyAgent, setGlobalDispatcher } from "undici"; import { ProxyAgent, setGlobalDispatcher } from "undici";
import pkg from "../package.json" with { type: "json" }; import pkg from "../package.json";
export function setGlobalProxy() { export function setGlobalProxy() {
const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.ALL_PROXY; const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.ALL_PROXY;
+1 -1
View File
@@ -17,6 +17,6 @@
* limitations under the License. * limitations under the License.
*/ */
import { pkg } from "./utils.ts"; import { pkg } from "./utils";
console.log(pkg.version); console.log(pkg.version);
File renamed without changes.
File renamed without changes.
+90
View File
@@ -0,0 +1,90 @@
/*!
* 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 type { StyleRule } from "@vanilla-extract/css";
import { transform } from "lightningcss";
import { getCallerInfo } from "../utils";
import { captureStyle } from "../vanilla-extract";
declare const CSSBrand: unique symbol;
type CSSObject = { [CSSBrand]: true };
type CSSPrimitive = string | number;
type CSSInterpolation = CSSPrimitive | CSSObject | undefined;
type SelectorStyleRule =
| StyleRule
| {
[key: string]: StyleRule | SelectorStyleRule;
};
const SHARED_CACHE_KEY = "__GITEA_GITHUB_THEME_CSS_CACHE__";
const g = globalThis as Record<string, unknown>;
const cssCache: string[] = (g[SHARED_CACHE_KEY] as string[]) || (g[SHARED_CACHE_KEY] = []);
/**
* css 模板字符串 —— 类式 linaria 的 css tag,用于 vscode-styled-components 高亮。
* 运行时校验 CSS 语法,收集输出到缓存,供 flushCSS() 获取。
*/
export function css(strings: TemplateStringsArray, ...values: CSSInterpolation[]): string {
const result = strings.reduce((acc, s, i) => acc + s + String(values[i] ?? ""), "");
// 构建时校验 CSS 语法
transform({ filename: getCallerInfo(1), code: Buffer.from(result) });
cssCache.push(result);
return result;
}
/** 构建时一次性获取所有通过 css() 收集的 CSS */
export function flushCSS(): string {
const all = cssCache.join("\n");
cssCache.length = 0;
return all;
}
/** cssStyle 用于 css 模板字符串的插值
* 提取可复用的样式, 并保留 vanilla-extract 的类型检查
* - 属性访问:保留原值(如 style.padding → "0px 6px")
* - 字符串插值:自动输出 CSS 片段(如 `${style}` → "padding:0px 6px;")
*/
export function cssStyle<T extends SelectorStyleRule>(input: T): T & CSSObject {
const flat: Record<string, CSSPrimitive> = {};
const nested: Record<string, SelectorStyleRule> = {};
// Object.entries 对无索引签名的 StyleRule 只能返回 any/unknown,
// 这里做最小断言:entry 的值是 CSS 叶子值(string|number)或嵌套对象
for (const [key, val] of Object.entries(input) as [string, CSSPrimitive | SelectorStyleRule][]) {
if (val === null || val === undefined) continue;
if (typeof val === "object") {
nested[key] = cssStyle(val);
} else {
flat[key] = val;
}
}
// 构建 CSS 字符串
const cssParts: string[] = [];
if (Object.keys(flat).length > 0) {
cssParts.push(captureStyle(flat));
}
for (const [key, val] of Object.entries(nested)) {
cssParts.push(`${key}{${String(val)}}`);
}
const cssText = cssParts.join("");
input.toString = () => cssText;
return input as T & CSSObject;
}
+4
View File
@@ -17,6 +17,10 @@
* limitations under the License. * limitations under the License.
*/ */
export { createChroma } from "./chroma";
export { createCodeMirror } from "./codemirror";
export { css, cssStyle, flushCSS } from "./css";
export { createThemeMetaInfo, type ColorblindType, type GiteaThemeMeta } from "./meta";
export { createTheme, defineTheme } from "./theme"; export { createTheme, defineTheme } from "./theme";
export type { Theme, ThemeVars } from "./theme"; export type { Theme, ThemeVars } from "./theme";
export type { CSSVarFunction, MapLeafNodes } from "./types"; export type { CSSVarFunction, MapLeafNodes } from "./types";
File renamed without changes.
+15 -7
View File
@@ -18,13 +18,24 @@
*/ */
import { createGlobalTheme, globalKeyframes, globalStyle } from "@vanilla-extract/css"; import { createGlobalTheme, globalKeyframes, globalStyle } from "@vanilla-extract/css";
import pkg from "../../package.json";
import type { GiteaColor, GitHubColor, ThemeColor } from "../palette"; import type { GiteaColor, GitHubColor, ThemeColor } from "../palette";
import { gitea2ThemeVars, github2ThemeColor, primer2Chroma, primer2CodeMirror, theme2ThemeVars } from "../palette"; import { gitea2ThemeVars, github2ThemeColor, primer2Chroma, primer2CodeMirror, theme2ThemeVars } from "../palette";
import selectors from "../selectors"; import selectors from "../selectors";
import { createChroma, createCodeMirror } from "../styles";
import { otherThemeVars, syntaxVars, themeVars, type Syntax } from "../types"; import { otherThemeVars, syntaxVars, themeVars, type Syntax } from "../types";
import { createChroma } from "./chroma";
import { createCodeMirror } from "./codemirror";
import type { MapLeafNodes } from "./types"; import type { MapLeafNodes } from "./types";
function getThemeVersion(): string {
// 版本号: 版本号.YYMMDD
const now = new Date();
const year = now.getFullYear().toString().slice(-2);
const month = (now.getMonth() + 1).toString().padStart(2, "0");
const day = now.getDate().toString().padStart(2, "0");
return `${pkg.version}.${year}${month}${day}`;
}
export type ThemeVars = { isDarkTheme: boolean } & MapLeafNodes<typeof themeVars, string>; export type ThemeVars = { isDarkTheme: boolean } & MapLeafNodes<typeof themeVars, string>;
export type ThemeColors = export type ThemeColors =
| { colorType: "github"; themeColor: GitHubColor } | { colorType: "github"; themeColor: GitHubColor }
@@ -41,8 +52,8 @@ export type Theme = {
* - "theme": GiteaGitHubTheme 用于简化 Gitea 颜色变量设置的配色, 使用 Gitea 的代码语法高亮色 * - "theme": GiteaGitHubTheme 用于简化 Gitea 颜色变量设置的配色, 使用 Gitea 的代码语法高亮色
* *
* @example * @example
* import type { Console, Diff, Other, Github, ThemeColor, Syntax } from "@gitea-github-theme/core"; * import type { Console, Diff, Other, Github, ThemeColor, Syntax } from "@lutinglt/gitea-github-theme/core";
* import { defineTheme, themeVars } from "@gitea-github-theme/core"; * import { defineTheme, themeVars } from "@lutinglt/gitea-github-theme/core";
* *
* const console: Console = { * const console: Console = {
* fg: { * fg: {
@@ -77,9 +88,6 @@ export function defineTheme(themeColors: ThemeColors): Theme {
}; };
} }
// vite define 编译时注入的常量
declare const __THEME_VERSION__: string;
export function createTheme(theme: Theme): void { export function createTheme(theme: Theme): void {
const { isDarkTheme, ...themeVarsColor } = const { isDarkTheme, ...themeVarsColor } =
theme.colorType === "github" theme.colorType === "github"
@@ -90,7 +98,7 @@ export function createTheme(theme: Theme): void {
// 注入主题标识和版本号 // 注入主题标识和版本号
createGlobalTheme(selectors.root, { createGlobalTheme(selectors.root, {
theme: { version: `"${__THEME_VERSION__}"` }, theme: { version: `"${getThemeVersion()}"` },
is: { dark: { theme: isDarkTheme.toString() } }, is: { dark: { theme: isDarkTheme.toString() } },
}); });
// 全局主题变量 // 全局主题变量
-57
View File
@@ -1,57 +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 * as lightningcss from "lightningcss";
import type { CSSObject } from "./toCSS";
const sharedCacheKey = "__GITEA_GITHUB_THEME_CSS_CACHE__";
const g = globalThis as Record<string, unknown>;
const cssCache: string[] = (g[sharedCacheKey] as string[]) || (g[sharedCacheKey] = []);
type CSSInterpolation = string | number | boolean | CSSObject | undefined | null;
function getCallerInfo(): string {
const stack = new Error().stack?.split("\n") || [];
// stack[0] = "Error"
// stack[1] = " at getCallerInfo (css.ts:...)"
// stack[2] = " at css (css.ts:...)"
// stack[3] = " at <caller> (styles/components/heatmap.ts:23:18)" ← 目标
const frame = stack[3] || "";
const match = frame.match(/\((.+?):(\d+):(\d+)\)/) ?? frame.match(/at\s+(.+?):(\d+):(\d+)/);
return match ? `${match[1]}:${match[2]}` : frame.trim() || "unknown";
}
/**
* css 模板字符串 —— 类式 linaria 的 css tag,用于 vscode-styled-components 高亮。
* 运行时校验 CSS 语法,收集输出到缓存,供 flushCSS() 获取。
*/
export function css(strings: TemplateStringsArray, ...values: CSSInterpolation[]): string {
const result = strings.reduce((acc, s, i) => acc + s + String(values[i] ?? ""), "");
// 构建时校验 CSS 语法
lightningcss.transform({ filename: getCallerInfo(), code: Buffer.from(result) });
cssCache.push(result);
return result;
}
/** 构建时一次性获取所有通过 css() 收集的 CSS */
export function flushCSS(): string {
const all = cssCache.join("\n");
cssCache.length = 0;
return all;
}
+2 -5
View File
@@ -19,8 +19,7 @@
import selectors from "./selectors"; import selectors from "./selectors";
export { createTheme, defineTheme, type MapLeafNodes } from "./core"; export { css, cssStyle, defineTheme, type MapLeafNodes } from "./core";
export { css, flushCSS } from "./css";
export { extractVarName, scaleColorLight } from "./functions"; export { extractVarName, scaleColorLight } from "./functions";
export { export {
catppuccin2Syntax, catppuccin2Syntax,
@@ -30,10 +29,8 @@ export {
primer2GitHubColor, primer2GitHubColor,
} from "./palette"; } from "./palette";
export type { DisplayColor, GitHubColor, GiteaColor, ThemeColor } from "./palette"; export type { DisplayColor, GitHubColor, GiteaColor, ThemeColor } from "./palette";
export { createThemeMetaInfo } from "./styles";
export { toCSS } from "./toCSS";
export { chromaVars, customThemeVars, otherThemeVars, syntaxVars, themeVars } from "./types"; export { chromaVars, customThemeVars, otherThemeVars, syntaxVars, themeVars } from "./types";
export type { Ansi, Chroma, Console, Diff, GitHub, Message, Named, Other, Primary, Secondary, Syntax } from "./types"; export type { Ansi, Chroma, Console, Diff, GitHub, Message, Named, Other, Primary, Secondary, Syntax } from "./types";
export { deepOverride } from "./utils"; export { deepOverride } from "./utils";
export { defineThemeConfig } from "./vite-plugin"; export { defineThemeConfig } from "./vite-plugin/themeConfig";
export { selectors }; export { selectors };
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import type { Primer } from "@gitea-github-theme/primer"; import type { Primer } from "@lutinglt/gitea-github-theme/primer";
import { saturate } from "polished"; import { saturate } from "polished";
import { scaleColorLight } from "../functions"; import { scaleColorLight } from "../functions";
import { deepOverride } from "../utils"; import { deepOverride } from "../utils";
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import type { Primer } from "@gitea-github-theme/primer"; import type { Primer } from "@lutinglt/gitea-github-theme/primer";
import { mix, saturate } from "polished"; import { mix, saturate } from "polished";
import { scaleColorLight } from "../functions"; import { scaleColorLight } from "../functions";
import type { Ansi, Console, Diff, GitHub, Message, Other } from "../types"; import type { Ansi, Console, Diff, GitHub, Message, Other } from "../types";
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import type { Primer } from "@gitea-github-theme/primer"; import type { Primer } from "@lutinglt/gitea-github-theme/primer";
import type { Chroma, CodeMirror } from "../types"; import type { Chroma, CodeMirror } from "../types";
import { deepOverride } from "../utils"; import { deepOverride } from "../utils";
import type { GitHubColor } from "./github"; import type { GitHubColor } from "./github";
-22
View File
@@ -1,22 +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.
*/
export { createChroma } from "./chroma";
export { createCodeMirror } from "./codemirror";
export { createThemeMetaInfo, type ColorblindType, type GiteaThemeMeta } from "./meta";
-102
View File
@@ -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.
*/
import type { StyleRule } from "@vanilla-extract/css";
import { globalStyle } from "@vanilla-extract/css";
import { removeAdapter, setAdapter } from "@vanilla-extract/css/adapter";
import { endFileScope, setFileScope } from "@vanilla-extract/css/fileScope";
import { transformCss } from "@vanilla-extract/css/transformCss";
/** 使用 vanilla-extract 适配器序列化一个扁平 StyleRule 为 CSS 属性行 */
function captureStyleRule(style: StyleRule): string {
const captured: unknown[] = [];
setAdapter({
appendCss: css => captured.push(css),
registerClassName: () => {},
registerComposition: () => {},
markCompositionUsed: () => {},
onEndFileScope: () => {},
getIdentOption: () => "short",
});
setFileScope("");
globalStyle("_x", style);
endFileScope();
removeAdapter();
const css = transformCss({
localClassNames: [],
composedClassLists: [],
cssObjs: captured as Parameters<typeof transformCss>[0]["cssObjs"],
}).join("");
// 去掉 "_x { ... }" 外壳,只留内部属性
const inner = css
.replace(/^_x\s*\{/, "")
.replace(/\}\s*$/, "")
.trim();
return inner ? inner + ";" : "";
}
// ─── toCSS ──────────────────────────────────────────────
type SelectorStyleRule = {
[key: string]: StyleRule | SelectorStyleRule;
};
type SelectorsStyleRule = StyleRule | SelectorStyleRule;
declare const CSSBrand: unique symbol;
export type CSSObject = { [CSSBrand]: true };
/**
* 将 SelectorsStyleRule 转为可复用的对象:
* - 属性访问:保留原值(如 style.padding → "0px 6px")
* - 字符串插值:自动输出 CSS 片段(如 `${style}` → "padding:0px 6px;")
*/
export function toCSS<T extends SelectorsStyleRule>(input: T): T & CSSObject {
const flat: Record<string, string | number> = {};
const nested: Record<string, SelectorsStyleRule> = {};
// Object.entries 对无索引签名的 StyleRule 只能返回 any/unknown,
// 这里做最小断言:entry 的值是 CSS 叶子值(string|number)或嵌套对象
for (const [key, val] of Object.entries(input) as [string, string | number | SelectorsStyleRule][]) {
if (val === null || val === undefined) continue;
if (typeof val === "object") {
nested[key] = toCSS(val);
} else {
flat[key] = val;
}
}
// 构建 CSS 字符串
const cssParts: string[] = [];
if (Object.keys(flat).length > 0) {
cssParts.push(captureStyleRule(flat));
}
for (const [key, val] of Object.entries(nested)) {
cssParts.push(`${key}{${String(val)}}`);
}
const cssText = cssParts.join("");
input.toString = () => cssText;
return input as T & CSSObject;
}
+23
View File
@@ -32,3 +32,26 @@ export function deepOverride<T extends object>(target: T, patch: DeepPartial<T>)
} }
return result; return result;
} }
/**
* 从调用堆栈中获取调用者信息(文件名:行号)。
*
* 堆栈帧结构(0-based):
* stack[0] = "Error"
* stack[1] = getCallerInfo 自身 ← 始终跳过
* stack[2] = 直接调用者 ← skipFrames=0 时返回此行
* stack[3] = 上层调用者 ← skipFrames=1 时返回此行
* ...
*
* 每层中间函数由调用方自行声明需要跳过的帧数,
* 而非将调用深度硬编码在此函数中。
*
* @param skipFrames 额外跳过的帧数(默认 0:返回直接调用者)
* @returns 格式 "path/file:line",无法解析时返回 "unknown"
*/
export function getCallerInfo(skipFrames: number = 0): string {
const stack = new Error().stack?.split("\n") || [];
const index = 2 + skipFrames;
const frame = stack[index] || stack[stack.length - 1] || "";
const match = frame.match(/\((.+?):(\d+):(\d+)\)/) ?? frame.match(/at\s+(.+?):(\d+):(\d+)/);
return match ? `${match[1]}:${match[2]}` : frame.trim() || "unknown";
}
+69
View File
@@ -0,0 +1,69 @@
/*!
* 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 type { StyleRule } from "@vanilla-extract/css";
import { globalStyle } from "@vanilla-extract/css";
import { removeAdapter, setAdapter } from "@vanilla-extract/css/adapter";
import { endFileScope, setFileScope } from "@vanilla-extract/css/fileScope";
import { transformCss } from "@vanilla-extract/css/transformCss";
import { getCallerInfo } from "./utils";
type CSS = Parameters<typeof transformCss>[0]["cssObjs"][number];
type Composition = Parameters<typeof transformCss>[0]["composedClassLists"][number];
/** 执行 vanilla-extract API 并序列化为 CSS 字符串 */
export function compileCSS(compileFn: () => void): string {
const capturedCssObjs: CSS[] = [];
const localClassNames = new Set<string>();
const composedClassLists: Composition[] = [];
setAdapter({
appendCss: css => capturedCssObjs.push(css),
registerClassName: className => localClassNames.add(className),
registerComposition: composition => composedClassLists.push(composition),
markCompositionUsed: () => {},
onEndFileScope: () => {},
getIdentOption:
() =>
({ debugId }) =>
`${debugId}`,
});
setFileScope(getCallerInfo(1));
compileFn();
endFileScope();
removeAdapter();
return transformCss({
localClassNames: Array.from(localClassNames),
composedClassLists,
cssObjs: capturedCssObjs,
}).join("\n");
}
/** 使用 vanilla-extract 适配器序列化一个扁平 StyleRule 为 CSS 属性行 */
export function captureStyle(style: StyleRule): string {
const css = compileCSS(() => globalStyle("_CAPTURED_STYLE", style));
const inner = css
.replace(/^_CAPTURED_STYLE\s*\{/, "")
.replace(/\}\s*$/, "")
.trim();
return inner ? inner + ";" : "";
}
-325
View File
@@ -1,325 +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 { removeAdapter, setAdapter } from "@vanilla-extract/css/adapter";
import { endFileScope, setFileScope } from "@vanilla-extract/css/fileScope";
import { transformCss } from "@vanilla-extract/css/transformCss";
import * as lightningcss from "lightningcss";
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 { PluginOption } from "vite";
import type { Theme } from "./core";
import { createTheme } from "./core";
import { flushCSS } from "./css";
import type { ColorblindType, GiteaThemeMeta } from "./styles";
import { createThemeMetaInfo } from "./styles";
interface Composition {
identifier: string;
classList: string;
}
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 其中一个, 如果 dark & light 都声明了, 会生成自动颜色主题 */
themes: Themes;
};
/** 定义主题配置 */
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;
}
/** 使用 Vanilla Extract 的 adapter + transformCss 在 Node.js 中编译主题 CSS */
function compileThemeCSS(compileFn: () => void): string {
const capturedCssObjs: Parameters<typeof transformCss>[0]["cssObjs"] = [];
const localClassNames = new Set<string>();
const composedClassLists: Composition[] = [];
setAdapter({
appendCss: css => capturedCssObjs.push(css),
registerClassName: className => localClassNames.add(className),
registerComposition: composition => composedClassLists.push(composition),
markCompositionUsed: () => {},
onEndFileScope: () => {},
getIdentOption:
() =>
({ debugId }) =>
`${debugId}`,
});
setFileScope("theme.css.ts");
compileFn();
endFileScope();
removeAdapter();
return transformCss({
localClassNames: Array.from(localClassNames),
composedClassLists,
cssObjs: capturedCssObjs,
}).join("\n");
}
/** Gitea GitHub Theme 主题插件: 解析入口文件, 生成主题 */
export function giteaGitHubThemePlugin(): PluginOption {
const PLUGIN_NAME = "GiteaGitHubThemePlugin";
const PREFIX = "theme-github-";
let themeEntries: ThemeEntry[];
const autoThemeEntries = new Map<string, AutoThemeEntry>();
let themeVersion = "";
let styles = "";
return {
name: PLUGIN_NAME,
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);
// 提取 __THEME_VERSION__ 定义, 用于后续在 Node.js 中编译主题时注入
const themeVersionDefine = userConfig.define?.__THEME_VERSION__;
if (typeof themeVersionDefine === "string") {
themeVersion = JSON.parse(themeVersionDefine);
}
// 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<string, string> = {};
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(`[${PLUGIN_NAME}] 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 !== "default" ? `${themeSeries.themeSeriesName}-` : ""}${themeName}`;
}
/** 辅助函数: 将显示名称转为正式名称 */
function buildFullDisplayName(themeSeries: ThemeSeries, displayName: string): string {
return `GitHub ${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. 解析自动主题条目
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,
};
autoThemeEntries.set(themeName, {
darkThemeName: themeSeries.themes.dark.themeName!,
lightThemeName: themeSeries.themes.light.themeName!,
});
// 将自动主题也加入 themeEntries 以便编译 CSS
themeEntries.push({ themeName, meta, theme: null as unknown as Theme });
}
}
// 6. 编译公共样式 (替代 wyw-in-js)
// 使用 jiti 直接执行源文件,无需 rolldown 打包,避免 tree-shaking
const { createJiti } = await import("jiti");
const jitiInstance = createJiti(import.meta.url, {
alias: resolveAlias,
});
await jitiInstance.import(path.join(root, "styles/index.ts"));
const rawStyles = flushCSS();
// LightningCSS 展开嵌套 + 压缩
styles = lightningcss
.transform({
filename: "styles.css",
code: Buffer.from(rawStyles),
targets: { chrome: 100 << 16 },
minify: true,
})
.code.toString();
// 7. 提供占位入口,Vite 需要至少一个输入才会触发 generateBundle
const placeholder = path.join(tmpDir, "_placeholder.js");
fs.writeFileSync(placeholder, "// placeholder\n");
return { build: { rollupOptions: { input: placeholder } } };
},
generateBundle(this, _options, bundle) {
// 清除占位入口产物
for (const key of Object.keys(bundle)) {
delete bundle[key];
}
// 注入 __THEME_VERSION__ 全局变量, createTheme 中使用
(globalThis as Record<string, unknown>).__THEME_VERSION__ = themeVersion;
// 编译每个主题的 CSS 并输出
for (const entry of themeEntries) {
const { themeName, meta } = entry;
const autoTheme = autoThemeEntries.get(themeName);
let themeCSS = compileThemeCSS(() => {
createThemeMetaInfo(meta);
// 自动主题不需要颜色变量, 只有 metaInfo
if (!autoTheme) {
createTheme(entry.theme);
}
});
themeCSS = lightningcss
.transform({ filename: themeName + ".css", code: Buffer.from(themeCSS), minify: true })
.code.toString();
const source = autoTheme
? [
`@import "./${autoTheme.darkThemeName}.css" (prefers-color-scheme: dark);`,
`@import "./${autoTheme.lightThemeName}.css" (prefers-color-scheme: light);`,
themeCSS,
].join("\n")
: `${themeCSS}${styles}`;
this.emitFile({
type: "asset",
fileName: `${themeName}.css`,
source,
});
}
// 清理全局变量
delete (globalThis as Record<string, unknown>).__THEME_VERSION__;
},
};
}
+131
View File
@@ -0,0 +1,131 @@
/*!
* 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 { transform } from "lightningcss";
import fs from "node:fs";
import path from "node:path";
import type { PluginOption } from "vite";
import type { GiteaThemeMeta, Theme } from "../core";
import { createTheme, createThemeMetaInfo } from "../core";
import { flushCSS } from "../core/css";
import { compileCSS } from "../vanilla-extract";
import { buildFullDisplayName, buildFullThemeName } from "./utils";
type ThemeEntry = { themeName: string; meta: GiteaThemeMeta; theme: Theme };
type AutoThemeEntry = { darkThemeName: string; lightThemeName: string };
export function giteaGitHubTheme(): PluginOption {
const themeEntries = new Array<ThemeEntry>();
const autoThemeEntries = new Map<string, AutoThemeEntry>();
return {
name: "lutinglt-gitea-github-theme",
async config(userConfig) {
// 1. 动态导入 theme.config.ts(Bun 原生 TS + exports 自引用)
const themeConfig = (await import("@lutinglt/gitea-github-theme/theme.config.ts")).default;
// 2. 解析主题条目
for (const themeSeries of themeConfig) {
for (const [themeKeyName, entry] of Object.entries(themeSeries.themes)) {
const name = entry.themeName ?? themeKeyName;
// 直接修改主题名用于自动主题生成使用, 避免重复计算
entry.themeName = buildFullThemeName(themeSeries, name);
themeEntries.push({
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,
});
}
}
// 3. 解析自动主题条目
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,
};
autoThemeEntries.set(themeName, {
darkThemeName: themeSeries.themes.dark.themeName!,
lightThemeName: themeSeries.themes.light.themeName!,
});
// 将自动主题也加入 themeEntries 以便编译 CSS
themeEntries.push({ themeName, meta, theme: null as unknown as Theme });
}
}
// 4. 提供占位入口,Vite 需要至少一个输入才会触发 generateBundle
const outDir = userConfig.build?.outDir || "dist";
const placeholder = path.join(outDir, "_placeholder.js");
fs.mkdirSync(outDir, { recursive: true });
fs.writeFileSync(placeholder, "// placeholder\n");
return { build: { outDir, rolldownOptions: { input: placeholder } } };
},
async generateBundle(this, _options, bundle) {
// 清除占位入口产物
for (const key of Object.keys(bundle)) {
delete bundle[key];
}
// 1. 编译公共样式 (替代 wyw-in-js)
// Bun 原生 TS + exports 自引用,导入即触发所有 css() 副作用
await import("@lutinglt/gitea-github-theme/styles");
const rawStyles = Buffer.from(flushCSS());
const styles = transform({ filename: "styles.css", code: rawStyles, minify: true }).code.toString();
// 编译每个主题的 CSS 并输出
for (const entry of themeEntries) {
const { themeName, meta } = entry;
const autoTheme = autoThemeEntries.get(themeName);
const rawThemeCSS = Buffer.from(
compileCSS(() => {
createThemeMetaInfo(meta);
// 自动主题不需要颜色变量, 只有 metaInfo
if (!autoTheme) createTheme(entry.theme);
})
);
const themeCSS = transform({ filename: themeName + ".css", code: rawThemeCSS, minify: true }).code.toString();
const source = autoTheme
? [
`@import "./${autoTheme.darkThemeName}.css" (prefers-color-scheme: dark);`,
`@import "./${autoTheme.lightThemeName}.css" (prefers-color-scheme: light);`,
themeCSS,
].join("\n")
: `${themeCSS}${styles}`;
this.emitFile({
type: "asset",
fileName: `${themeName}.css`,
source,
});
}
},
};
}
+68
View File
@@ -0,0 +1,68 @@
/*!
* 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 type { ColorblindType, Theme } from "../core";
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;
};
export type ThemeSeries = {
/** 主题系列名称, 做为前缀用于生成文件名和显示名称 */
themeSeriesName: string;
/** 主题系列自动颜色主题配置 */
autoTheme?: {
/** 自动颜色主题用于 Gitea UI 显示的名称 */
displayName?: string;
/** 色盲类型, 仅用于声明主题为色盲主题 */
colorblindType?: ColorblindType;
};
/** 必须至少声明 dark/light 其中一个, 如果 dark & light 都声明了, 会生成自动颜色主题 */
themes: Themes;
};
/** 定义主题配置 */
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;
}
+36
View File
@@ -0,0 +1,36 @@
/*!
* 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 type { ThemeSeries } from "./themeConfig";
/** 按 "-" 分割字符串并首字母大写 */
function kebabToTitle(str: string): string {
return str
.split("-")
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ");
}
/** 将主题名称转为正式主题名称 */
export function buildFullThemeName(themeSeries: ThemeSeries, themeName: string): string {
return `theme-github-${themeSeries.themeSeriesName !== "default" ? `${themeSeries.themeSeriesName}-` : ""}${themeName}`;
}
/** 将显示名称转为正式名称 */
export function buildFullDisplayName(themeSeries: ThemeSeries, displayName: string): string {
return `GitHub ${kebabToTitle(themeSeries.themeSeriesName)} ${kebabToTitle(displayName)}`;
}
+2 -2
View File
@@ -17,12 +17,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { otherThemeVars, themeVars, toCSS } from "@gitea-github-theme/core"; import { cssStyle, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
/** 激活项后缀样式 /** 激活项后缀样式
* @example 菜单激活子项前面的竖线, 方便识别 * @example 菜单激活子项前面的竖线, 方便识别
*/ */
export const activeItemAfterStyle = toCSS({ export const activeItemAfterStyle = cssStyle({
content: `""`, content: `""`,
backgroundColor: themeVars.github.borderColor.accent.emphasis, backgroundColor: themeVars.github.borderColor.accent.emphasis,
borderRadius: otherThemeVars.border.radius, borderRadius: otherThemeVars.border.radius,
+4 -4
View File
@@ -17,10 +17,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { selectors, toCSS } from "@gitea-github-theme/core"; import { cssStyle, selectors } from "@lutinglt/gitea-github-theme/core";
// 出现动画 // 出现动画
export const animation = toCSS({ export const animation = cssStyle({
animation: selectors.overlayAppear, animation: selectors.overlayAppear,
animationDuration: "80ms", animationDuration: "80ms",
animationFillMode: "forwards", animationFillMode: "forwards",
@@ -28,14 +28,14 @@ export const animation = toCSS({
}); });
// 向下出现动画 // 向下出现动画
export const animationDown = toCSS({ export const animationDown = cssStyle({
animation: selectors.overlayAppearDown, animation: selectors.overlayAppearDown,
animationDuration: "200ms", animationDuration: "200ms",
animationTimingFunction: "cubic-bezier(0.33, 1, 0.68, 1)", animationTimingFunction: "cubic-bezier(0.33, 1, 0.68, 1)",
}); });
// 向上出现动画 // 向上出现动画
export const animationUp = toCSS({ export const animationUp = cssStyle({
animation: selectors.overlayAppearUp, animation: selectors.overlayAppearUp,
animationDuration: "200ms", animationDuration: "200ms",
animationTimingFunction: "cubic-bezier(0.33, 1, 0.68, 1)", animationTimingFunction: "cubic-bezier(0.33, 1, 0.68, 1)",
+3 -3
View File
@@ -17,10 +17,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { themeVars, toCSS } from "@gitea-github-theme/core"; import { cssStyle, themeVars } from "@lutinglt/gitea-github-theme/core";
/** 主色调按钮样式 */ /** 主色调按钮样式 */
export const primaryButtonStyle = toCSS({ export const primaryButtonStyle = cssStyle({
color: themeVars.github.button.primary.fgColor.rest, color: themeVars.github.button.primary.fgColor.rest,
backgroundColor: themeVars.github.button.primary.bgColor.rest, backgroundColor: themeVars.github.button.primary.bgColor.rest,
borderColor: themeVars.github.button.primary.borderColor.rest, borderColor: themeVars.github.button.primary.borderColor.rest,
@@ -28,7 +28,7 @@ export const primaryButtonStyle = toCSS({
}); });
/** 主色调按钮悬停样式 */ /** 主色调按钮悬停样式 */
export const primaryButtonHoverStyle = toCSS({ export const primaryButtonHoverStyle = cssStyle({
color: themeVars.github.button.primary.fgColor.rest, color: themeVars.github.button.primary.fgColor.rest,
backgroundColor: themeVars.github.button.primary.bgColor.hover, backgroundColor: themeVars.github.button.primary.bgColor.hover,
borderColor: themeVars.github.button.primary.borderColor.hover, borderColor: themeVars.github.button.primary.borderColor.hover,
+2 -2
View File
@@ -17,9 +17,9 @@
* limitations under the License. * limitations under the License.
*/ */
import { themeVars, toCSS } from "@gitea-github-theme/core"; import { cssStyle, themeVars } from "@lutinglt/gitea-github-theme/core";
export const deleteHoverActiveStyle = toCSS({ export const deleteHoverActiveStyle = cssStyle({
"&:hover": { "&:hover": {
backgroundColor: `${themeVars.github.control.danger.bgColor.hover} !important`, backgroundColor: `${themeVars.github.control.danger.bgColor.hover} !important`,
color: `${themeVars.github.control.danger.fgColor.hover} !important`, color: `${themeVars.github.control.danger.fgColor.hover} !important`,
+3 -3
View File
@@ -17,15 +17,15 @@
* limitations under the License. * limitations under the License.
*/ */
import { toCSS } from "@gitea-github-theme/core"; import { cssStyle } from "@lutinglt/gitea-github-theme/core";
/** 基本标签样式 */ /** 基本标签样式 */
export const labelStyle = toCSS({ export const labelStyle = cssStyle({
padding: "0px 6px", padding: "0px 6px",
}); });
/** bot 标签样式 */ /** bot 标签样式 */
export const botLabelStyle = toCSS({ export const botLabelStyle = cssStyle({
height: "20px", height: "20px",
padding: "0 6px !important", padding: "0 6px !important",
marginLeft: "4px", marginLeft: "4px",
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
// 修改 action 页面 svg 颜色 (主要为了覆盖工作流状态中的白色图标) // 修改 action 页面 svg 颜色 (主要为了覆盖工作流状态中的白色图标)
export const actionSVG = css` export const actionSVG = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
// 仓库 Actions 页面 // 仓库 Actions 页面
export const actions = css` export const actions = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
// 工作流详情页标题 // 工作流详情页标题
export const actionViewHeader = css` export const actionViewHeader = css`
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
import { animationDown } from "@gitea-github-theme/styles/common"; import { animationDown } from "@lutinglt/gitea-github-theme/styles/common";
// 工作流右侧作业步骤日志详情 // 工作流右侧作业步骤日志详情
export const actionViewRight = css` export const actionViewRight = css`
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
export const summaryView = css` export const summaryView = css`
.action-view-right:has(.action-run-summary-view) { .action-view-right:has(.action-run-summary-view) {
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { labelStyle } from "@gitea-github-theme/styles/common"; import { labelStyle } from "@lutinglt/gitea-github-theme/styles/common";
export const dashboard = css` export const dashboard = css`
.page-content.dashboard { .page-content.dashboard {
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, customThemeVars, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, customThemeVars, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { fallbackVar } from "@vanilla-extract/css"; import { fallbackVar } from "@vanilla-extract/css";
const userRepoVar = fallbackVar(customThemeVars.userRepolistColumns, "2"); const userRepoVar = fallbackVar(customThemeVars.userRepolistColumns, "2");
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
export const footer = css` export const footer = css`
.page-footer { .page-footer {
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
export const heatmap = css` export const heatmap = css`
#user-heatmap { #user-heatmap {
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { activeItemAfterStyle } from "@gitea-github-theme/styles/common"; import { activeItemAfterStyle } from "@lutinglt/gitea-github-theme/styles/common";
export const button = css` export const button = css`
/* 工单&PR标题右侧按钮 */ /* 工单&PR标题右侧按钮 */
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { botLabelStyle, deleteHoverActiveStyle } from "@gitea-github-theme/styles/common"; import { botLabelStyle, deleteHoverActiveStyle } from "@lutinglt/gitea-github-theme/styles/common";
// 评论 // 评论
export const comment = css` export const comment = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, extractVarName, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, extractVarName, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
// 工单&PR 列表 // 工单&PR 列表
export const issueList = css` export const issueList = css`
+3 -3
View File
@@ -17,10 +17,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars, toCSS } from "@gitea-github-theme/core"; import { css, cssStyle, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { deleteHoverActiveStyle } from "@gitea-github-theme/styles/common"; import { deleteHoverActiveStyle } from "@lutinglt/gitea-github-theme/styles/common";
const sidebarPadding = toCSS({ const sidebarPadding = cssStyle({
padding: "4px 8px", padding: "4px 8px",
}); });
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
import { botLabelStyle } from "@gitea-github-theme/styles/common"; import { botLabelStyle } from "@lutinglt/gitea-github-theme/styles/common";
// 时间线 // 时间线
export const timeline = css` export const timeline = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, customThemeVars, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, customThemeVars, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { fallbackVar } from "@vanilla-extract/css"; import { fallbackVar } from "@vanilla-extract/css";
export const navbarRight = css` export const navbarRight = css`
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css } from "@gitea-github-theme/core"; import { css } from "@lutinglt/gitea-github-theme/core";
import { activeItemAfterStyle } from "@gitea-github-theme/styles/common"; import { activeItemAfterStyle } from "@lutinglt/gitea-github-theme/styles/common";
// 新建仓库页面下拉菜单 // 新建仓库页面下拉菜单
export const newRepo = css` export const newRepo = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
// 用户订阅/关注页面 // 用户订阅/关注页面
export const notification = css` export const notification = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
export const org = css` export const org = css`
.page-content.organization { .page-content.organization {
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, customThemeVars, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, customThemeVars, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
// 克隆按钮的弹窗 // 克隆按钮的弹窗
export const clone = css` export const clone = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
// 提交列表 // 提交列表
export const commit = css` export const commit = css`
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { activeItemAfterStyle } from "@gitea-github-theme/styles/common"; import { activeItemAfterStyle } from "@lutinglt/gitea-github-theme/styles/common";
export const diff = css` export const diff = css`
/* 这里的折叠行和代码行高度与 GitHub 的 release 和 review 的差异对比时的高度一致, 不需要像 commit 中的差异对比那样行高过高 */ /* 这里的折叠行和代码行高度与 GitHub 的 release 和 review 的差异对比时的高度一致, 不需要像 commit 中的差异对比那样行高过高 */
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
export const milestone = css` export const milestone = css`
/* 里程碑头部 */ /* 里程碑头部 */
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
// 组织/仓库的软件包列表(包含用户但未测试) // 组织/仓库的软件包列表(包含用户但未测试)
export const packagesList = css` export const packagesList = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
// release 顶部栏左侧按钮组 // release 顶部栏左侧按钮组
export const releaseTagMenu = css` export const releaseTagMenu = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
// 仓库头信息 // 仓库头信息
export const repoHeader = css` export const repoHeader = css`
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { activeItemAfterStyle, deleteHoverActiveStyle } from "@gitea-github-theme/styles/common"; import { activeItemAfterStyle, deleteHoverActiveStyle } from "@lutinglt/gitea-github-theme/styles/common";
// 仓库打开文件时的视图 // 仓库打开文件时的视图
export const repoFileView = css` export const repoFileView = css`
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { animationDown } from "@gitea-github-theme/styles/common"; import { animationDown } from "@lutinglt/gitea-github-theme/styles/common";
// 文件列表页面下的分支按钮 // 文件列表页面下的分支按钮
export const branchButton = css` export const branchButton = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
// 仓库代码布局调整, 侧边栏宽度调整 // 仓库代码布局调整, 侧边栏宽度调整
export const repoGrid = css` export const repoGrid = css`
+4 -4
View File
@@ -17,16 +17,16 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars, toCSS } from "@gitea-github-theme/core"; import { css, cssStyle, themeVars } from "@lutinglt/gitea-github-theme/core";
import { primaryButtonHoverStyle, primaryButtonStyle } from "@gitea-github-theme/styles/common"; import { primaryButtonHoverStyle, primaryButtonStyle } from "@lutinglt/gitea-github-theme/styles/common";
const tinyStyle = toCSS({ const tinyStyle = cssStyle({
color: themeVars.github.themeExtra.button.primary.fgColor.accent, color: themeVars.github.themeExtra.button.primary.fgColor.accent,
backgroundColor: themeVars.color.button, backgroundColor: themeVars.color.button,
borderColor: themeVars.color.light.border, borderColor: themeVars.color.light.border,
}); });
const tinyHoverStyle = toCSS({ const tinyHoverStyle = cssStyle({
color: themeVars.github.button.primary.fgColor.rest, color: themeVars.github.button.primary.fgColor.rest,
backgroundColor: themeVars.github.button.primary.bgColor.hover, backgroundColor: themeVars.github.button.primary.bgColor.hover,
borderColor: themeVars.github.button.primary.borderColor.hover, borderColor: themeVars.github.button.primary.borderColor.hover,
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css } from "@gitea-github-theme/core"; import { css } from "@lutinglt/gitea-github-theme/core";
// 注册/登录界面 // 注册/登录界面
export const signIn = css` export const signIn = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
// 用户点星仓库列表 // 用户点星仓库列表
export const stars = css` export const stars = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
export const attached = css` export const attached = css`
/* 设置右面板的内容 */ /* 设置右面板的内容 */
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css } from "@gitea-github-theme/core"; import { css } from "@lutinglt/gitea-github-theme/core";
export const body = css` export const body = css`
body { body {
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
import { primaryButtonHoverStyle, primaryButtonStyle } from "@gitea-github-theme/styles/common"; import { primaryButtonHoverStyle, primaryButtonStyle } from "@lutinglt/gitea-github-theme/styles/common";
// 普通按钮和主色调按钮 // 普通按钮和主色调按钮
export const baseButton = css` export const baseButton = css`
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, customThemeVars, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, customThemeVars, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { animationDown } from "@gitea-github-theme/styles/common"; import { animationDown } from "@lutinglt/gitea-github-theme/styles/common";
import { fallbackVar } from "@vanilla-extract/css"; import { fallbackVar } from "@vanilla-extract/css";
// 分支菜单 // 分支菜单
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { activeItemAfterStyle, animationDown, animationUp } from "@gitea-github-theme/styles/common"; import { activeItemAfterStyle, animationDown, animationUp } from "@lutinglt/gitea-github-theme/styles/common";
export const dropdown = css` export const dropdown = css`
.ui.dropdown, .ui.dropdown,
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
// 包含表情的下拉菜单 // 包含表情的下拉菜单
export const emojiDropdown = css` export const emojiDropdown = css`
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { activeItemAfterStyle } from "@gitea-github-theme/styles/common"; import { activeItemAfterStyle } from "@lutinglt/gitea-github-theme/styles/common";
// 选择框的下拉菜单看起来像普通按钮 // 选择框的下拉菜单看起来像普通按钮
export const selectionDropdown = css` export const selectionDropdown = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
export const input = css` export const input = css`
textarea, textarea,
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
import { labelStyle } from "@gitea-github-theme/styles/common"; import { labelStyle } from "@lutinglt/gitea-github-theme/styles/common";
export const label = css` export const label = css`
.ui.label { .ui.label {
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
// 仓库标签 (私有/公开/内部) // 仓库标签 (私有/公开/内部)
export const repoLabel = css` export const repoLabel = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
// 提交中的 SHA 标签 // 提交中的 SHA 标签
export const shaLabel = css` export const shaLabel = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
// 任务状态标签, 目前仅在管理员页面 Runner 状态中看到 // 任务状态标签, 目前仅在管理员页面 Runner 状态中看到
export const taskStatusLabel = css` export const taskStatusLabel = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
// 单行双选项菜单 // 单行双选项菜单
export const smallCompactMenu = css` export const smallCompactMenu = css`
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
import { labelStyle } from "@gitea-github-theme/styles/common"; import { labelStyle } from "@lutinglt/gitea-github-theme/styles/common";
export const menu = css` export const menu = css`
.ui.menu { .ui.menu {
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
// 分页菜单 // 分页菜单
export const paginationMenu = css` export const paginationMenu = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
export const secondaryMenu = css` export const secondaryMenu = css`
/* 二级菜单, 比如 Issue/PR/Actions 的筛选菜单 */ /* 二级菜单, 比如 Issue/PR/Actions 的筛选菜单 */
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { activeItemAfterStyle } from "@gitea-github-theme/styles/common"; import { activeItemAfterStyle } from "@lutinglt/gitea-github-theme/styles/common";
export const verticalMenu = css` export const verticalMenu = css`
/* 垂直菜单, 用于左侧边栏 */ /* 垂直菜单, 用于左侧边栏 */
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
import { animationDown } from "@gitea-github-theme/styles/common"; import { animationDown } from "@lutinglt/gitea-github-theme/styles/common";
export const modal = css` export const modal = css`
.ui.modal { .ui.modal {
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
export const text = css` export const text = css`
/* 默认颜色是 --color-text-light, 主题下此颜色是亮白色, 修改为灰色 */ /* 默认颜色是 --color-text-light, 主题下此颜色是亮白色, 修改为灰色 */
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars } from "@lutinglt/gitea-github-theme/core";
// 全部圆角替换 // 全部圆角替换
export const radius = css` export const radius = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, themeVars } from "@gitea-github-theme/core"; import { css, themeVars } from "@lutinglt/gitea-github-theme/core";
export const table = css` export const table = css`
.ui.table > tr > td, .ui.table > tr > td,
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
import { animation, animationDown } from "@gitea-github-theme/styles/common"; import { animation, animationDown } from "@lutinglt/gitea-github-theme/styles/common";
// 一些界面内的提示框, 比如克隆按钮, PR信息, Runner信息 等 // 一些界面内的提示框, 比如克隆按钮, PR信息, Runner信息 等
export const tippyBox = css` export const tippyBox = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css } from "@gitea-github-theme/core"; import { css } from "@lutinglt/gitea-github-theme/core";
// 简单的渐变过渡 // 简单的渐变过渡
export const transition = css` export const transition = css`
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
export const commitSignBadge = css` export const commitSignBadge = css`
a.ui.label.commit-id-short.gitea-github-theme-commit-sha { a.ui.label.commit-id-short.gitea-github-theme-commit-sha {
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
const primary = "primary" as const; const primary = "primary" as const;
const secondary = "secondary" as const; const secondary = "secondary" as const;
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
export const repoButtonRow = css` export const repoButtonRow = css`
.gitea-github-theme-templates { .gitea-github-theme-templates {
+1 -1
View File
@@ -17,7 +17,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { css, otherThemeVars, themeVars } from "@gitea-github-theme/core"; import { css, otherThemeVars, themeVars } from "@lutinglt/gitea-github-theme/core";
export const repoFileLastCommit = css` export const repoFileLastCommit = css`
/* 仓库页和文件列表文件夹页的最后一次提交 */ /* 仓库页和文件列表文件夹页的最后一次提交 */
+2 -2
View File
@@ -17,8 +17,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { defineThemeConfig } from "@gitea-github-theme/core"; import { defineThemeConfig } from "@lutinglt/gitea-github-theme/core";
import themes from "@gitea-github-theme/themes"; import themes from "@lutinglt/gitea-github-theme/themes";
export default defineThemeConfig([ export default defineThemeConfig([
{ {
+1 -1
View File
@@ -22,7 +22,7 @@
*/ */
import { flavors, type CatppuccinFlavor } from "@catppuccin/palette"; import { flavors, type CatppuccinFlavor } from "@catppuccin/palette";
import { catppuccin2Syntax, catppuccin2ThemeColor, defineTheme } from "@gitea-github-theme/core"; import { catppuccin2Syntax, catppuccin2ThemeColor, defineTheme } from "@lutinglt/gitea-github-theme/core";
function defineCatppuccinTheme(flavor: CatppuccinFlavor) { function defineCatppuccinTheme(flavor: CatppuccinFlavor) {
return defineTheme({ return defineTheme({
+2 -2
View File
@@ -32,8 +32,8 @@ import type {
Primary, Primary,
Secondary, Secondary,
Syntax, Syntax,
} from "@gitea-github-theme/core"; } from "@lutinglt/gitea-github-theme/core";
import { defineTheme, themeVars } from "@gitea-github-theme/core"; import { defineTheme, themeVars } from "@lutinglt/gitea-github-theme/core";
const primary: Primary = { const primary: Primary = {
self: "#4183c4", self: "#4183c4",
+2 -2
View File
@@ -32,8 +32,8 @@ import type {
Primary, Primary,
Secondary, Secondary,
Syntax, Syntax,
} from "@gitea-github-theme/core"; } from "@lutinglt/gitea-github-theme/core";
import { defineTheme, themeVars } from "@gitea-github-theme/core"; import { defineTheme, themeVars } from "@lutinglt/gitea-github-theme/core";
const primary: Primary = { const primary: Primary = {
self: "#4183c4", self: "#4183c4",
+3 -3
View File
@@ -21,9 +21,9 @@
* @author lutinglt * @author lutinglt
*/ */
import type { GitHubColor } from "@gitea-github-theme/core"; import type { GitHubColor } from "@lutinglt/gitea-github-theme/core";
import { deepOverride, defineTheme, display2GitHubColor, primer2GitHubColor } from "@gitea-github-theme/core"; import { deepOverride, defineTheme, display2GitHubColor, primer2GitHubColor } from "@lutinglt/gitea-github-theme/core";
import { default as primer } from "@gitea-github-theme/primer"; import { default as primer } from "@lutinglt/gitea-github-theme/primer";
/** - 仅适用于 Dark 主题的颜色转换 */ /** - 仅适用于 Dark 主题的颜色转换 */
function darkConvert(color: GitHubColor) { function darkConvert(color: GitHubColor) {
Loaded 100 of 102 files, more files were not shown because too many files have changed in this diff. Show more