mirror of
https://github.com/lutinglt/gitea-github-theme.git
synced 2026-10-28 09:44:55 +00:00
nodejs -> bun
This commit is contained in:
102 files changed
+611
-708
No files matched your search
Vendored
+5
-5
@@ -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'
|
||||||
|
|||||||
Vendored
+4
-4
@@ -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 \
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
dist
|
dist
|
||||||
node_modules
|
node_modules
|
||||||
|
bun.lock
|
||||||
|
bun.lockb
|
||||||
package-lock.json
|
package-lock.json
|
||||||
.env
|
.env
|
||||||
.VSCodeCounter
|
.VSCodeCounter
|
||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
@@ -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` 目录下, 然后在
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# bunfig.toml
|
||||||
|
[install]
|
||||||
|
registry = "https://registry.npmjs.org"
|
||||||
+23
-16
@@ -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
@@ -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";
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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.
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
@@ -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
@@ -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
@@ -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 };
|
||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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";
|
||||||
|
}
|
||||||
@@ -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 + ";" : "";
|
||||||
|
}
|
||||||
@@ -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__;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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)}`;
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -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)",
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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`,
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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标题右侧按钮 */
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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 中的差异对比那样行高过高 */
|
||||||
|
|||||||
@@ -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`
|
||||||
/* 里程碑头部 */
|
/* 里程碑头部 */
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
/* 设置右面板的内容 */
|
/* 设置右面板的内容 */
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
// 分支菜单
|
// 分支菜单
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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 的筛选菜单 */
|
||||||
|
|||||||
@@ -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`
|
||||||
/* 垂直菜单, 用于左侧边栏 */
|
/* 垂直菜单, 用于左侧边栏 */
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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, 主题下此颜色是亮白色, 修改为灰色 */
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
@@ -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([
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
@@ -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",
|
||||||
|
|||||||
@@ -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
@@ -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
Reference in new issue
Block a user