organize code

This commit is contained in:
lutinglt committed 2026-06-07 19:36:02 +08:00
1 parent f222adf1bf
commit 6d2c510148
9 files changed
+141 -123

No files matched your search

+2 -2
View File
@@ -115,8 +115,8 @@ Please add your author info at the top of the color theme file so Issue reporter
It is recommended to use `defineTheme` with the `ThemeColor` type to define theme colors. The framework will
automatically compute and generate all Gitea CSS variables.
Color calculation functions can be imported from `@lutinglt/gitea-github-theme/core` (`scaleColorLight`, `rgba`),
or use the `color2k` library for additional color manipulation.
Color calculation functions can be imported from `@lutinglt/gitea-github-theme/core` (`scaleColorLight`, `rgba`), or use
the `color2k` library for additional color manipulation.
Example: `themes/my-theme.ts`
+2 -1
View File
@@ -106,7 +106,8 @@ bun commit
推荐使用 `defineTheme` 配合 `ThemeColor` 类型来定义主题颜色, 框架会自动计算生成所有 Gitea CSS 变量.
颜色计算函数可从 `@lutinglt/gitea-github-theme/core` 导入 `scaleColorLight` 和 `rgba`, 或使用 `color2k` 库进行额外颜色操作.
颜色计算函数可从 `@lutinglt/gitea-github-theme/core` 导入 `scaleColorLight` 和 `rgba`, 或使用 `color2k`
库进行额外颜色操作.
例: `themes/主题名称.ts`
-1
View File
@@ -11,7 +11,6 @@
"bun": ">=1.3.14"
},
"exports": {
"./theme.config.ts": "./theme.config.ts",
"./core": "./src/index.ts",
"./vite-plugin": "./src/vite-plugin/index.ts",
"./styles": "./styles/index.ts",
+2 -2
View File
@@ -49,8 +49,8 @@ export function css(strings: TemplateStringsArray, ...values: CSSInterpolation[]
*
* 合并按参数顺序排列
*/
export function cssCombine(...styles: CSSString[]): CSSString {
return styles.join("\n") as CSSString;
export function cssCombine(...styles: (CSSString | undefined)[]): CSSString {
return styles.filter(Boolean).join("\n") as CSSString;
}
/** cssStyle 用于 css 模板字符串的插值
+14 -9
View File
@@ -19,8 +19,10 @@
import { transform } from "lightningcss";
import type { PluginOption } from "vite";
import { createTheme, createThemeMetaInfo, type CSSString, type GiteaThemeMeta, type Theme } from "../core";
import type { CSSString, GiteaThemeMeta, Theme } from "../core";
import { createTheme, createThemeMetaInfo, cssCombine } from "../core";
import { compileCSS } from "../vanilla-extract";
import type { ThemeConfig } from "./themeConfig";
import { buildFullDisplayName, buildFullThemeName } from "./utils";
const VIRTUAL_ID = "virtual:gitea-github-theme-placeholder";
@@ -33,7 +35,7 @@ type ThemeEntry = {
styles?: CSSString;
};
export function giteaGitHubTheme(): PluginOption {
export function giteaGitHubTheme(themeConfig: ThemeConfig): PluginOption {
return {
name: "lutinglt-gitea-github-theme",
@@ -47,17 +49,15 @@ export function giteaGitHubTheme(): PluginOption {
return { build: { rolldownOptions: { input: VIRTUAL_ID } } };
},
async generateBundle(this, _options, bundle) {
generateBundle(this, _options, bundle) {
// 清除占位入口产物
for (const key of Object.keys(bundle)) {
delete bundle[key];
}
// 1. 解析主题配置
const themeConfig = (await import("@lutinglt/gitea-github-theme/theme.config.ts")).default;
const themeEntries: ThemeEntry[] = [];
for (const themeSeries of themeConfig) {
for (const themeSeries of themeConfig.themeSeries) {
for (const [themeKeyName, entry] of Object.entries(themeSeries.themes)) {
const name = entry.themeName ?? themeKeyName;
entry.themeName = buildFullThemeName(themeSeries, name);
@@ -69,7 +69,7 @@ export function giteaGitHubTheme(): PluginOption {
colorblindType: entry.colorblindType,
},
theme: entry.theme,
styles: themeSeries.styles,
styles: cssCombine(themeSeries.styles, entry.styles),
});
}
// 处理自动主题
@@ -93,8 +93,13 @@ export function giteaGitHubTheme(): PluginOption {
}
// 2. 编译公共样式
const rawStyles = Buffer.from((await import("@lutinglt/gitea-github-theme/styles")).default);
const globalStyles = transform({ filename: "globalStyles.css", code: rawStyles, minify: true }).code.toString();
const globalStyles = themeConfig.globalStyles
? transform({
filename: "globalStyles.css",
code: Buffer.from(themeConfig.globalStyles),
minify: true,
}).code.toString()
: "";
// 3. 编译每个主题的 CSS 并输出
for (const entry of themeEntries) {
+17 -8
View File
@@ -19,7 +19,7 @@
import type { ColorblindType, CSSString, Theme } from "../core";
type ThemeConfig = {
type ThemeSpec = {
/** 主题名称, 用于生成文件名, 未指定时取 themes 中的键名 */
themeName?: string;
/** 显示名称, 用于 Gitea UI 显示的名称
@@ -30,17 +30,19 @@ type ThemeConfig = {
/** 色盲类型, 仅用于声明主题为色盲主题 */
colorblindType?: ColorblindType;
theme: Theme;
/** 主题追加的样式, 优先级高于默认样式和主题系列样式 */
styles?: CSSString;
};
type Themes =
| {
/** 主题系列的深色模式主题 */
dark: ThemeConfig;
[themeKeyName: string]: ThemeConfig;
dark: ThemeSpec;
[themeKeyName: string]: ThemeSpec;
}
| {
/** 主题系列的浅色模式主题 */
light: ThemeConfig;
[themeKeyName: string]: ThemeConfig;
light: ThemeSpec;
[themeKeyName: string]: ThemeSpec;
};
export type ThemeSeries = {
/** 主题系列名称, 做为前缀用于生成文件名和显示名称 */
@@ -58,13 +60,20 @@ export type ThemeSeries = {
styles?: CSSString;
};
export type ThemeConfig = {
/** 全局样式 */
globalStyles?: CSSString;
/** 主题系列 */
themeSeries: ThemeSeries[];
};
/** 定义主题配置 */
export function defineThemeConfig(config: ThemeSeries[]): ThemeSeries[] {
export function defineThemeConfig(themeConfig: ThemeConfig): ThemeConfig {
// 检查主题系列名称是否重复
const names = config.map(c => c.themeSeriesName);
const names = themeConfig.themeSeries.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;
return themeConfig;
}
+102 -98
View File
@@ -18,111 +18,115 @@
*/
import { defineThemeConfig } from "@lutinglt/gitea-github-theme/core";
import styles from "@lutinglt/gitea-github-theme/styles";
import themes from "@lutinglt/gitea-github-theme/themes";
export default defineThemeConfig([
{
themeSeriesName: "default",
themes: {
dark: { theme: themes.github.dark },
light: { theme: themes.github.light },
"soft-dark": { theme: themes.github.softDark },
},
},
{
themeSeriesName: "colorblind",
autoTheme: { displayName: "Default Auto Protanopia And Deuteranopia", colorblindType: "red-green" },
themes: {
dark: {
displayName: "Default Dark Protanopia And Deuteranopia",
colorblindType: "red-green",
theme: themes.github.colorblind.dark,
},
light: {
displayName: "Default Light Protanopia And Deuteranopia",
colorblindType: "red-green",
theme: themes.github.colorblind.light,
export default defineThemeConfig({
globalStyles: styles,
themeSeries: [
{
themeSeriesName: "default",
themes: {
dark: { theme: themes.github.dark },
light: { theme: themes.github.light },
"soft-dark": { theme: themes.github.softDark },
},
},
},
{
themeSeriesName: "tritanopia",
autoTheme: { displayName: "Default Auto Tritanopia", colorblindType: "blue-yellow" },
themes: {
dark: {
displayName: "Default Dark Tritanopia",
colorblindType: "blue-yellow",
theme: themes.github.tritanopia.dark,
},
light: {
displayName: "Default Light Tritanopia",
colorblindType: "blue-yellow",
theme: themes.github.tritanopia.light,
{
themeSeriesName: "colorblind",
autoTheme: { displayName: "Default Auto Protanopia And Deuteranopia", colorblindType: "red-green" },
themes: {
dark: {
displayName: "Default Dark Protanopia And Deuteranopia",
colorblindType: "red-green",
theme: themes.github.colorblind.dark,
},
light: {
displayName: "Default Light Protanopia And Deuteranopia",
colorblindType: "red-green",
theme: themes.github.colorblind.light,
},
},
},
},
{
themeSeriesName: "pink",
themes: {
dark: { theme: themes.github.pink.dark },
light: { theme: themes.github.pink.light },
"soft-dark": { theme: themes.github.pink.softDark },
},
},
{
themeSeriesName: "gitea",
themes: {
dark: { theme: themes.gitea.dark },
light: { theme: themes.gitea.light },
},
},
{
themeSeriesName: "catppuccin",
themes: {
dark: { themeName: "mocha", theme: themes.catppuccin.mocha },
light: { themeName: "latte", theme: themes.catppuccin.latte },
frappe: { theme: themes.catppuccin.frappe },
macchiato: { theme: themes.catppuccin.macchiato },
},
},
{
themeSeriesName: "high-contrast",
themes: {
dark: { theme: themes.github.highContrast.dark },
light: { theme: themes.github.highContrast.light },
"soft-dark": { theme: themes.github.highContrast.softDark },
},
},
{
themeSeriesName: "high-contrast-colorblind",
autoTheme: { displayName: "High Contrast Auto Protanopia And Deuteranopia", colorblindType: "red-green" },
themes: {
dark: {
displayName: "High Contrast Dark Protanopia And Deuteranopia",
colorblindType: "red-green",
theme: themes.github.highContrast.colorblind.dark,
},
light: {
displayName: "High Contrast Light Protanopia And Deuteranopia",
colorblindType: "red-green",
theme: themes.github.highContrast.colorblind.light,
{
themeSeriesName: "tritanopia",
autoTheme: { displayName: "Default Auto Tritanopia", colorblindType: "blue-yellow" },
themes: {
dark: {
displayName: "Default Dark Tritanopia",
colorblindType: "blue-yellow",
theme: themes.github.tritanopia.dark,
},
light: {
displayName: "Default Light Tritanopia",
colorblindType: "blue-yellow",
theme: themes.github.tritanopia.light,
},
},
},
},
{
themeSeriesName: "high-contrast-tritanopia",
autoTheme: { displayName: "High Contrast Auto Tritanopia", colorblindType: "blue-yellow" },
themes: {
dark: {
displayName: "High Contrast Dark Tritanopia",
colorblindType: "blue-yellow",
theme: themes.github.highContrast.tritanopia.dark,
},
light: {
displayName: "High Contrast Light Tritanopia",
colorblindType: "blue-yellow",
theme: themes.github.highContrast.tritanopia.light,
{
themeSeriesName: "pink",
themes: {
dark: { theme: themes.github.pink.dark },
light: { theme: themes.github.pink.light },
"soft-dark": { theme: themes.github.pink.softDark },
},
},
},
]);
{
themeSeriesName: "gitea",
themes: {
dark: { theme: themes.gitea.dark },
light: { theme: themes.gitea.light },
},
},
{
themeSeriesName: "catppuccin",
themes: {
dark: { themeName: "mocha", theme: themes.catppuccin.mocha },
light: { themeName: "latte", theme: themes.catppuccin.latte },
frappe: { theme: themes.catppuccin.frappe },
macchiato: { theme: themes.catppuccin.macchiato },
},
},
{
themeSeriesName: "high-contrast",
themes: {
dark: { theme: themes.github.highContrast.dark },
light: { theme: themes.github.highContrast.light },
"soft-dark": { theme: themes.github.highContrast.softDark },
},
},
{
themeSeriesName: "high-contrast-colorblind",
autoTheme: { displayName: "High Contrast Auto Protanopia And Deuteranopia", colorblindType: "red-green" },
themes: {
dark: {
displayName: "High Contrast Dark Protanopia And Deuteranopia",
colorblindType: "red-green",
theme: themes.github.highContrast.colorblind.dark,
},
light: {
displayName: "High Contrast Light Protanopia And Deuteranopia",
colorblindType: "red-green",
theme: themes.github.highContrast.colorblind.light,
},
},
},
{
themeSeriesName: "high-contrast-tritanopia",
autoTheme: { displayName: "High Contrast Auto Tritanopia", colorblindType: "blue-yellow" },
themes: {
dark: {
displayName: "High Contrast Dark Tritanopia",
colorblindType: "blue-yellow",
theme: themes.github.highContrast.tritanopia.dark,
},
light: {
displayName: "High Contrast Light Tritanopia",
colorblindType: "blue-yellow",
theme: themes.github.highContrast.tritanopia.light,
},
},
},
],
});
-1
View File
@@ -28,7 +28,6 @@
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
"paths": {
"@lutinglt/gitea-github-theme/theme.config.ts": ["./theme.config.ts"],
"@lutinglt/gitea-github-theme/core": ["./src"],
"@lutinglt/gitea-github-theme/vite-plugin": ["./src/vite-plugin"],
"@lutinglt/gitea-github-theme/styles": ["./styles"],
+2 -1
View File
@@ -19,5 +19,6 @@
import { giteaGitHubTheme } from "@lutinglt/gitea-github-theme/vite-plugin";
import { defineConfig } from "vite";
import themeConfig from "./theme.config.ts";
export default defineConfig({ plugins: [giteaGitHubTheme()] });
export default defineConfig({ plugins: [giteaGitHubTheme(themeConfig)] });