diff --git a/.github/release.md b/.github/release.md index 28f2ca0..6578bb5 100644 --- a/.github/release.md +++ b/.github/release.md @@ -2,10 +2,18 @@ - 支持亮色主题 +## 🌈 Style + +#### 更符合 GitHub 风格 + +- 同步查看文件内容时的代码高亮色 (由于词法分析器的差异和解析问题, 只能实现大概相似, 目前观察到在 TypeScript 下词法分析器表现非常糟糕) + ## 🎈 Perf - 优化差异对比的代码折叠/展开按钮的高度和动画效果 ## 🐞 Fix -- 修复仓库页面与探索页面下仓库主题标签字重不一致的问题 \ No newline at end of file +- 修复仓库页面与探索页面下仓库主题标签字重不一致的问题 +- 修复发布页面下的分支按钮点击时高度变化问题 +- 修复首页/登录页/注册页下导航栏右侧按钮样式问题 #10 diff --git a/TODO.md b/TODO.md index ea36a19..9fead9a 100644 --- a/TODO.md +++ b/TODO.md @@ -4,7 +4,6 @@ - issue/PR 列表样式 github 布局 - styles/themes 库组件导出整理 - defineTheme 颜色生成代码重构 -- 亮色主题适配/测试 - 自动颜色主题生成 ### 其他 diff --git a/src/core/color.ts b/src/core/color.ts index 0a59e0c..53f89df 100644 --- a/src/core/color.ts +++ b/src/core/color.ts @@ -1,7 +1,8 @@ import { rgba, saturate } from "polished"; import { scaleColorLight } from "src/functions"; -import type { Ansi, Console, Diff, Github, Message, Named, Other, Primary, Secondary } from "src/types"; +import type { Ansi, Chroma, Console, Diff, Github, Message, Named, Other, Primary, Secondary } from "src/types"; import { themeVars } from "src/types/vars"; +import { prettylightsDark, prettylightsLight } from "./prettylights"; import type { Theme } from "./theme"; type ThemeColor = { @@ -57,7 +58,7 @@ type ThemeColor = { /** 定义颜色, 用于生成颜色主题 * @example - * 文件名: "dark.css.tsx" + * 文件名: "dark.css.ts" * import type { Console, Diff, Other } from "src/types"; * import { defineTheme, themeVars } from "src"; * @@ -70,7 +71,6 @@ type ThemeColor = { * ... * } * ... - * // 会经过 lightningcss 打包处理生成最终的 CSS * export default defineTheme({ * isDarkTheme: true, * primary: "#0969da", @@ -80,7 +80,7 @@ type ThemeColor = { * other, * }) */ -export function defineTheme(themeColor: ThemeColor): Theme { +export function defineTheme(themeColor: ThemeColor, chroma: Chroma | null = null): Theme { const brightDir = themeColor.isDarkTheme ? -1 : 1; const primary: Primary = { @@ -341,6 +341,7 @@ export function defineTheme(themeColor: ThemeColor): Theme { return { isDarkTheme: themeColor.isDarkTheme.toString(), + chroma: chroma || (themeColor.isDarkTheme ? prettylightsDark : prettylightsLight), color: { primary, secondary, diff --git a/src/core/prettylights.ts b/src/core/prettylights.ts new file mode 100644 index 0000000..fccffb7 --- /dev/null +++ b/src/core/prettylights.ts @@ -0,0 +1,262 @@ +import type { Chroma } from "src/types"; + +export type prettylightsColor = { + syntax: { + brackethighlighter: { + angle: string; + unmatched: string; + }; + carriage: { + return: { + bg: string; + text: string; + }; + }; + comment: string; + constant: string; + constantOtherReferenceLink: string; + entity: string; + entityTag: string; + invalid: { + illegal: { + bg: string; + text: string; + }; + }; + keyword: string; + markup: { + bold: string; + changed: { + bg: string; + text: string; + }; + deleted: { + bg: string; + text: string; + }; + heading: string; + ignored: { + bg: string; + text: string; + }; + inserted: { + bg: string; + text: string; + }; + italic: string; + list: string; + }; + metaDiffRange: string; + storageModifierImport: string; + string: string; + stringRegexp: string; + sublimelinterGutterMark: string; + variable: string; + }; +}; + +export function prettylights2Chroma(prettylights: prettylightsColor): Chroma { + return { + textWhiteSpace: prettylights.syntax.brackethighlighter.unmatched, + err: prettylights.syntax.brackethighlighter.unmatched, + keyword: { + self: prettylights.syntax.keyword, + constant: prettylights.syntax.constant, + declaration: prettylights.syntax.keyword, + namespace: prettylights.syntax.keyword, + pseudo: prettylights.syntax.constant, + reserved: prettylights.syntax.keyword, + type: prettylights.syntax.markup.bold, + }, + name: { + self: prettylights.syntax.markup.bold, + attribute: prettylights.syntax.entityTag, + builtin: prettylights.syntax.entity, + builtinPseudo: prettylights.syntax.markup.bold, + class: prettylights.syntax.variable, + constant: prettylights.syntax.variable, + decorator: prettylights.syntax.entity, + entity: prettylights.syntax.variable, + exception: prettylights.syntax.variable, + function: prettylights.syntax.entity, + functionMagic: prettylights.syntax.entity, + label: prettylights.syntax.constant, + other: prettylights.syntax.markup.bold, + namespace: prettylights.syntax.markup.bold, + property: prettylights.syntax.constant, + tag: prettylights.syntax.entityTag, + variable: prettylights.syntax.constant, + variableClass: prettylights.syntax.constant, + variableGlobal: prettylights.syntax.constant, + variableInstance: prettylights.syntax.constant, + variableMagic: prettylights.syntax.markup.bold, + }, + literal: { + self: prettylights.syntax.string, + date: prettylights.syntax.constant, + }, + string: { + self: prettylights.syntax.string, + affix: prettylights.syntax.string, + backtick: prettylights.syntax.string, + char: prettylights.syntax.string, + delimiter: prettylights.syntax.string, + doc: prettylights.syntax.comment, + double: prettylights.syntax.string, + escape: prettylights.syntax.string, + heredoc: prettylights.syntax.string, + interpol: prettylights.syntax.string, + other: prettylights.syntax.string, + regex: prettylights.syntax.stringRegexp, + single: prettylights.syntax.string, + symbol: prettylights.syntax.string, + }, + number: { + self: prettylights.syntax.constant, + bin: prettylights.syntax.constant, + float: prettylights.syntax.constant, + hex: prettylights.syntax.constant, + integer: prettylights.syntax.constant, + integerLong: prettylights.syntax.constant, + oct: prettylights.syntax.constant, + }, + operator: { + self: prettylights.syntax.constant, + word: prettylights.syntax.constant, + }, + punctuation: prettylights.syntax.markup.bold, + comment: { + self: prettylights.syntax.comment, + hashbang: prettylights.syntax.comment, + multiline: prettylights.syntax.comment, + preproc: prettylights.syntax.constant, + preprocFile: prettylights.syntax.constant, + single: prettylights.syntax.comment, + special: prettylights.syntax.comment, + }, + generic: { + self: prettylights.syntax.markup.bold, + deleted: prettylights.syntax.markup.deleted.text, + emph: prettylights.syntax.markup.italic, + error: prettylights.syntax.invalid.illegal.text, + heading: prettylights.syntax.markup.heading, + inserted: prettylights.syntax.markup.inserted.text, + output: prettylights.syntax.markup.bold, + prompt: prettylights.syntax.markup.bold, + strong: prettylights.syntax.markup.bold, + subheading: prettylights.syntax.markup.heading, + traceback: prettylights.syntax.invalid.illegal.text, + underline: prettylights.syntax.markup.italic, + }, + }; +} + +export const prettylightsDark = prettylights2Chroma({ + syntax: { + brackethighlighter: { + angle: "#9198a1", + unmatched: "#f85149", + }, + carriage: { + return: { + bg: "#b62324", + text: "#f0f6fc", + }, + }, + comment: "#9198a1", + constant: "#79c0ff", + constantOtherReferenceLink: "#a5d6ff", + entity: "#d2a8ff", + entityTag: "#7ee787", + invalid: { + illegal: { + bg: "#8e1519", + text: "#f0f6fc", + }, + }, + keyword: "#ff7b72", + markup: { + bold: "#f0f6fc", + changed: { + bg: "#5a1e02", + text: "#ffdfb6", + }, + deleted: { + bg: "#67060c", + text: "#ffdcd7", + }, + heading: "#1f6feb", + ignored: { + bg: "#1158c7", + text: "#f0f6fc", + }, + inserted: { + bg: "#033a16", + text: "#aff5b4", + }, + italic: "#f0f6fc", + list: "#f2cc60", + }, + metaDiffRange: "#d2a8ff", + storageModifierImport: "#f0f6fc", + string: "#a5d6ff", + stringRegexp: "#7ee787", + sublimelinterGutterMark: "#3d444d", + variable: "#ffa657", + } +}) + +export const prettylightsLight = prettylights2Chroma({ + syntax: { + brackethighlighter: { + angle: "#59636e", + unmatched: "#82071e", + }, + carriage: { + return: { + bg: "#cf222e", + text: "#f6f8fa", + }, + }, + comment: "#59636e", + constant: "#0550ae", + constantOtherReferenceLink: "#0a3069", + entity: "#6639ba", + entityTag: "#0550ae", + invalid: { + illegal: { + bg: "#82071e", + text: "#f6f8fa", + }, + }, + keyword: "#cf222e", + markup: { + bold: "#1f2328", + changed: { + bg: "#ffd8b5", + text: "#953800", + }, + deleted: { + bg: "#ffebe9", + text: "#82071e", + }, + heading: "#0550ae", + ignored: { + bg: "#0550ae", + text: "#d1d9e0", + }, + inserted: { + bg: "#dafbe1", + text: "#116329", + }, + italic: "#1f2328", + list: "#3b2300", + }, + metaDiffRange: "#8250df", + storageModifierImport: "#1f2328", + string: "#0a3069", + stringRegexp: "#116329", + sublimelinterGutterMark: "#818b98", + variable: "#953800", + } +}) \ No newline at end of file diff --git a/src/core/theme.ts b/src/core/theme.ts index fb293a0..0783168 100644 --- a/src/core/theme.ts +++ b/src/core/theme.ts @@ -4,15 +4,6 @@ import type { MapLeafNodes, WithOptionalLayer } from "./types"; export type Theme = WithOptionalLayer>; -function stringToBoolean(str: string, name: string): boolean { - try { - return JSON.parse(str); - } catch (error) { - console.error(error); - throw new Error(`Invalid boolean value(${name}): ${str}`); - } -} - export const overlayAppearDown = "overlay-appear-down"; export const animationDown = `200ms cubic-bezier(0.33, 1, 0.68, 1) 0s 1 normal none running ${overlayAppearDown}`; export const overlayAppearUp = "overlay-appear-up"; @@ -42,7 +33,7 @@ const emoji = ` `; export function createTheme(theme: Theme): void { - const isDarkTheme = stringToBoolean(theme.isDarkTheme, "isDarkTheme"); + const isDarkTheme: boolean = JSON.parse(theme.isDarkTheme); if (isDarkTheme) { globalStyle(emoji, { filter: "invert(100%) hue-rotate(180deg)" }); } diff --git a/src/types/color/chroma.ts b/src/types/color/chroma.ts new file mode 100644 index 0000000..03760c0 --- /dev/null +++ b/src/types/color/chroma.ts @@ -0,0 +1,255 @@ +// 注释来自 AI +export const chroma = { + textWhiteSpace: "text-white-space", + err: null, + keyword: { + /** 所有关键字 + * @example class function var if else return + */ + self: null, + /** 常量关键字 + * @example true false null + */ + constant: null, + /** 声明关键字 + * @example var let const + */ + declaration: null, + /** 命名空间关键字 + * @example package import export + */ + namespace: null, + /** 伪关键字 + * @example this super __init__ + */ + pseudo: null, + /** 保留关键字 + * @example yield await goto + */ + reserved: null, + /** 类型关键字 + * @example int float string bool + */ + type: null, + }, + name: { + /** 通用标识符 */ + self: null, + /** 属性名 + * @example obj.foo HTML/XML 属性名 id="foo" + */ + attribute: null, + /** 内置函数/对象 + * @example Math.PI Math.max + */ + builtin: null, + /** 内置伪标识符 + * @example this super self + */ + builtinPseudo: null, + /** 类名 */ + class: null, + /** 常量名 */ + constant: null, + /** 装饰器 */ + decorator: null, + /** 实体名 + * @example HTML实体名 < > & + */ + entity: null, + /** 异常类名 */ + exception: null, + /** 函数名 */ + function: null, + /** 魔术方法名 + * @example __init__ __str__ + */ + functionMagic: null, + /** 对象属性 */ + property: null, + /** 标签名 + * @example 跳转标签 + */ + label: null, + /** 命名空间 */ + namespace: null, + /** 其他未归类的标识符 */ + other: null, + /** 标签名 + * @example 跳转标签 + */ + tag: null, + /** 变量名 */ + variable: null, + /** 类变量 */ + variableClass: null, + /** 全局变量 */ + variableGlobal: null, + /** 实例变量 */ + variableInstance: null, + /** 魔术变量 + * @example __name__ __doc__ + */ + variableMagic: null, + }, + literal: { + /** 通用字面量 */ + self: null, + /** 日期字面量 + * @example SQL 日期 + */ + date: null, + }, + string: { + /** 通用字符串 */ + self: null, + /** 字符串前缀/后缀 + * @example f"..." 的 f + */ + affix: null, + /** 反引号字符串 + * @example `string` + */ + backtick: null, + /** 字符字面量 + * @example 'a' + */ + char: null, + /** 字符串分隔符 + * @example 引号自身 + */ + delimiter: null, + /** 文档字符串 + * @example """docstring""" + */ + doc: null, + /** 双引号字符串 + * @example "string" + */ + double: null, + /** 转义字符 + * @example \n \t + */ + escape: null, + /** 定界字符串 + * @example <> + */ + heredoc: null, + /** 插值字符串 + * @example ${name} + */ + interpol: null, + /** 其他类型字符串 */ + other: null, + /** 正则表达式字面量 + * @example /^abc/ + */ + regex: null, + /** 单引号字符串 + * @example 'string' + */ + single: null, + /** 符号字符串 + * @example ruby 的 :symbol + */ + symbol: null, + }, + number: { + /** 通用数字 */ + self: null, + /** 二进制数字 + * @example 0b1010 + */ + bin: null, + /** 浮点数 + * @example 1.23 + */ + float: null, + /** 十六进制数字 + * @example 0x123 + */ + hex: null, + /** 普通整数 + * @example 123 + */ + integer: null, + /** 长整数 + * @example 123L + */ + integerLong: null, + /** 八进制数字 + * @example 0o123 + */ + oct: null, + }, + operator: { + /** 运算符 + * @example + - * / = + */ + self: null, + /** 单词运算符 + * @example and or not in is + */ + word: null, + }, + /** 标点符号 + * @example , . : ; ( ) [ ] { } + */ + punctuation: null, + comment: { + /** 通用注释 */ + self: null, + /** Hashbang 注释 + * @example #!/bin/bash + */ + hashbang: null, + /** 多行注释 */ + multiline: null, + /** 预处理器注释 + * @example #include + */ + preproc: null, + /** 预处理器文件注释 + * @example 如 python 的编码声明 # -*- coding: utf-8 -*- + */ + preprocFile: null, + /** 单行注释 */ + single: null, + /** 特殊注释 + * @example JavaDoc 的 `@param` + */ + special: null, + }, + generic: { + /** 通用文本容器 */ + self: null, + /** 被删除的内容 */ + deleted: null, + /** 强调文本 (斜体) */ + emph: null, + /** 错误信息 */ + error: null, + /** 标题 + * @example Markdown 标题 # + */ + heading: null, + /** 新增内容 */ + inserted: null, + /** 程序输出文本 */ + output: null, + /** 交互式提示符 + * @example shell 的 $ + */ + prompt: null, + /** 强调文本 (粗体) */ + strong: null, + /** 子标题 + * @example Markdown 子标题 ## + */ + subheading: null, + /** 堆栈跟踪信息 */ + traceback: null, + /** 下划线文本 */ + underline: null, + }, +}; diff --git a/src/types/color/index.ts b/src/types/color/index.ts index 4dcf082..430f6df 100644 --- a/src/types/color/index.ts +++ b/src/types/color/index.ts @@ -1,3 +1,4 @@ +export { chroma } from "./chroma"; export { ansi, console } from "./console"; export { diff } from "./diff"; export { github } from "./github"; diff --git a/src/types/index.ts b/src/types/index.ts index 34d55f0..6f43f00 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,6 +1,8 @@ import type { MapLeafNodes } from "src/core/types"; import * as color from "./color"; +/** 代码高亮色 */ +export type Chroma = MapLeafNodes; /** 主色调(强调色) */ export type Primary = MapLeafNodes; /** 副色调(边框色) */ diff --git a/src/types/vars.ts b/src/types/vars.ts index 84f33a3..cd02d3a 100644 --- a/src/types/vars.ts +++ b/src/types/vars.ts @@ -1,17 +1,23 @@ import { createGlobalThemeContract } from "@vanilla-extract/css"; import * as color from "./color"; -export function varMapper(value: string | null, path: string[]) { - if (value === null) { - path = path.filter(item => item !== "self"); - path = path.map(item => item.replace(/^num/, "")); - return path.join("-"); - } - return value; +function varMapper(prefix: string | null = null) { + return (value: string | null, path: string[]) => { + if (value === null) { + path = path.filter(item => item !== "self"); + path = path.map(item => item.replace(/^num/, "")); + value = path.join("-"); + } + if (prefix) { + value = `${prefix}-${value}`; + } + return value; + }; } const vars = { isDarkTheme: "is-dark-theme", + chroma: color.chroma, color: { ...color.other, ...color.message, @@ -36,22 +42,20 @@ const otherVars = { }; const customVars = { - custom: { - cloneMenuWidth: "custom-clone-menu-width", - explore: { - repolistColumns: "custom-explore-repolist-columns", - userlistColumns: "custom-explore-userlist-columns", - }, - userRepolistColumns: "custom-user-repolist-columns", - org: { - repolistColumns: "custom-org-repolist-columns", - userlistColumns: "custom-org-userlist-columns", - }, + cloneMenuWidth: "clone-menu-width", + explore: { + repolistColumns: "explore-repolist-columns", + userlistColumns: "explore-userlist-columns", + }, + userRepolistColumns: "user-repolist-columns", + org: { + repolistColumns: "org-repolist-columns", + userlistColumns: "org-userlist-columns", }, }; -export const themeVars = createGlobalThemeContract(vars, varMapper); -export const otherThemeVars = createGlobalThemeContract(otherVars, varMapper); -export const customThemeVars = createGlobalThemeContract(customVars, varMapper); +export const themeVars = createGlobalThemeContract(vars, varMapper()); +export const otherThemeVars = createGlobalThemeContract(otherVars, varMapper()); +export const customThemeVars = createGlobalThemeContract(customVars, varMapper("custom")); export { css } from "@linaria/core"; diff --git a/styles/components/clone.ts b/styles/components/clone.ts index e080b4a..41147a7 100644 --- a/styles/components/clone.ts +++ b/styles/components/clone.ts @@ -54,7 +54,7 @@ export const clone = css` font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, monospace); min-width: 150px; max-width: 400px; - width: ${customThemeVars.custom.cloneMenuWidth}; + width: ${customThemeVars.cloneMenuWidth}; &:hover { border: 1px solid ${themeVars.color.light.border}; border-radius: ${otherThemeVars.border.radius}; diff --git a/styles/components/commit.ts b/styles/components/commit.ts index efb3714..043b8e8 100644 --- a/styles/components/commit.ts +++ b/styles/components/commit.ts @@ -8,7 +8,7 @@ export const commit = css` // 作者 .author { // 作者名称 - a.author-wrapper { + .author-wrapper { color: ${themeVars.color.text.light.num1}; } } diff --git a/styles/components/diff.ts b/styles/components/diff.ts index e21833f..2db5f5f 100644 --- a/styles/components/diff.ts +++ b/styles/components/diff.ts @@ -29,6 +29,7 @@ export const diff = css` } /* 展开/收缩按钮 */ .code-expander-button { + color: ${themeVars.color.text.light.num1}; height: 28px !important; &:hover { diff --git a/styles/components/explore.ts b/styles/components/explore.ts index c612b02..e87ea55 100644 --- a/styles/components/explore.ts +++ b/styles/components/explore.ts @@ -1,9 +1,9 @@ import { fallbackVar } from "src/functions"; import { css, customThemeVars, otherThemeVars, themeVars } from "src/types/vars"; -const userRepoVar = fallbackVar(customThemeVars.custom.userRepolistColumns, "2"); -const exploreRepoVar = fallbackVar(customThemeVars.custom.explore.repolistColumns, "2"); -const orgRepoVar = fallbackVar(customThemeVars.custom.org.repolistColumns, "1"); +const userRepoVar = fallbackVar(customThemeVars.userRepolistColumns, "2"); +const exploreRepoVar = fallbackVar(customThemeVars.explore.repolistColumns, "2"); +const orgRepoVar = fallbackVar(customThemeVars.org.repolistColumns, "1"); // 仓库列表 export const repoList = css` @@ -88,8 +88,8 @@ export const repoList = css` } `; -const exploreUserVar = fallbackVar(customThemeVars.custom.explore.userlistColumns, "3"); -const orgUserVar = fallbackVar(customThemeVars.custom.org.userlistColumns, "2"); +const exploreUserVar = fallbackVar(customThemeVars.explore.userlistColumns, "3"); +const orgUserVar = fallbackVar(customThemeVars.org.userlistColumns, "2"); // 用户列表 export const userList = css` diff --git a/styles/components/release.ts b/styles/components/release.ts index df46e0d..46f4bff 100644 --- a/styles/components/release.ts +++ b/styles/components/release.ts @@ -11,6 +11,7 @@ export const releaseTagMenu = css` font-weight: 500; &.active { background: ${themeVars.github.bgColor.accent.emphasis} !important; + color: ${themeVars.color.white}; } } } @@ -101,6 +102,8 @@ export const rightButton = css` &.tags { .ui.small.button { background-color: ${themeVars.color.button}; + border-color: ${themeVars.color.light.border}; + color: ${themeVars.color.text.light.self}; padding: 5px 16px; min-height: auto; line-height: 20px; diff --git a/styles/public/chroma.ts b/styles/public/chroma.ts index 3d14101..d895980 100644 --- a/styles/public/chroma.ts +++ b/styles/public/chroma.ts @@ -1,277 +1,286 @@ -import { css } from "src/types/vars"; +import { css, themeVars } from "src/types/vars"; -export const chroma = css` +// https://github.com/go-gitea/gitea/blob/main/web_src/css/chroma/base.css +export const chromaBase = css` .chroma { - background-color: var(--color-code-bg); - + // LineTableTD .lntd { vertical-align: top; - border: 0; - margin: 0; padding: 0; + margin: 0; + border: 0; } - + // LineTable .lntable { border-spacing: 0; + padding: 0; + margin: 0; border: 0; width: auto; - margin: 0; - padding: 0; - display: block; overflow: auto; - } - - .hl { - width: 100%; display: block; } - + // LineHighlight + .hl { + display: block; + width: 100%; + } + // LineNumbersTable .lnt, + // LineNumbers .ln { margin-right: 0.4em; padding: 0 0.4em; } - + // GenericStrong .gs { font-weight: var(--font-weight-semibold); } - + // GenericUnderline .gl { text-decoration: underline; } + } +`; - .bp { - color: #fabd2f; - } - - .c, - .c1, - .ch, - .cm { - color: #777e94; - } - - .cp { - color: #8ec07c; - } - - .cpf { - color: #79c0ff; - } - - .cs { - color: #9075cd; - } - - .dl { - color: #79c0ff; - } - - .gd { - color: #fff; - background-color: #5f3737; - } - - .ge { - color: #ddee30; - } - - .gh { - color: #ffaa10; - } - - .gi { - color: #fff; - background-color: #3a523a; - } - - .go { - color: #777e94; - } - - .gp { - color: #ebdbb2; - } - - .gr { - color: #f43; - } - - .gs { - color: #ebdbb2; - } - - .gt { - color: #7ee787; - } - - .gu { - color: #a5d6ff; - } - - .il { - color: #79c0ff; - } - - .k { - color: #ff7b72; - } - - .kc { - color: #79c0ff; - } - - .kd { - color: #ff7b72; - } - - .kn { - color: #ff7b72; - } - - .kp { - color: #5f8700; - } - - .kr { - color: #7ee787; - } - - .kt { - color: #ff7b72; - } - - .m, - .mb, - .mf, - .mh, - .mi, - .mo { - color: #79c0ff; - } - - .n { - color: #c9d1d9; - } - - .na { - color: #d2a8ff; - } - - .nb { - color: #a5d6ff; - } - - .nc { - color: #e6edf3; - } - - .nd { - color: #79c0ff; - } - - .ne { - color: #7ee787; - } - - .nf, - .ni { - color: #d2a8ff; - } - - .nl { - color: #7ee787; - } - - .nn { - color: #e6edf3; - } - - .no { - color: #79c0ff; - } - - .nt { - color: #7ee787; - } - - .nv { - color: #ebdbb2; - } - - .nx { - color: #b6bac5; - } - - .o { - color: #7ee787; - } - - .ow { - color: #5f8700; - } - - .p { - color: #d2d4db; - } - - .s, - .s1, - .s2 { - color: #a5d6ff; - } - - .sa { - color: #79c0ff; - } - - .sb { - color: #a5d6ff; - } - - .sc { - color: #79c0ff; - } - - .sd { - color: #777e94; - } - - .se { - color: #7ee787; - } - - .sh { - color: #79c0ff; - } - - .si { - color: #ffaa10; - } - - .sr { - color: #9075cd; - } - - .ss { - color: #7ee787; - } - - .sx { - color: #ffaa10; - } - - .vc { - color: #7ee787; - } - - .vg, - .vi { - color: #ffaa10; - } - +// https://github.com/alecthomas/chroma/blob/6428fb4e65f3c1493491571c8a6a8f1add1da822/types.go#L208 +export const chromaCode = css` + .chroma { + // TextWhiteSpace .w { - color: #7f8699; + color: ${themeVars.chroma.textWhiteSpace}; + } + // Error + .err { + color: ${themeVars.chroma.err}; + } + // Keyword + .k { + color: ${themeVars.chroma.keyword.self}; + } + .kc { + color: ${themeVars.chroma.keyword.constant}; + } + .kd { + color: ${themeVars.chroma.keyword.declaration}; + } + .kn { + color: ${themeVars.chroma.keyword.namespace}; + } + .kp { + color: ${themeVars.chroma.keyword.pseudo}; + } + .kr { + color: ${themeVars.chroma.keyword.reserved}; + } + .kt { + color: ${themeVars.chroma.keyword.type}; + } + // Name + .n { + color: ${themeVars.chroma.name.self}; + } + .na { + color: ${themeVars.chroma.name.attribute}; + } + .nb { + color: ${themeVars.chroma.name.builtin}; + } + .bp { + color: ${themeVars.chroma.name.builtinPseudo}; + } + .nc { + color: ${themeVars.chroma.name.class}; + } + .no { + color: ${themeVars.chroma.name.constant}; + } + .nd { + color: ${themeVars.chroma.name.decorator}; + } + .ni { + color: ${themeVars.chroma.name.entity}; + } + .ne { + color: ${themeVars.chroma.name.exception}; + } + .nf { + color: ${themeVars.chroma.name.function}; + } + .fm { + color: ${themeVars.chroma.name.functionMagic}; + } + .py { + color: ${themeVars.chroma.name.property}; + } + .nl { + color: ${themeVars.chroma.name.label}; + } + .nn { + color: ${themeVars.chroma.name.namespace}; + } + .nx { + color: ${themeVars.chroma.name.other}; + } + .nt { + color: ${themeVars.chroma.name.tag}; + } + .nv { + color: ${themeVars.chroma.name.variable}; + } + .vc { + color: ${themeVars.chroma.name.variableClass}; + } + .vg { + color: ${themeVars.chroma.name.variableGlobal}; + } + .vi { + color: ${themeVars.chroma.name.variableInstance}; + } + .vm { + color: ${themeVars.chroma.name.variableMagic}; + } + // Literal + .l { + color: ${themeVars.chroma.literal.self}; + } + .ld { + color: ${themeVars.chroma.literal.date}; + } + // String + .s { + color: ${themeVars.chroma.string.self}; + } + .sa { + color: ${themeVars.chroma.string.affix}; + } + .sb { + color: ${themeVars.chroma.string.backtick}; + } + .sc { + color: ${themeVars.chroma.string.char}; + } + .dl { + color: ${themeVars.chroma.string.delimiter}; + } + .sd { + color: ${themeVars.chroma.string.doc}; + } + .s2 { + color: ${themeVars.chroma.string.double}; + } + .se { + color: ${themeVars.chroma.string.escape}; + } + .sh { + color: ${themeVars.chroma.string.heredoc}; + } + .si { + color: ${themeVars.chroma.string.interpol}; + } + .sx { + color: ${themeVars.chroma.string.other}; + } + .sr { + color: ${themeVars.chroma.string.regex}; + } + .s1 { + color: ${themeVars.chroma.string.single}; + } + .ss { + color: ${themeVars.chroma.string.symbol}; + } + // Number + .m { + color: ${themeVars.chroma.number.self}; + } + .mb { + color: ${themeVars.chroma.number.bin}; + } + .mf { + color: ${themeVars.chroma.number.float}; + } + .mh { + color: ${themeVars.chroma.number.hex}; + } + .mi { + color: ${themeVars.chroma.number.integer}; + } + .il { + color: ${themeVars.chroma.number.integerLong}; + } + .mo { + color: ${themeVars.chroma.number.oct}; + } + // Operator + .o { + color: ${themeVars.chroma.operator.self}; + } + .ow { + color: ${themeVars.chroma.operator.word}; + } + // Punctuation + .p { + color: ${themeVars.chroma.punctuation}; + } + // Comment + .c { + color: ${themeVars.chroma.comment.self}; + } + .ch { + color: ${themeVars.chroma.comment.hashbang}; + } + .cm { + color: ${themeVars.chroma.comment.multiline}; + } + .cp { + color: ${themeVars.chroma.comment.preproc}; + } + .cpf { + color: ${themeVars.chroma.comment.preprocFile}; + } + .c1 { + color: ${themeVars.chroma.comment.single}; + } + .cs { + color: ${themeVars.chroma.comment.special}; + } + // Generic + .g { + color: ${themeVars.chroma.generic.self}; + } + .gd { + color: ${themeVars.chroma.generic.deleted}; + } + .ge { + color: ${themeVars.chroma.generic.emph}; + } + .gr { + color: ${themeVars.chroma.generic.error}; + } + .gh { + color: ${themeVars.chroma.generic.heading}; + } + .gi { + color: ${themeVars.chroma.generic.inserted}; + } + .go { + color: ${themeVars.chroma.generic.output}; + } + .gp { + color: ${themeVars.chroma.generic.prompt}; + } + .gs { + color: ${themeVars.chroma.generic.strong}; + } + .gu { + color: ${themeVars.chroma.generic.subheading}; + } + .gt { + color: ${themeVars.chroma.generic.traceback}; + } + .gu { + color: ${themeVars.chroma.generic.underline}; } } `; diff --git a/styles/public/dropdown.ts b/styles/public/dropdown.ts index f2d5874..64f3b6f 100644 --- a/styles/public/dropdown.ts +++ b/styles/public/dropdown.ts @@ -120,6 +120,11 @@ export const selectionDropdown = css` ${activeItemAfterStyle}; } } + // 发布版本页面的分支按钮, 覆盖 Gitea 的样式, 避免按钮元素高度不一致 + .repository.new.release .target .selection.dropdown { + padding-top: 8px; + padding-bottom: 8px; + } // 这个按钮项目前只在创建仓库的拥有者 // 不实现伪元素, 因为 .item 设置溢出的元素会被截断 .ui.selection.dropdown.ellipsis-text-items, diff --git a/styles/public/navbar.ts b/styles/public/navbar.ts index 0274b0e..ab6034e 100644 --- a/styles/public/navbar.ts +++ b/styles/public/navbar.ts @@ -2,7 +2,8 @@ import { css, otherThemeVars, themeVars } from "src/types/vars"; export const navbarRight = css` #navbar { - .navbar-right { + // 进入用户页面后, 避免注册, 登录和首页等意外覆盖 + .navbar-right:has(.user-menu) { gap: 8px; // 右侧按钮, 但不包括头像 > .item:not(:last-child) { diff --git a/themes/light.css.ts b/themes/light.css.ts index 41775d4..1dd4c72 100644 --- a/themes/light.css.ts +++ b/themes/light.css.ts @@ -1,7 +1,5 @@ import { defineGithubTheme } from "src/core/github"; -// [TODO] chroma 语法高亮的颜色 - export default defineGithubTheme({ isDarkTheme: false, display: {