Compare commits

...

139 Commits

Author SHA1 Message Date
lutinglt
987144a594 version 2025-09-11 14:40:08 +08:00
lutinglt
2caf68e290 1.24.6 2025-09-11 14:36:26 +08:00
lutinglt
e2ccc8c9f7 release 2025-09-11 13:35:21 +08:00
lutinglt
7287aad198 author 2025-09-11 13:31:34 +08:00
lutinglt
b3ce1a8439 简化 release 2025-09-11 12:01:35 +08:00
lutinglt
5d96a6896d 修复display主题下差异对比展开折叠代码按钮颜色 2025-09-11 11:48:35 +08:00
lutinglt
ced954c1d0 精调 display 主题颜色 2025-09-11 11:16:06 +08:00
lutinglt
bfb27ab4a2 perf release ci 2025-09-11 00:07:26 +08:00
lutinglt
3a5306b1a6 就这样吧 2025-09-11 00:05:45 +08:00
lutinglt
6608abc39b 测试 release 中的排序 2025-09-10 23:59:45 +08:00
lutinglt
7eeafae4da fix ci 2025-09-10 23:49:44 +08:00
lutinglt
89ac2720c7 支持猛男粉颜色主题 2025-09-10 23:43:38 +08:00
lutinglt
472647e7c1 修复发布页主色调按钮多余的阴影 2025-09-10 12:32:21 +08:00
lutinglt
84a2f5a1ee 版本号自动生成 2025-09-10 10:59:33 +08:00
lutinglt
e45c73d850 me sb, so fix 2025-09-10 00:25:52 +08:00
lutinglt
10d0a3dbd8 format 2025-09-09 23:50:40 +08:00
lutinglt
ae9bc3cbb5 修改外观设置中显示的主题名称 2025-09-09 23:48:55 +08:00
lutinglt
dc0f43a082 派生栏上下间距 2025-09-09 18:52:51 +08:00
lutinglt
5fb9ef2a61 修复归档仓库 Issue 时间线过长插入归档信息框 2025-09-09 17:47:33 +08:00
lutinglt
247c6fd987 弹窗圆角 2025-09-09 17:14:11 +08:00
lutinglt
865642eb3b 仪表盘页的提交 SHA 标签居中对齐 2025-09-09 17:02:45 +08:00
lutinglt
392c82fcd5 修复新建里程碑切换按钮样式 2025-09-09 14:52:08 +08:00
lutinglt
02087941f4 修复创建工单页面样式 2025-09-09 14:48:57 +08:00
lutinglt
0560aad59e 隐藏热力图和动态的分割线 2025-09-09 14:24:52 +08:00
lutinglt
8e8416507e 同步主色调按钮和红色按钮的阴影样式 2025-09-09 14:14:12 +08:00
lutinglt
1a702c9526 同步提示框样式 2025-09-09 10:41:23 +08:00
lutinglt
46c2d46482 优化分页菜单高度 2025-09-08 22:32:09 +08:00
lutinglt
8b15abe30b 优化动态间隔 2025-09-08 21:05:47 +08:00
lutinglt
9756cbd409 优化仪表板热力图和动态样式 2025-09-08 20:44:39 +08:00
lutinglt
b529cefd04 release 2025-09-08 18:37:59 +08:00
lutinglt
dded6b1948 release 2025-09-08 16:34:06 +08:00
lutinglt
5e8f62c79f release 2025-09-08 16:25:07 +08:00
lutinglt
9b2a1783ef release 2025-09-08 16:11:38 +08:00
lutinglt
6bb138e964 软件包详情页版本标签样式 2025-09-08 15:53:01 +08:00
lutinglt
e387008ee5 同步软件包页面样式 2025-09-08 15:29:01 +08:00
lutinglt
c8634fb14b 微调仓库相关界面元素间隔 2025-09-08 11:02:58 +08:00
lutinglt
fc10a1f54b 优化仪表板动态信息间隔 2025-09-07 23:41:21 +08:00
lutinglt
f08c7a0c8c 修复嵌套下拉菜单样式和双选项切换按钮 2025-09-07 23:05:26 +08:00
lutinglt
6c0fd14119 同步仓库已标星的星星颜色 2025-09-07 18:31:46 +08:00
lutinglt
cb49b12ff0 调整发布页版本间隔 2025-09-07 18:07:57 +08:00
lutinglt
468a97994a 优化仪表板的仓库组织切换按钮样式 2025-09-07 17:02:34 +08:00
lutinglt
1986956191 优化下拉菜单样式 2025-09-07 15:28:00 +08:00
lutinglt
979af2a756 优化通知页面按钮悬浮效果 2025-09-07 14:49:43 +08:00
lutinglt
a34bd93894 同步通知页面样式 2025-09-07 14:44:04 +08:00
lutinglt
64684a51da 同步分支菜单宽度 2025-09-07 13:30:24 +08:00
lutinglt
e89c26e753 同步关注页面样式 2025-09-07 12:52:21 +08:00
lutinglt
796c6f1519 同步差异对比页面文件名标题栏样式 2025-09-07 11:00:53 +08:00
lutinglt
f9d63e6fd1 同步用户菜单样式 2025-09-07 10:31:54 +08:00
lutinglt
08f662497b 同步订阅页面样式 2025-09-06 21:23:47 +08:00
lutinglt
c4bff9fdc1 修复仓库克隆点星按钮高度 2025-09-06 20:53:43 +08:00
lutinglt
a48963c43d 同步置顶 Issue 样式 2025-09-06 20:35:55 +08:00
lutinglt
7366813f02 修复提交列表尾行圆角 2025-09-06 20:08:06 +08:00
lutinglt
dc3047f16a 同步顶部工单等仪表板样式 2025-09-06 19:59:48 +08:00
lutinglt
e0518a2986 同步里程碑页面样式 2025-09-06 16:20:40 +08:00
lutinglt
39727c789b 缩小发布标题和内容的间隔 2025-09-05 17:02:36 +08:00
lutinglt
3c21a98fee 优化发布页面布局和下载列表样式 2025-09-04 20:03:34 +08:00
lutinglt
9bce3797a6 修复文件预览时文件树有边框过粗 2025-08-30 15:37:58 +08:00
lutinglt
9d3e738723 微调一些标签的字体大小 2025-08-29 12:11:15 +08:00
lutinglt
86ac3b73ba 略微减小导航栏创建仓库菜单按钮内的图标间隔 2025-08-25 16:25:29 +08:00
lutinglt
09a4bbdc07 取消修改编辑器字体大小, 避免光标错位 2025-08-23 11:55:33 +08:00
lutinglt
68d632a6b3 update readme 2025-08-19 00:51:02 +08:00
lutinglt
2b5962e1c2 update readme 2025-08-19 00:49:40 +08:00
lutinglt
7cd7a48d17 修复后台管理的运维管理面板的样式 2025-08-17 16:18:57 +08:00
lutinglt
ebc6463c30 修复登录二次验证页面内容位置 2025-08-17 10:46:52 +08:00
lutinglt
77c3842a43 修复登录二次验证页面内容位置 2025-08-17 10:39:50 +08:00
lutinglt
d311072ca0 update readme 2025-08-16 22:50:00 +08:00
lutinglt
8b4102d8d9 同步查看代码文件内容时的样式 2025-08-16 22:33:16 +08:00
lutinglt
73b5397d77 优化文件树的顶部和底部间隔 2025-08-16 20:58:10 +08:00
lutinglt
134c383cdb 优化查看代码文件内容时的体验 2025-08-16 20:51:07 +08:00
lutinglt
c6e73000bd 修复仓库中文 README 时的按钮下划线长度 2025-08-16 13:03:56 +08:00
lutinglt
dbf3547ad5 change default readme 2025-08-16 12:23:43 +08:00
lutinglt
5235dae367 更新英文截图 2025-08-16 12:19:11 +08:00
lutinglt
a9df7a31e1 README_EN 2025-08-16 12:03:10 +08:00
lutinglt
dd6e97be1d update readme 2025-08-15 10:53:02 +08:00
lutinglt
29f983cce6 update readme 2025-08-15 10:51:24 +08:00
鲁汀
fca10130a3 Create FUNDING.yml 2025-08-15 10:45:15 +08:00
lutinglt
8676816342 修复红绿色盲主题的代码高亮色 2025-08-15 09:15:13 +08:00
lutinglt
9bcea89fcb update readme 2025-08-14 23:31:41 +08:00
lutinglt
26deec78ff format code 2025-08-14 21:24:03 +08:00
lutinglt
ffb7fa810b 发布时的主题顺序 2025-08-14 20:51:56 +08:00
lutinglt
2083d3026b version 2025-08-14 20:37:00 +08:00
lutinglt
5037e46447 beta 2025-08-14 20:10:48 +08:00
lutinglt
cd2f7579b1 色盲主题打包 2025-08-14 20:02:57 +08:00
lutinglt
1b237b12f3 update readme 2025-08-14 19:59:57 +08:00
lutinglt
a8453a87a5 支持色盲主题 2025-08-14 19:59:08 +08:00
lutinglt
6aef26cdc8 重叠边框线, 避免过粗 2025-08-14 00:10:46 +08:00
lutinglt
a4c94cb34d 重叠边框线, 避免过粗 2025-08-14 00:09:38 +08:00
lutinglt
8c45f44309 查看代码文件页面文件树头部有时不会固定住 2025-08-13 23:35:03 +08:00
lutinglt
1c9b02ea88 查看代码文件页面路径栏有时内容不会居中 2025-08-13 22:44:19 +08:00
lutinglt
61313d5644 ci tag 2025-08-13 22:39:10 +08:00
lutinglt
d7722cde2f update md 2025-08-13 22:33:53 +08:00
lutinglt
e3366a8406 filetree 默认高度 2025-08-13 22:32:47 +08:00
lutinglt
f6fc6a9702 🎉 release 2025-08-13 22:17:12 +08:00
lutinglt
12d5636fb7 同步查看代码文件页面样式 2025-08-13 22:03:41 +08:00
lutinglt
10c06dad60 仪表板时间 2025-08-13 19:53:27 +08:00
lutinglt
c80dd09828 时间追踪 2025-08-13 18:09:27 +08:00
lutinglt
8f2f45406a 同步 Issue/PR 列表样式 2025-08-13 16:45:53 +08:00
lutinglt
c46d9333ff fix org 2025-08-13 12:13:18 +08:00
lutinglt
7039041d9d 同步编辑器字体大小 2025-08-13 11:34:48 +08:00
lutinglt
9949bdc7bd 优化仪表板样式 & 同步代码编辑器背景色 2025-08-13 11:20:01 +08:00
lutinglt
1b81b6ad93 优化仪表板仓库/组织列表样式, 好看多了, 愿称之为神之一手 2025-08-12 22:32:31 +08:00
lutinglt
62bc2afa2a 同步 Issue/PR 详细页面侧边栏样式 2025-08-12 20:57:03 +08:00
lutinglt
60e873b0e0 同步用户点星仓库列表样式 2025-08-12 16:05:38 +08:00
lutinglt
00737f5203 优化标签样式 2025-08-12 15:34:53 +08:00
lutinglt
a90b72896b 优化热力图和动态样式 2025-08-12 14:43:05 +08:00
lutinglt
f90c488d45 优化消息右上角小图标样式 2025-08-12 11:06:32 +08:00
lutinglt
56c284aec2 同步登录/注册页面样式 2025-08-12 10:29:32 +08:00
lutinglt
0df107a166 优化创建仓库/迁移仓库/创建组织页面的样式与设置页面的样式一致 2025-08-12 09:47:43 +08:00
lutinglt
c5c1ca4a6b fix height 2025-08-12 00:27:23 +08:00
lutinglt
6bbc304a7c 激活字体颜色白色 2025-08-12 00:20:47 +08:00
lutinglt
5c95add059 同步分页菜单样式 2025-08-12 00:16:38 +08:00
lutinglt
2efaeead6b 同步仓库代码文件页 README 导航栏样式 2025-08-11 23:29:48 +08:00
lutinglt
29122e946c 修复顶部导航栏工单管理/请求合并页面搜索框旁的选择下拉框按钮内容过窄 2025-08-11 22:55:05 +08:00
lutinglt
81be016be3 略微增加仓库代码文件列表的单行高度 2025-08-11 22:41:24 +08:00
lutinglt
2ffdf501b3 修复用户公开活动页动态布局问题 2025-08-11 18:12:51 +08:00
lutinglt
9f2e5df49c 代码整理 2025-08-11 17:56:39 +08:00
lutinglt
00eda68f00 修复 Action 作业步骤页面标题选中时滚动固定的高度问题 2025-08-11 17:39:58 +08:00
lutinglt
fc4e6f43bb todo 2025-08-11 09:55:30 +08:00
lutinglt
1f01495a10 update 2025-08-11 09:52:43 +08:00
lutinglt
eae2961989 update contributing 2025-08-11 09:52:18 +08:00
lutinglt
563c20f2cc update todo 2025-08-11 09:45:32 +08:00
lutinglt
058e1b89ee update todo 2025-08-11 09:44:31 +08:00
lutinglt
c431fbadb4 update todo 2025-08-11 09:42:24 +08:00
lutinglt
74254a3f80 update readme 2025-08-11 09:31:57 +08:00
lutinglt
8118706706 update readme 2025-08-11 09:30:01 +08:00
lutinglt
ffbfccd7dc update md 2025-08-11 09:26:10 +08:00
lutinglt
1d8dfdb82b update markdown 2025-08-10 23:04:19 +08:00
lutinglt
11422f3b05 udpate contributing 2025-08-10 23:02:25 +08:00
lutinglt
cca5e4e435 update contributing 2025-08-10 22:58:38 +08:00
lutinglt
780c72919d update README 2025-08-10 22:43:39 +08:00
lutinglt
dc4eff2bd7 update contributing.md 2025-08-10 21:46:30 +08:00
lutinglt
3b5a596b2f fix ci 2025-08-10 17:14:55 +08:00
lutinglt
41deab68c9 支持柔和的暗色主题 2025-08-10 17:12:26 +08:00
lutinglt
a4ae937291 主题打包 2025-08-10 16:40:25 +08:00
lutinglt
babb174b24 自动颜色主题生成 2025-08-10 16:18:30 +08:00
鲁汀
dca1c34518 feat(chroma): 代码高亮重构 (#9)
* feat(chroma): 代码高亮重构

* todo

* release 亮色适配

* 发布页分支按钮高度修正

* chroma变量和修复注册页导航栏

* chroma 重构适配亮色

---------

Co-authored-by: lutinglt <lutinglt@users.noreply.github.com>
2025-08-10 14:06:08 +08:00
lutinglt
065d7893d8 亮色主题适配 2025-08-07 18:26:21 +08:00
lutinglt
0a6770c28e 亮色主题 2025-08-07 16:19:18 +08:00
lutinglt
0825efeb2c update readme 2025-08-06 15:23:48 +08:00
99 changed files with 4132 additions and 974 deletions

View File

@@ -1,4 +1,8 @@
# 开发模式下编译的主题 (开发模式仅编译单个主题)
DEV_THEME=dark
# 把编译后的主题上传到服务器的服务器名称, 通过 SCP 上传
SSH_SERVER=localhost
# 上传到服务器的用户名称, 不支持密码, 请确保有 SSH 免密登录权限
SSH_USER=root
# 上传到服务器的主题路径, 请使用绝对路径
GITEA_THEME_PATH=/data/gitea/public/assets/css/

15
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
thanks_dev: # Replace with a single thanks.dev username
custom: ["https://afdian.com/a/luting"]

View File

@@ -1,11 +1,17 @@
## ✨ Feature
### 🎉
### ✨ Feature
#### CSS 变量
## 🌈 Style
### 🌈 Style
#### 更符合 GitHub 风格
##### 更符合 GitHub 风格
## 🎈 Perf
### 🐞 Fix
## 🐞 Fix
## 📃 English
#### CSS Variable
##### More GitHub-like style

91
.github/release.md vendored
View File

@@ -1,20 +1,87 @@
## ✨ Feature
### 🎉 已完成大部分页面的 GitHub 风格 ( GitHub Style Completed for Most Pages )
如果您仍在使用旧版本,强烈建议更新至本版本。此版本已为大部分常用页面实现了 GitHub 风格设计,提供了更强的一致性,并修复了若干已知问题。
由于布局限制,项目和百科页面的 GitHub 风格适配方案尚未确定。
If you are still using an older version, we highly recommend updating to this release. This version has implemented the
GitHub-style design for most commonly used pages, ensuring stronger consistency, and addresses several known issues.
Due to layout constraints, the approach for adapting the GitHub style to Project and Wiki pages has not yet been
determined.
### ✨ Feature
- 新增粉色颜色主题
- 修改外观设置中显示的主题名称
#### CSS 变量
- 支持自定义探索/组织/用户页面的仓库列表列数
- 支持自定义探索/组织页面的用户/组织列表列数
- 新增 `--custom-branch-menu-width` 变量, 用于设置分支菜单的宽度
- 新增 `--custom-user-menu-width` 变量, 用于设置用户菜单的宽度
## 🌈 Style
### 🌈 Style
#### 更符合 GitHub 风格
- 优化用户首页仪表板的样式
- 同步 Issue/PR 的评论样式
- 同步表情菜单样式
- 同步探索/组织/用户页面的仓库列表样式
- 同步探索/组织页面的用户列表样式
- 同步探索页面的组织列表样式
##### 更符合 GitHub 风格
## 🐞 Fix
- 同步查看代码文件内容时的样式 (去掉了一些底部元素, 优化滚动体验)
- 整体调整了页面元素的间隔, 样式和字体大小
- 同步顶部工单/合并请求/里程碑下的仪表板样式
- 同步里程碑/置顶 Issue 的样式
- 同步通知/订阅/关注/软件包/提示框/用户头像菜单的页面样式
- 同步分支菜单宽度
- 同步仓库已标星的星星颜色
- 修复探索页面下仓库的类型标签意外触发悬浮效果
### 🐞 Fix
- 修复红绿色盲主题的代码高亮色
- 修复仓库中文 README 时的按钮下划线长度
- 修复登录二次验证页面内容位置
- 修复后台管理的运维管理面板的样式
- 取消修改编辑器字体大小, 避免光标错位
- 修复提交列表尾行圆角
- 修复 Wiki 页面和二级导航栏组织下团队菜单的圆角问题
- 修复创建工单页面样式
- 修复归档仓库 Issue 时间线过长插入归档信息框
- 修复亮色主题下的 PR 合并操作评论的头像和按钮图标颜色
## 📃 English (From AI)
### ✨ Feature
- Added pink color theme
- Modified theme names displayed in appearance settings
#### CSS Variables
- Added `--custom-branch-menu-width` variable for setting branch menu width
- Added `--custom-user-menu-width` variable for setting user menu width
### 🌈 Style
- Optimized dashboard style on user homepage
##### More GitHub-like style
- Synced styles when viewing code file content (removed some bottom elements, optimized scrolling experience)
- Adjusted spacing, styles, and font sizes of page elements overall
- Synced dashboard styles under top issues/pull requests/milestones
- Synced styles of milestones/pinned Issues
- Synced page styles of notifications/subscriptions/follows/packages/tooltips/user avatar menus
- Synced branch menu width
- Synced star color for starred repositories
### 🐞 Fix
- Fixed code highlight colors for red-green color blindness theme
- Fixed button underline length for Chinese README in repositories
- Fixed content position on login two-factor authentication page
- Fixed style of operation and maintenance management panel in admin backend
- Reverted editor font size changes to avoid cursor misalignment
- Fixed rounded corners of last row in commit list
- Fixed rounded corners issue in Wiki pages and team menus under secondary navigation bar organization
- Fixed style of issue creation page
- Fixed issue where archive information box is inserted when issue timeline is too long in archived repositories
- Fixed avatar and button icon colors in PR merge operation comments under light theme

View File

@@ -17,8 +17,19 @@ jobs:
npm run build
- name: Create release
run: |
export TZ=Asia/Shanghai
TAG="v$(npm run -s version).$(date +%y%m%d%H%M)"
tar -zcf dist/theme-github-base.tar.gz --remove-files \
dist/theme-github-auto.css dist/theme-github-light.css dist/theme-github-dark.css dist/theme-github-soft-dark.css
tar -zcf dist/theme-github-colorblindness-colorblind.tar.gz --remove-files \
dist/theme-github-colorblind-auto.css dist/theme-github-colorblind-light.css dist/theme-github-colorblind-dark.css
tar -zcf dist/theme-github-colorblindness-tritanopia.tar.gz --remove-files \
dist/theme-github-tritanopia-auto.css dist/theme-github-tritanopia-light.css dist/theme-github-tritanopia-dark.css
tar -zcf dist/theme-github-extra-pink.tar.gz --remove-files \
dist/theme-github-pink-auto.css dist/theme-github-pink-light.css dist/theme-github-pink-dark.css dist/theme-github-pink-soft-dark.css
TAG="v$(npm run -s version)"
gh release create "$TAG" dist/* --notes-file .github/release.md --draft -t $TAG
env:
GH_TOKEN: ${{ github.token }}

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@ dist
node_modules
package-lock.json
.env
.VSCodeCounter

View File

@@ -1,7 +1,171 @@
# 贡献指南
## 目录结构
| 目录 | 说明 |
| ----------------- | ---------------------------- |
| styles | 元素 GitHub 风格 |
| styles/components | 具体页面的元素单独风格 |
| styles/public | 适用大部分页面的元素默认风格 |
| src | 主题生成框架与辅助工具的包 |
| src/core | 主题生成框架 |
| src/functions | 主题辅助工具 |
| src/types | 主题的颜色变量定义 |
| styles | 主题样式 |
| styles/components | 具体页面的元素的样式 |
| styles/public | 基础元素或跨页面的元素的样式 |
| themes | 颜色主题 |
| themes/\<theme> | 具体颜色主题自己的颜色或风格 |
## 贡献说明
不推荐主题样式贡献, 因为 Gitea 主题最终是由单个 CSS 文件提供, 所以会有先后顺序覆盖, 样式影响广泛等问题.
开发者每个人的思路不一样, 审核很难看出这些问题, 会极大增加维护难度.
如果确定理解了 Gitea 的样式布局和我的思路, 请先提交 Issue 确认工作量和预期效果, 然后再开发提交 PR.
如果认为有更好的思路, 欢迎提交 Issue.
> [!IMPORTANT]
>
> 提交 PR 时, 请执行 `npm run commit`
## 开发环境
主题仅依赖于 Node.js 环境, 请确保你的环境中已经安装了 Node.js, 推荐使用 Node.js 20 或以上版本.
请使用 VSCode 开发, 并安装仓库中推荐的插件.
如果不喜欢多余的插件, 请务必安装 `vscode-styled-components` 插件, 此插件用于渲染和检查 TypeScript 中的 CSS 模板字符串.
推荐使用 VSCode 1.102.0 版本以上开发, 此版本以上提供 TypeScript 代码中 16 进制颜色的支持.
## 开发流程
### 安装依赖
```bash
npm install
```
### 设置环境变量
在项目根目录下创建 `.env` 文件, 变量参考 `.env.example` 文件.
环境变量用于发送编译后的主题到服务器上, 快速预览主题.
### 编译主题
编译开发中的主题
```bash
npm run dev
```
编译所有主题
```bash
npm run build
```
格式化项目中的代码
```bash
npm run format
```
用于 PR, 检查并编译项目中的所有代码并进行格式化
```bash
npm run commit
```
## 开发规范
`src`, `styles`, `themes` 为项目的主目录, 主目录下的第一个目录为模块.
主目录或主目录下模块互相引用时, 请使用绝对路径, 例如 `import { defineTheme } from "src"`
模块下的文件互相引用时, 请使用相对路径, 例如 `import { defineTheme } from "./theme"`
## 颜色主题贡献
颜色主题名称格式: `主题名称-dark.css.ts``主题名称-light.css.ts`, 分别表示深色和亮色主题.
如果主题有深色和亮色模式, 会自动生成自动颜色主题, 不需要手动添加.
项目接受自定义主题并会附加到发布的版本中, 但项目所有者不参与维护和审核.
请在颜色主题文件头部附加自己的作者信息, 方便 Issue 提问者找到你 `@`.
推荐使用 `import { defineTheme, type ThemeColor } from "src"` 导入主题生成框架, 声明主题颜色, 然后使用 `defineTheme`
函数生成主题所有 CSS 变量, defineTheme 中设置了一些经过计算得到的 Gitea 变量可以减少工作量, 具体请查看函数说明和定义.
颜色计算函数可以从 `src/functions` 导入, 例如 `import { scaleColorLight } from "src/functions"`, 或者使用 `polished` 库.
例: `themes/主题名称-dark.css.ts`
```ts
/**
* @author 你的名字
* @description 主题描述
*/
import { defineTheme, type ThemeColor } from "src";
export const 主题名称DarkColors: ThemeColor = {
...
}
export default defineTheme(主题名称DarkColors);
// 使用其他主题颜色作为基础
import dark from "themes/dark";
import { darkColors } from "themes/dark";
export const 主题名称DarkColors: ThemeColor = darkColors;
export default defineTheme({
...dark,
...
});
```
如果不需要自定义代码高亮色, 则不传递 chroma 参数, 框架会自动根据主题的暗色或亮色生成代码高亮色.
如果需要完全自定义每个 Gitea 变量, 请导入 `import type { Theme } from "src"`
例: `themes/主题名称-dark.css.ts`
```ts
/**
* @author 你的名字
* @description 主题描述
*/
import type { Theme, Chroma, Primary, Secondary, ... } from "src";
export const primary: Primary = ...;
export const secondary: Secondary =...;
export const chroma: Chroma =...;
...
export default theme: Theme = {
primary,
secondary,
chroma,
...
};
```
完成主题颜色开发后, 请在某个仓库的代码文件列表页, 打开 Code 菜单选择 Tea Cli 进行截图, 并放入 `screenshots`
目录下, 截图名与主题名相同. (推荐克隆本仓库, 避免泄露个人隐私)
然后将截图信息添加到 `README.md` 文件中, 可以在折叠部分中添加自己的说明.
主题颜色复用案例可以参考本主题的色盲主题.
## 主题样式贡献
主题样式使用 TypeScript 的 css 模板字符串开发, 该模板字符串会经过 sass 预处理器处理, 支持 SCSS 语法并且主题只接受 SCSS 嵌套语法, 请不要使用 CSS 语法, 如果一定要用请说明原因.
请尽量不要使用 SCSS 的函数, `vscode-styled-components` 插件会报错, 请使用 TypeScript 相关库处理, 比如主题自带的
`polished` 库.
推荐需要使用复杂处理时, 提取逻辑到 `src/functions` 目录下的函数中, 然后在 `src/styles` 目录下的样式文件中使用.
主题样式中使用到的所有颜色必须使用颜色变量, 颜色变量导入 `import { themeVars } from "src/types/vars"`
涉及到主题自己的颜色变量 `${themeVars.github.xxx}`, 在使用时请将使用的文件和变量添加到对应变量的注释中
`src/types/color/github`
小型圆角(6px)请使用全局圆角变量, 圆角变量导入 `import { otherThemeVars } from "src/types/vars"`
`${otherThemeVars.border.radius}`

132
README.md
View File

@@ -1,31 +1,103 @@
# gitea-github-theme
<p align="center">
中文 |
<a href="./README_EN.md">English</a>
</p>
尽量保持与 GitHub 相同样式的 Gitea 主题
# Gitea GitHub Theme
### 主题说明
## 版本号说明
添加了短暂的过渡动画优化体验(与 GitHub Code 克隆列表动画一致)
主题版本号与 Gitea 版本号保持一致
推荐搭配文件图标浏览器插件一起使用更佳
[github-file-explorer-icons](https://github.com/catppuccin/github-file-explorer-icons)
Gitea 版本号格式: `1.大版本号.小版本号`
Gitea 理论上小版本号变更不会修改前端布局, 所以主题的小版本号适用于所有 Gitea 大版本号相同的 Gitea 版本.
比如: 主题版本 `1.24.5` 适用于 Gitea 版本 `>=1.24.0` `<1.25.0`
仅维护项目发布中的最新的 Gitea 版本, 其他旧版本主题不接受 Issue 和 PR.
> 开发阶段的主题版本号格式: `1.大版本号.小版本号.时间戳`
## 安装
1. 在发布页下载最新的 `theme-github-dark.css` 放入 `gitea/public/assets/css` 目录下
2. 修改 `gitea/conf/app.ini`,并将 `, github` 附加到 `[ui]` 下的 `THEMES` 末尾
1. 在发布页下载最新的 CSS 主题文件放入 `gitea/public/assets/css` 目录下
2. 修改 `gitea/conf/app.ini`,并将 CSS 文件名去掉 `theme-` 的名称附加到 `[ui]` 下的 `THEMES` 末尾
3. 重启 Gitea
4. 在设置中查看主题
> [!IMPORTANT]
>
> 自动颜色主题需要亮色和暗色的主题文件
> [!TIP]
>
> 推荐搭配 Catppuccin 文件图标浏览器插件一起使用更佳
> [github-file-explorer-icons](https://github.com/catppuccin/github-file-explorer-icons)
例: 主题文件名为 `theme-github-dark.css`,则添加 `github-dark``THEMES` 末尾
`gitea/conf/app.ini` 例:
```ini
[ui]
THEMES = gitea-dark, github-dark
THEMES = gitea-auto, gitea-light, gitea-dark, github-auto, github-light, github-dark, github-soft-dark
```
详细请查看 Gitea 文档
[Gitea docs](https://docs.gitea.com/next/administration/customizing-gitea#customizing-the-look-of-gitea)
## 截图
![Dashboard](screenshots/dashboard.png)
### 基本主题
```ini
THEMES = github-auto, github-light, github-dark, github-soft-dark
```
<details>
<summary>Base</summary>
<h4>theme-github-light.css</h4>
<img src="screenshots/light.png"/>
<h4>theme-github-dark.css</h4>
<img src="screenshots/dark.png"/>
<h4>theme-github-soft-dark.css</h4>
<img src="screenshots/soft-dark.png"/>
</details>
### 色盲主题 ( Beta )
```ini
THEMES = github-colorblind-auto, github-colorblind-light, github-colorblind-dark
THEMES = github-tritanopia-auto, github-tritanopia-light, github-tritanopia-dark
```
<details>
<summary>Colorblind & Tritanopia (红绿色盲 & 蓝色盲)</summary>
<h4>theme-github-colorblind-light.css & theme-github-tritanopia-light.css</h4>
<img src="screenshots/colorblind-light.png"/>
<h4>theme-github-colorblind-dark.css & theme-github-tritanopia-dark.css</h4>
<img src="screenshots/colorblind-dark.png"/>
</details>
### 粉色主题
```ini
THEMES = github-pink-auto, github-pink-light, github-pink-dark, github-pink-soft-dark
```
<details>
<summary>Pink</summary>
<h4>theme-github-pink-light.css</h4>
<img src="screenshots/pink/pink-light.png"/>
<h4>theme-github-pink-dark.css</h4>
<img src="screenshots/pink/pink-dark.png"/>
<h4>theme-github-pink-soft-dark.css</h4>
<img src="screenshots/pink/pink-soft-dark.png"/>
</details>
## 自定义 CSS 变量
可以根据自己的偏好自定义主题的一部分样式
@@ -51,31 +123,33 @@ THEMES = gitea-dark, github-dark
### CSS 变量
| 变量名 | 描述 | 默认 | Github | 推荐 | 最小 | 最大 |
| :-------------------------------- | :-------------------------- | :----- | :----- | :---- | :----- | :----- |
| --custom-clone-menu-width | 克隆菜单宽度 | Gitea | 332px | 200px | 150px | 400px |
| --custom-explore-repolist-columns | 探索页面的仓库列表列数 | 2 | 2 | 2 | | |
| --custom-explore-userlist-columns | 探索页面的用户/组织列表列数 | 3 | 1 | 2/3 | | |
| --custom-user-repolist-columns | 用户页面的仓库列表列数 | 2 | 2 | 2 | | |
| --custom-org-repolist-columns | 组织页面的仓库列表列数 | 1 | 1 | 1 | | |
| --custom-org-userlist-columns | 组织页面的用户列表列数 | 2 | 1 | 2 | | |
| 变量名 | 描述 | 默认 | Github | 推荐 | 最小 | 最大 |
| :-------------------------------- | :-------------------------- | :---- | :----- | :---- | :---- | :---- |
| --custom-branch-menu-width | 分支菜单宽度 | 320px | 320px | 320px | Gitea | 640px |
| --custom-clone-menu-width | 克隆按钮的菜单宽度 | Gitea | 332px | 200px | 150px | 400px |
| --custom-user-menu-width | 用户菜单的宽度 | 192px | 256px | | Gitea | 320px |
| --custom-explore-repolist-columns | 探索页面的仓库列表列数 | 2 | 2 | 2 | | |
| --custom-explore-userlist-columns | 探索页面的用户/组织列表列数 | 3 | 1 | 2/3 | | |
| --custom-user-repolist-columns | 用户页面的仓库列表列数 | 2 | 2 | 1/2 | | |
| --custom-org-repolist-columns | 组织页面的仓库列表列数 | 1 | 1 | 1/2 | | |
| --custom-org-userlist-columns | 组织页面的用户列表列数 | 2 | 1 | 1/2 | | |
## 截图
## 使用开发中的主题
![仓库](screenshots/repo.png)
也许你会想使用开发中的主题, 而不是发布的主题
![仓库文件列表](screenshots/file_list.png)
请确保你已经安装了 Node.js 环境, 推荐使用 Node.js 20 或以上版本
![仓库发布](screenshots/release.png)
```bash
git clone https://github.com/lutinglt/gitea-github-theme.git
cd gitea-github-theme
npm install
npm run build
```
![仓库提交](screenshots/commit.png)
![Actions](screenshots/actions.png)
![Action](screenshots/action.png)
![Dispatch](screenshots/dispatch.png)
编译完成后, 会在 `dist` 目录下生成主题文件, 你可以将主题文件放入 `gitea/public/assets/css` 目录下, 然后在
`gitea/conf/app.ini` 中添加主题名称到 `THEMES` 末尾
## 贡献
欢迎提交 Issue 或 Pull Request
请查看 [CONTRIBUTING](CONTRIBUTING.md)

159
README_EN.md Normal file
View File

@@ -0,0 +1,159 @@
<p align="center">
<a href="./README.md">中文</a> |
English
</p>
# Gitea GitHub Theme
## Version Number Explanation
The theme version number is kept consistent with the Gitea version number
Gitea version number format: `1.major.minor`
Theoretically, minor version changes in Gitea do not modify the frontend layout, so the minor version of the theme is
applicable to all Gitea versions with the same major version number.
For example: Theme version `1.24.5` is applicable to Gitea versions `>=1.24.0` `<1.25.0`
Only the latest released Gitea version is maintained. Issues and PRs for other older theme versions will not be
accepted.
> Development stage theme version number format: `1.major.minor.timestamp`
## Installation
1. Download the latest CSS theme file from the release page and place it in the `gitea/public/assets/css` directory
2. Modify `gitea/conf/app.ini` and append the CSS filename without the `theme-` prefix to the end of `THEMES` under the
`[ui]` section
3. Restart Gitea
4. Check the theme in the settings
> [!IMPORTANT]
>
> Automatic color theme requires both light and dark theme files.
> [!TIP]
>
> Recommend using Catppuccin file icon browser plugin together for better performance.
> [github-file-explorer-icons](https://github.com/catppuccin/github-file-explorer-icons)
Example: If the theme filename is `theme-github-dark.css`, add `github-dark` to the end of `THEMES`
Example `gitea/conf/app.ini`:
```ini
[ui]
THEMES = gitea-auto, gitea-light, gitea-dark, github-auto, github-light, github-dark, github-soft-dark
```
For details, please refer to the Gitea documentation
[Gitea docs](https://docs.gitea.com/next/administration/customizing-gitea#customizing-the-look-of-gitea)
## Screenshots
![Dashboard](screenshots/en/dashboard-en.png)
### Basic Themes
```ini
THEMES = github-auto, github-light, github-dark, github-soft-dark
```
<details>
<summary>Base</summary>
<h4>theme-github-light.css</h4>
<img src="screenshots/en/light.png"/>
<h4>theme-github-dark.css</h4>
<img src="screenshots/en/dark.png"/>
<h4>theme-github-soft-dark.css</h4>
<img src="screenshots/en/soft-dark.png"/>
</details>
### Colorblind Themes (Beta)
```ini
THEMES = github-colorblind-auto, github-colorblind-light, github-colorblind-dark
THEMES = github-tritanopia-auto, github-tritanopia-light, github-tritanopia-dark
```
<details>
<summary>Colorblind & Tritanopia</summary>
<h4>theme-github-colorblind-light.css & theme-github-tritanopia-light.css</h4>
<img src="screenshots/en/colorblind-light.png"/>
<h4>theme-github-colorblind-dark.css & theme-github-tritanopia-dark.css</h4>
<img src="screenshots/en/colorblind-dark.png"/>
</details>
### Pink Themes
```ini
THEMES = github-pink-auto, github-pink-light, github-pink-dark, github-pink-soft-dark
```
<details>
<summary>Pink</summary>
<h4>theme-github-pink-light.css</h4>
<img src="screenshots/pink/en/pink-light-en.png"/>
<h4>theme-github-pink-dark.css</h4>
<img src="screenshots/pink/en/pink-dark-en.png"/>
<h4>theme-github-pink-soft-dark.css</h4>
<img src="screenshots/pink/en/pink-soft-dark-en.png"/>
</details>
## Custom CSS Variables
You can customize parts of the theme style according to your preferences
### Usage Method
Add the following code at the beginning or end of the theme's CSS file
```css
:root {
--custom-clone-menu-width: 150px;
...
}
```
> [!IMPORTANT]
>
> Please ensure to add custom variables in the `:root` selector, otherwise they will not take effect
>
> Variables are separated by `;`
>
> It is recommended to place custom variables in a separate file and append them to the theme file using shell commands
> or other methods
### CSS Variables
| Variable Name | Description | Default | Github | Recommend | Min | Max |
| :-------------------------------- | :------------------------------------------------------- | :------ | :----- | :-------- | :---- | :---- |
| --custom-branch-menu-width | Branch menu width | 320px | 320px | 320px | Gitea | 640px |
| --custom-clone-menu-width | Clone button menu width | Gitea | 332px | 200px | 150px | 400px |
| --custom-user-menu-width | User menu width | 192px | 200px | | Gitea | 320px |
| --custom-explore-repolist-columns | Number of repository list columns on explore page | 2 | 2 | 2 | | |
| --custom-explore-userlist-columns | Number of user/organization list columns on explore page | 3 | 1 | 2/3 | | |
| --custom-user-repolist-columns | Number of repository list columns on user page | 2 | 2 | 1/2 | | |
| --custom-org-repolist-columns | Number of repository list columns on organization page | 1 | 1 | 1/2 | | |
| --custom-org-userlist-columns | Number of user list columns on organization page | 2 | 1 | 1/2 | | |
## Using Development Version of the Theme
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 20 or above is recommended
```bash
git clone https://github.com/lutinglt/gitea-github-theme.git
cd gitea-github-theme
npm install
npm run build
```
After compilation, theme files will be generated in the `dist` directory. You can place the theme files into the
`gitea/public/assets/css` directory, then add the theme name to the end of `THEMES` in `gitea/conf/app.ini`
## Contribution
Please refer to [CONTRIBUTING](CONTRIBUTING.md)

14
TODO.md
View File

@@ -1,14 +0,0 @@
### 重大
- gitea issue 默认标签颜色匹配使用 github 样式
- issue/PR 列表样式 github 布局
- styles/themes 库组件导出整理
- defineTheme 颜色生成代码重构
- 亮色主题适配/测试
- 自动颜色主题生成
- github primer 官方库集成
### 其他
- README 更新/截图更新
- CONTRIBUTING 更新

View File

@@ -1,7 +1,6 @@
{
"name": "gitea-github-theme",
"version": "1.24.4",
"description": "A theme to make Gitea look and feel like GitHub",
"version": "1.24.6",
"type": "module",
"scripts": {
"dev": "vite build --mode dev",

BIN
screenshots/action.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

BIN
screenshots/colorblind-dark.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

BIN
screenshots/colorblind-light.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

BIN
screenshots/commit.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 394 KiB

BIN
screenshots/dark.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

BIN
screenshots/dashboard.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

BIN
screenshots/en/dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 KiB

BIN
screenshots/en/light.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 KiB

BIN
screenshots/light.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

BIN
screenshots/repo.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 KiB

BIN
screenshots/soft-dark.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

64
src/core/chroma.ts Normal file
View File

@@ -0,0 +1,64 @@
import { prettylights2Chroma, type prettylightsColor } from "./prettylights";
export const lightPrettylights: prettylightsColor = {
syntax: {
brackethighlighter: { angle: "#59636e", unmatched: "#82071e" },
carriage: { return: { bg: "#cf222e", text: "#f6f8fa" } },
comment: "#59636e",
constant: "#0550ae",
constantOtherReferenceLink: "#0a3069",
entity: "#6639ba",
entityTag: "#0550ae",
invalid: { illegal: { bg: "#82071e", text: "#f6f8fa" } },
keyword: "#cf222e",
markup: {
bold: "#1f2328",
changed: { bg: "#ffd8b5", text: "#953800" },
deleted: { bg: "#ffebe9", text: "#82071e" },
heading: "#0550ae",
ignored: { bg: "#0550ae", text: "#d1d9e0" },
inserted: { bg: "#dafbe1", text: "#116329" },
italic: "#1f2328",
list: "#3b2300",
},
metaDiffRange: "#8250df",
storageModifierImport: "#1f2328",
string: "#0a3069",
stringRegexp: "#116329",
sublimelinterGutterMark: "#818b98",
variable: "#953800",
},
};
export const darkPrettylights: prettylightsColor = {
syntax: {
brackethighlighter: { angle: "#9198a1", unmatched: "#f85149" },
carriage: { return: { bg: "#b62324", text: "#f0f6fc" } },
comment: "#9198a1",
constant: "#79c0ff",
constantOtherReferenceLink: "#a5d6ff",
entity: "#d2a8ff",
entityTag: "#7ee787",
invalid: { illegal: { bg: "#8e1519", text: "#f0f6fc" } },
keyword: "#ff7b72",
markup: {
bold: "#f0f6fc",
changed: { bg: "#5a1e02", text: "#ffdfb6" },
deleted: { bg: "#67060c", text: "#ffdcd7" },
heading: "#1f6feb",
ignored: { bg: "#1158c7", text: "#f0f6fc" },
inserted: { bg: "#033a16", text: "#aff5b4" },
italic: "#f0f6fc",
list: "#f2cc60",
},
metaDiffRange: "#d2a8ff",
storageModifierImport: "#f0f6fc",
string: "#a5d6ff",
stringRegexp: "#7ee787",
sublimelinterGutterMark: "#3d444d",
variable: "#ffa657",
},
};
export const defaultLightChroma = prettylights2Chroma(lightPrettylights);
export const defaultDarkChroma = prettylights2Chroma(darkPrettylights);

View File

@@ -1,10 +1,11 @@
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 { defaultDarkChroma, defaultLightChroma } from "./chroma";
import type { Theme } from "./theme";
type ThemeColor = {
export type ThemeColor = {
/** 用于标识当前是否为暗色主题: `true` 暗色 `false` 亮色 */
isDarkTheme: boolean;
/** 主色调(强调色) */
@@ -13,38 +14,41 @@ type ThemeColor = {
primaryContrast: string;
/** 副色调(边框色) */
secondary: string;
/** 色 */
red: string;
/** 色 */
orange: string;
/** 色 */
yellow: string;
/** 黄绿色/橄榄色 */
olive: string;
/** 绿色 */
green: string;
/** 绿色/青色(偏绿) */
teal: string;
/** 蓝绿色/青色(偏) */
cyan: string;
/** 蓝 */
blue: string;
/** 蓝紫色/紫罗兰色 */
violet: string;
/** 色 */
purple: string;
/** 粉红色 */
pink: string;
/** 色 */
brown: string;
/** 色 */
black: string;
/** 色 */
grey: string;
/** 色 */
gold: string;
/** 色 */
white: string;
/** 基础颜色 */
base: {
/** 色 */
red: string;
/** 色 */
orange: string;
/** 黄色 */
yellow: string;
/** 黄绿色/橄榄色 */
olive: string;
/** 绿色 */
green: string;
/** 蓝绿色/青色(偏绿) */
teal: string;
/** 蓝绿色/青色(偏蓝) */
cyan: string;
/** 蓝色 */
blue: string;
/** 蓝紫色/紫罗兰色 */
violet: string;
/** 色 */
purple: string;
/** 粉红色 */
pink: string;
/** 色 */
brown: string;
/** 色 */
black: string;
/** 色 */
grey: string;
/** 色 */
gold: string;
/** 白色 */
white: string;
};
/** Action 日志 */
console: Console;
/** 提交代码对比 */
@@ -57,8 +61,8 @@ type ThemeColor = {
/** 定义颜色, 用于生成颜色主题
* @example
* 文件名: "dark.css.tsx"
* import type { Console, Diff, Other } from "src/types";
* 文件名: "dark.css.ts"
* import type { Console, Diff, Other, Github } from "src/types";
* import { defineTheme, themeVars } from "src";
*
* const console: Console = {
@@ -70,7 +74,6 @@ type ThemeColor = {
* ...
* }
* ...
* // 会经过 lightningcss 打包处理生成最终的 CSS
* export default defineTheme({
* isDarkTheme: true,
* primary: "#0969da",
@@ -78,9 +81,10 @@ type ThemeColor = {
* console,
* diff,
* other,
* github,
* })
*/
export function defineTheme(themeColor: ThemeColor): Theme {
export function defineTheme(themeColor: ThemeColor, chroma?: Chroma): Theme {
const brightDir = themeColor.isDarkTheme ? -1 : 1;
const primary: Primary = {
@@ -160,161 +164,187 @@ export function defineTheme(themeColor: ThemeColor): Theme {
const named: Named = {
red: {
self: themeColor.red,
light: themeColor.isDarkTheme ? scaleColorLight(themeColor.red, 15) : scaleColorLight(themeColor.red, 25),
self: themeColor.base.red,
light: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.red, 15)
: scaleColorLight(themeColor.base.red, 25),
dark: {
num1: scaleColorLight(themeColor.red, -10),
num2: scaleColorLight(themeColor.red, -20),
num1: scaleColorLight(themeColor.base.red, -10),
num2: scaleColorLight(themeColor.base.red, -20),
},
badge: {
self: themeColor.red,
bg: rgba(themeColor.red, 0.1),
self: themeColor.base.red,
bg: rgba(themeColor.base.red, 0.1),
hover: {
bg: rgba(themeColor.red, 0.3),
bg: rgba(themeColor.base.red, 0.3),
},
},
},
orange: {
self: themeColor.orange,
light: themeColor.isDarkTheme ? scaleColorLight(themeColor.orange, 15) : scaleColorLight(themeColor.orange, 25),
self: themeColor.base.orange,
light: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.orange, 15)
: scaleColorLight(themeColor.base.orange, 25),
dark: {
num1: scaleColorLight(themeColor.orange, -10),
num2: scaleColorLight(themeColor.orange, -20),
num1: scaleColorLight(themeColor.base.orange, -10),
num2: scaleColorLight(themeColor.base.orange, -20),
},
badge: {
self: themeColor.orange,
bg: rgba(themeColor.orange, 0.1),
self: themeColor.base.orange,
bg: rgba(themeColor.base.orange, 0.1),
hover: {
bg: rgba(themeColor.orange, 0.3),
bg: rgba(themeColor.base.orange, 0.3),
},
},
},
yellow: {
self: themeColor.yellow,
light: themeColor.isDarkTheme ? scaleColorLight(themeColor.yellow, 15) : scaleColorLight(themeColor.yellow, 25),
self: themeColor.base.yellow,
light: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.yellow, 15)
: scaleColorLight(themeColor.base.yellow, 25),
dark: {
num1: scaleColorLight(themeColor.yellow, -10),
num2: scaleColorLight(themeColor.yellow, -20),
num1: scaleColorLight(themeColor.base.yellow, -10),
num2: scaleColorLight(themeColor.base.yellow, -20),
},
badge: {
self: themeColor.yellow,
bg: rgba(themeColor.yellow, 0.1),
self: themeColor.base.yellow,
bg: rgba(themeColor.base.yellow, 0.1),
hover: {
bg: rgba(themeColor.yellow, 0.3),
bg: rgba(themeColor.base.yellow, 0.3),
},
},
},
olive: {
self: themeColor.olive,
light: themeColor.isDarkTheme ? scaleColorLight(themeColor.olive, 15) : scaleColorLight(themeColor.olive, 25),
self: themeColor.base.olive,
light: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.olive, 15)
: scaleColorLight(themeColor.base.olive, 25),
dark: {
num1: scaleColorLight(themeColor.olive, -10),
num2: scaleColorLight(themeColor.olive, -20),
num1: scaleColorLight(themeColor.base.olive, -10),
num2: scaleColorLight(themeColor.base.olive, -20),
},
},
green: {
self: themeColor.green,
light: themeColor.isDarkTheme ? scaleColorLight(themeColor.green, 15) : scaleColorLight(themeColor.green, 25),
self: themeColor.base.green,
light: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.green, 15)
: scaleColorLight(themeColor.base.green, 25),
dark: {
num1: scaleColorLight(themeColor.green, -10),
num2: scaleColorLight(themeColor.green, -20),
num1: scaleColorLight(themeColor.base.green, -10),
num2: scaleColorLight(themeColor.base.green, -20),
},
badge: {
self: themeColor.green,
bg: rgba(themeColor.green, 0.1),
self: themeColor.base.green,
bg: rgba(themeColor.base.green, 0.1),
hover: {
bg: rgba(themeColor.green, 0.3),
bg: rgba(themeColor.base.green, 0.3),
},
},
},
teal: {
self: themeColor.teal,
light: themeColor.isDarkTheme ? scaleColorLight(themeColor.teal, 15) : scaleColorLight(themeColor.teal, 25),
self: themeColor.base.teal,
light: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.teal, 15)
: scaleColorLight(themeColor.base.teal, 25),
dark: {
num1: scaleColorLight(themeColor.teal, -10),
num2: scaleColorLight(themeColor.teal, -20),
num1: scaleColorLight(themeColor.base.teal, -10),
num2: scaleColorLight(themeColor.base.teal, -20),
},
},
blue: {
self: themeColor.blue,
light: themeColor.isDarkTheme ? scaleColorLight(themeColor.blue, 15) : scaleColorLight(themeColor.blue, 25),
self: themeColor.base.blue,
light: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.blue, 15)
: scaleColorLight(themeColor.base.blue, 25),
dark: {
num1: scaleColorLight(themeColor.blue, -10),
num2: scaleColorLight(themeColor.blue, -20),
num1: scaleColorLight(themeColor.base.blue, -10),
num2: scaleColorLight(themeColor.base.blue, -20),
},
},
violet: {
self: themeColor.violet,
light: themeColor.isDarkTheme ? scaleColorLight(themeColor.violet, 15) : scaleColorLight(themeColor.violet, 25),
self: themeColor.base.violet,
light: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.violet, 15)
: scaleColorLight(themeColor.base.violet, 25),
dark: {
num1: scaleColorLight(themeColor.violet, -10),
num2: scaleColorLight(themeColor.violet, -20),
num1: scaleColorLight(themeColor.base.violet, -10),
num2: scaleColorLight(themeColor.base.violet, -20),
},
},
purple: {
self: themeColor.purple,
light: themeColor.isDarkTheme ? scaleColorLight(themeColor.purple, 15) : scaleColorLight(themeColor.purple, 25),
self: themeColor.base.purple,
light: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.purple, 15)
: scaleColorLight(themeColor.base.purple, 25),
dark: {
num1: scaleColorLight(themeColor.purple, -10),
num2: scaleColorLight(themeColor.purple, -20),
num1: scaleColorLight(themeColor.base.purple, -10),
num2: scaleColorLight(themeColor.base.purple, -20),
},
},
pink: {
self: themeColor.pink,
light: themeColor.isDarkTheme ? scaleColorLight(themeColor.pink, 15) : scaleColorLight(themeColor.pink, 25),
self: themeColor.base.pink,
light: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.pink, 15)
: scaleColorLight(themeColor.base.pink, 25),
dark: {
num1: scaleColorLight(themeColor.pink, -10),
num2: scaleColorLight(themeColor.pink, -20),
num1: scaleColorLight(themeColor.base.pink, -10),
num2: scaleColorLight(themeColor.base.pink, -20),
},
},
brown: {
self: themeColor.brown,
light: themeColor.isDarkTheme ? scaleColorLight(themeColor.brown, 15) : scaleColorLight(themeColor.brown, 25),
self: themeColor.base.brown,
light: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.brown, 15)
: scaleColorLight(themeColor.base.brown, 25),
dark: {
num1: scaleColorLight(themeColor.brown, -10),
num2: scaleColorLight(themeColor.brown, -20),
num1: scaleColorLight(themeColor.base.brown, -10),
num2: scaleColorLight(themeColor.base.brown, -20),
},
},
black: {
self: themeColor.black,
light: themeColor.isDarkTheme ? scaleColorLight(themeColor.black, 15) : scaleColorLight(themeColor.black, 25),
self: themeColor.base.black,
light: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.black, 15)
: scaleColorLight(themeColor.base.black, 25),
dark: {
num1: scaleColorLight(themeColor.black, -10),
num2: scaleColorLight(themeColor.black, -20),
num1: scaleColorLight(themeColor.base.black, -10),
num2: scaleColorLight(themeColor.base.black, -20),
},
},
grey: {
self: themeColor.grey,
light: themeColor.isDarkTheme ? scaleColorLight(themeColor.grey, 15) : scaleColorLight(themeColor.grey, 25),
self: themeColor.base.grey,
light: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.grey, 15)
: scaleColorLight(themeColor.base.grey, 25),
},
gold: themeColor.gold,
white: themeColor.white,
gold: themeColor.base.gold,
white: themeColor.base.white,
};
const message: Message = {
error: {
bg: {
self: rgba(themeColor.red, 0.1),
active: rgba(themeColor.red, 0.5),
hover: rgba(themeColor.red, 0.3),
self: rgba(themeColor.base.red, 0.1),
active: rgba(themeColor.base.red, 0.5),
hover: rgba(themeColor.base.red, 0.3),
},
border: rgba(themeColor.red, 0.4),
text: saturate(0.2, themeColor.red), // 饱和度提高
border: rgba(themeColor.base.red, 0.4),
text: saturate(0.2, themeColor.base.red), // 饱和度提高
},
success: {
bg: rgba(themeColor.green, 0.1),
border: rgba(themeColor.green, 0.4),
text: saturate(0.2, themeColor.green),
bg: rgba(themeColor.base.green, 0.1),
border: rgba(themeColor.base.green, 0.4),
text: saturate(0.2, themeColor.base.green),
},
warning: {
bg: rgba(themeColor.yellow, 0.1),
border: rgba(themeColor.yellow, 0.4),
text: saturate(0.2, themeColor.yellow),
bg: rgba(themeColor.base.yellow, 0.1),
border: rgba(themeColor.base.yellow, 0.4),
text: saturate(0.2, themeColor.base.yellow),
},
info: {
bg: rgba(themeColor.blue, 0.1),
border: rgba(themeColor.blue, 0.4),
text: saturate(0.2, themeColor.blue),
bg: rgba(themeColor.base.blue, 0.1),
border: rgba(themeColor.base.blue, 0.4),
text: saturate(0.2, themeColor.base.blue),
},
};
@@ -325,7 +355,7 @@ export function defineTheme(themeColor: ThemeColor): Theme {
yellow: themeVars.color.yellow.self,
blue: themeVars.color.blue.self,
magenta: themeVars.color.pink.self,
cyan: themeColor.cyan,
cyan: themeColor.base.cyan,
white: themeVars.color.console.fg.subtle,
bright: {
black: themeVars.color.black.light,
@@ -334,13 +364,16 @@ export function defineTheme(themeColor: ThemeColor): Theme {
yellow: themeVars.color.yellow.light,
blue: themeVars.color.blue.light,
magenta: themeVars.color.pink.light,
cyan: themeColor.isDarkTheme ? scaleColorLight(themeColor.cyan, 10) : scaleColorLight(themeColor.cyan, 25),
cyan: themeColor.isDarkTheme
? scaleColorLight(themeColor.base.cyan, 10)
: scaleColorLight(themeColor.base.cyan, 25),
white: themeVars.color.console.fg.self,
},
};
return {
isDarkTheme: themeColor.isDarkTheme.toString(),
chroma: chroma || (themeColor.isDarkTheme ? defaultDarkChroma : defaultLightChroma),
color: {
primary,
secondary,

85
src/core/display.ts Normal file
View File

@@ -0,0 +1,85 @@
import { saturate } from "polished";
import { scaleColorLight } from "src/functions";
import { type GithubColor } from "./github";
export type DisplayColor = {
num0: string;
num1: string;
num2: string;
num3: string;
num4: string;
num5: string;
num6: string;
num7: string;
num8: string;
num9: string;
};
export function display2GithubColor(
displayColor: DisplayColor,
baseGithubColor: GithubColor,
soft?: boolean
): GithubColor {
return {
...baseGithubColor,
diffBlob: {
...baseGithubColor.diffBlob,
hunkNum: { bgColor: { rest: soft ? displayColor.num2 : displayColor.num1 } },
},
fgColor: {
...baseGithubColor.fgColor,
accent: soft ? displayColor.num7 : displayColor.num6,
},
bgColor: {
...baseGithubColor.bgColor,
accent: {
emphasis: soft ? saturate(-0.1, scaleColorLight(displayColor.num5, -2)) : displayColor.num5,
muted: soft ? displayColor.num1 : displayColor.num0,
},
},
borderColor: {
...baseGithubColor.borderColor,
accent: {
emphasis: soft ? displayColor.num6 : displayColor.num5,
},
},
button: {
...baseGithubColor.button,
primary: {
...baseGithubColor.button.primary,
fgColor: {
...baseGithubColor.button.primary.fgColor,
accent: soft ? displayColor.num7 : displayColor.num6,
},
bgColor: {
...baseGithubColor.button.primary.bgColor,
rest: soft ? saturate(-0.1, scaleColorLight(displayColor.num5, -2)) : displayColor.num5,
hover: soft ? saturate(-0.1, scaleColorLight(displayColor.num5, -7)) : scaleColorLight(displayColor.num5, 5),
},
},
star: {
iconColor: soft
? scaleColorLight(displayColor.num6, -2)
: saturate(0.1, scaleColorLight(displayColor.num6, -2)),
},
},
underlineNav: {
borderColor: {
active: soft ? scaleColorLight(saturate(0.1, displayColor.num6), -5) : saturate(0.2, displayColor.num6),
},
},
contribution: {
...baseGithubColor.contribution,
default: {
...baseGithubColor.contribution.default,
bgColor: {
num0: baseGithubColor.contribution.default.bgColor.num0,
num1: soft ? displayColor.num2 : displayColor.num1,
num2: soft ? displayColor.num3 : displayColor.num2,
num3: soft ? displayColor.num5 : displayColor.num4,
num4: soft ? displayColor.num7 : displayColor.num6,
},
},
},
};
}

View File

@@ -1,12 +1,14 @@
import { saturate } from "polished";
import type { Console, Diff, Other } from "src";
import { scaleColorLight } from "src/functions";
import type { Github } from "src/types";
import { themeVars } from "src/types/vars";
import { defineTheme } from "./color";
import type { Theme } from "./theme";
import { type ThemeColor } from "./color";
export type GithubColor = {
isDarkTheme: boolean;
display: {
blue: { fgColor: string };
brown: { fgColor: string };
cyan: { fgColor: string };
indigo: { fgColor: string };
@@ -35,115 +37,50 @@ export type GithubColor = {
black: string;
white: string;
muted: string;
onEmphasis: string;
};
bgColor: {
accent: {
emphasis: string;
muted: string;
};
attention: {
muted: string;
};
success: {
emphasis: string;
muted: string;
};
danger: {
muted: string;
};
done: {
emphasis: string;
};
accent: { emphasis: string; muted: string };
attention: { muted: string };
emphasis: string;
success: { emphasis: string; muted: string };
danger: { muted: string };
done: { emphasis: string };
default: string;
inset: string;
muted: string;
neutral: {
muted: string;
};
neutral: { muted: string };
};
borderColor: {
accent: {
emphasis: string;
};
attention: {
emphasis: string;
};
accent: { emphasis: string };
attention: { emphasis: string };
default: string;
success: {
emphasis: string;
};
done: {
emphasis: string;
};
success: { emphasis: string };
done: { emphasis: string };
muted: string;
translucent: string;
};
button: {
primary: {
fgColor: {
accent: string;
rest: string;
};
bgColor: {
rest: string;
hover: string;
};
};
danger: {
fgColor: {
rest: string;
hover: string;
};
bgColor: {
hover: string;
};
};
primary: { fgColor: { accent: string; rest: string }; bgColor: { rest: string; hover: string } };
danger: { fgColor: { rest: string; hover: string }; bgColor: { hover: string } };
star: { iconColor: string };
};
control: {
bgColor: {
active: string;
hover: string;
rest: string;
};
transparent: {
bgColor: {
active: string;
hover: string;
selected: string;
};
};
};
shadow: {
floating: string;
};
overlay: {
backdrop: {
bgColor: string;
};
};
underlineNav: {
borderColor: {
active: string;
};
bgColor: { active: string; hover: string; rest: string };
transparent: { bgColor: { active: string; hover: string; selected: string } };
};
shadow: { floating: { small: string }; resting: { small: string } };
overlay: { backdrop: { bgColor: string } };
underlineNav: { borderColor: { active: string } };
contribution: {
default: {
bgColor: {
num0: string;
num1: string;
num2: string;
num3: string;
num4: string;
num5: string;
};
borderColor: {
num0: string;
};
bgColor: { num0: string; num1: string; num2: string; num3: string; num4: string };
borderColor: { num0: string };
};
};
};
export function defineGithubTheme(githubColor: GithubColor): Theme {
export function github2ThemeColor(githubColor: GithubColor): ThemeColor {
const console: Console = {
fg: {
self: githubColor.fgColor.default,
@@ -244,7 +181,7 @@ export function defineGithubTheme(githubColor: GithubColor): Theme {
button: githubColor.control.bgColor.rest,
codeBg: "unset",
shadow: {
self: githubColor.shadow.floating,
self: githubColor.shadow.floating.small,
opaque: themeVars.color.shadow.self,
},
secondaryBg: "unset",
@@ -259,8 +196,8 @@ export function defineGithubTheme(githubColor: GithubColor): Theme {
activeBg: githubColor.bgColor.accent.muted,
},
tooltip: {
text: githubColor.fgColor.default,
bg: githubColor.bgColor.default,
text: githubColor.fgColor.onEmphasis,
bg: githubColor.bgColor.emphasis,
},
nav: {
bg: githubColor.bgColor.inset,
@@ -323,7 +260,10 @@ export function defineGithubTheme(githubColor: GithubColor): Theme {
},
primary: {
fgColor: {
accent: githubColor.button.primary.fgColor.accent,
accent: saturate(
0.1,
scaleColorLight(githubColor.button.primary.fgColor.accent, githubColor.isDarkTheme ? 10 : -10)
),
rest: githubColor.button.primary.fgColor.rest,
},
bgColor: {
@@ -348,6 +288,9 @@ export function defineGithubTheme(githubColor: GithubColor): Theme {
hover: githubColor.borderColor.translucent,
},
},
star: {
iconColor: githubColor.button.star.iconColor,
},
},
control: {
bgColor: {
@@ -363,6 +306,9 @@ export function defineGithubTheme(githubColor: GithubColor): Theme {
floating: {
small: `0px 0px 0px 1px ${themeVars.color.light.border}, 0px 6px 12px -3px ${themeVars.color.shadow.self}, 0px 6px 18px 0px ${themeVars.color.shadow.self};`,
},
resting: {
small: `0px 1px 1px 0px ${githubColor.shadow.resting.small}, 0px 1px 3px 0px ${githubColor.shadow.resting.small};`,
},
},
underlineNav: {
borderColor: {
@@ -377,7 +323,10 @@ export function defineGithubTheme(githubColor: GithubColor): Theme {
num2: githubColor.contribution.default.bgColor.num2,
num3: githubColor.contribution.default.bgColor.num3,
num4: githubColor.contribution.default.bgColor.num4,
num5: githubColor.contribution.default.bgColor.num5,
num5: saturate(
0.2,
scaleColorLight(githubColor.contribution.default.bgColor.num4, githubColor.isDarkTheme ? 58 : -58)
),
},
borderColor: {
num0: githubColor.contribution.default.borderColor.num0,
@@ -390,30 +339,32 @@ export function defineGithubTheme(githubColor: GithubColor): Theme {
},
},
};
return defineTheme({
return {
isDarkTheme: githubColor.isDarkTheme,
primary: githubColor.fgColor.accent,
primaryContrast: githubColor.fgColor.default,
secondary: githubColor.borderColor.default,
red: githubColor.fgColor.danger,
orange: githubColor.fgColor.severe,
yellow: githubColor.fgColor.attention,
olive: githubColor.display.olive.fgColor,
green: githubColor.fgColor.success,
cyan: githubColor.display.cyan.fgColor,
teal: githubColor.display.teal.fgColor,
blue: githubColor.fgColor.accent,
violet: githubColor.display.indigo.fgColor,
purple: githubColor.fgColor.done,
pink: githubColor.fgColor.sponsors,
brown: githubColor.display.brown.fgColor,
black: githubColor.fgColor.black,
grey: githubColor.fgColor.neutral,
gold: githubColor.display.lemon.fgColor,
white: githubColor.fgColor.white,
base: {
red: githubColor.fgColor.danger,
orange: githubColor.fgColor.severe,
yellow: githubColor.fgColor.attention,
olive: githubColor.display.olive.fgColor,
green: githubColor.fgColor.success,
cyan: githubColor.display.cyan.fgColor,
teal: githubColor.display.teal.fgColor,
blue: githubColor.display.blue.fgColor,
violet: githubColor.display.indigo.fgColor,
purple: githubColor.fgColor.done,
pink: githubColor.fgColor.sponsors,
brown: githubColor.display.brown.fgColor,
black: githubColor.fgColor.black,
grey: githubColor.fgColor.neutral,
gold: githubColor.display.lemon.fgColor,
white: githubColor.fgColor.white,
},
console,
diff,
other,
github,
});
};
}

127
src/core/prettylights.ts Normal file
View File

@@ -0,0 +1,127 @@
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.constant,
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,
},
};
}

View File

@@ -1,18 +1,11 @@
import { createGlobalTheme, globalKeyframes, globalStyle } from "@vanilla-extract/css";
import { otherThemeVars, themeVars } from "src/types/vars";
import { createGlobalTheme, globalStyle } from "@vanilla-extract/css";
import fs from "node:fs";
import path from "node:path";
import { otherThemeVars, themeInfoVars, themeVars } from "src/types/vars";
import type { MapLeafNodes, WithOptionalLayer } from "./types";
export type Theme = WithOptionalLayer<MapLeafNodes<typeof themeVars, string>>;
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";
@@ -41,16 +34,22 @@ const emoji = `
.emoji[aria-label="musical notes"]
`;
// 版本号: 版本号.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");
const pkgPath = path.join(__dirname, "../..", "package.json");
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
const version = `"${pkg.version}.${year}${month}${day}"`;
export function createTheme(theme: Theme): void {
const isDarkTheme = stringToBoolean(theme.isDarkTheme, "isDarkTheme");
if (isDarkTheme) {
globalStyle(emoji, { filter: "invert(100%) hue-rotate(180deg)" });
}
const isDarkTheme: boolean = JSON.parse(theme.isDarkTheme);
createGlobalTheme(":root", themeInfoVars, { version });
createGlobalTheme(":root", themeVars, theme);
createGlobalTheme(":root", otherThemeVars, {
border: {
radius: "6px",
},
border: { radius: "6px" },
color: {
git: "#f05133",
light: {
@@ -64,12 +63,5 @@ export function createTheme(theme: Theme): void {
accentColor: themeVars.color.accent,
colorScheme: isDarkTheme ? "dark" : "light",
});
globalKeyframes(overlayAppearDown, {
"0%": { opacity: 0, transform: "translateY(-8px)" },
"100%": { opacity: 1, transform: "translateY(0)" },
});
globalKeyframes(overlayAppearUp, {
"0%": { opacity: 0, transform: "translateY(8px)" },
"100%": { opacity: 1, transform: "translateY(0)" },
});
if (isDarkTheme) globalStyle(emoji, { filter: "invert(100%) hue-rotate(180deg)" });
}

View File

@@ -50,6 +50,11 @@ export function themeInput(outDir: string, themeDir: string, mode: string): { [k
return input;
}
function giteaThemeMetaInfo(nameGroup: string[]): string {
const displayName = nameGroup.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
return `gitea-theme-meta-info{--theme-display-name:"GitHub ${displayName}";}`; // 不要省略分号, 也不要追加任何变量, 否则 Gitea 不识别
}
const prefix = "theme-github-";
/**
@@ -78,23 +83,46 @@ export function themePlugin(): Plugin {
for (const [key, value] of Object.entries(bundle)) {
// 仅为了类型检查, 逻辑上输出中全是 asset 类型
if (value.type === "asset") {
const name = `${prefix}${value.names[0]}`;
const name = `${prefix}${key}`;
const fileName = `${prefix}${value.fileName}`;
const originalFileName = value.originalFileNames.pop();
const type = value.type;
const source = `${styles}${value.source.toString()}`;
// 合并样式文件和主题信息
const meta = giteaThemeMetaInfo(key.split(".")[0].split("-"));
const source = `${meta}${value.source.toString()}${styles}`;
// 添加主题到输出
this.emitFile({ name, fileName, source, type, originalFileName });
// 自动颜色主题
const isDark = key.endsWith("dark.css");
const darkName = key.replace("light", "dark");
const lightName = darkName.replace("dark", "light");
const findTheme = isDark ? lightName : darkName;
if (findTheme in bundle) {
const autoName = `${prefix}${darkName.replace("dark", "auto")}`;
const lightContent = `@import "./${prefix}${lightName}" (prefers-color-scheme: light);`;
const darkContent = `@import "./${prefix}${darkName}" (prefers-color-scheme: dark);`;
const nameGroup = key.split(".")[0].split("-").slice(0, -1);
nameGroup.push("auto");
const metaInfo = giteaThemeMetaInfo(nameGroup);
this.emitFile({
name: autoName,
fileName: autoName,
type: "asset",
source: `${lightContent}\n${darkContent}\n${metaInfo}`,
});
}
// 删除原始的样式文件, 自动颜色主题因为删除, 永远不会生成两次
delete bundle[key];
}
}
},
writeBundle() {
// 上传到服务器
const server = process.env.SSH_SERVER;
const user = process.env.SSH_USER || "root";
const path = process.env.GITEA_THEME_PATH;
if (server && path) {
const cmd = `scp dist/${prefix}*.css ${user}@${server}:${path}`;
const theme_path = process.env.GITEA_THEME_PATH;
if (server && theme_path) {
const cmd = `scp dist/${prefix}*.css ${user}@${server}:${theme_path}`;
console.log("[themePlugin] exec:", cmd);
try {
execSync(cmd, { stdio: "inherit" });
@@ -105,6 +133,7 @@ export function themePlugin(): Plugin {
} else {
console.log("[themePlugin] no SSH_SERVER or GITEA_THEME_PATH, skip upload");
}
console.log("[themePlugin] exec end.");
},
};
}

View File

@@ -1,6 +1,12 @@
import type { CSSVarFunction } from "src/core/types";
type CSSFallbackVar = `var(--${string}, ${string})`;
/**
* 设置 CSS 变量的回退值
* @param cssvar `var(--${string})`
* @param fallback
* @returns `var(--${string}, fallback)`
*/
export function fallbackVar(cssvar: CSSVarFunction, fallback: string): CSSFallbackVar {
const var_name = cssvar.replace("var(--", "").replace(")", "");
return `var(--${var_name}, ${fallback})`;

View File

@@ -1,3 +1,5 @@
export { defineTheme } from "./core/color";
export type { Console, Diff, Other } from "./types";
export { themeVars } from "./types/vars";
export { defaultDarkChroma, defaultLightChroma } from "./core/chroma";
export { defineTheme, type ThemeColor } from "./core/color";
export type { Theme } from "./core/theme";
export type { Ansi, Chroma, Console, Diff, Github, Message, Named, Other, Primary, Secondary } from "./types";
export { otherThemeVars, themeVars } from "./types/vars";

255
src/types/color/chroma.ts Normal file
View File

@@ -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实体名 &lt; &gt; &amp;
*/
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 <<EOF EOF>>
*/
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 <stdio.h>
*/
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,
},
};

View File

@@ -25,10 +25,10 @@ export const github = {
accent: {
/** 强调色
* @diff 折叠/展开按钮的悬停颜色
* @actions `actionViewLeft` 左侧子作业激活伪元素颜色
* @release `releaseTagMenu` 顶部栏左侧按钮激活背景色
* @navbar `navbarRight` 头像管理员标识背景颜色
* @dropdown `dropdown` emoji 的悬停背景色
* @menu `paginationMenu` 分页菜单的激活背景色
*/
emphasis: null,
/** 暗淡的背景颜色
@@ -36,6 +36,7 @@ export const github = {
* @repo `repoTopic` 仓库主题标签背景颜色
* @actions `actions` 分支标签按钮背景颜色
* @actions `actionViewHeader` 分支标签按钮背景颜色
* @notification `notification` 通知列表悬停时的背景颜色
*/
muted: null,
},
@@ -59,8 +60,10 @@ export const github = {
* @input `input` 输入框被选中时的边框颜色
* @clone `clone` 克隆地址框被选中时的边框颜色
* @issue `comment` 评论框被选中时的边框颜色
* @actions `actionViewLeft` 左侧子作业激活伪元素颜色
* @menu `verticalMenu` 垂直菜单项激活时左侧的伪元素颜色
* @dropdown `selectionDropdown` 选择输入框的内部边框颜色
* @notification `notification` 通知列表悬停时的左边框颜色
*/
emphasis: null,
},
@@ -157,6 +160,10 @@ export const github = {
hover: null,
},
},
star: {
/** 已标星的星星颜色 */
iconColor: null,
},
},
control: {
bgColor: {
@@ -175,6 +182,11 @@ export const github = {
* @menu `menu` 菜单项的悬停背景颜色
* @repo `repoHeader` 仓库标题的悬停背景颜色
* @commit `commit` 提交信息的 Action 按钮的悬停背景颜色
* @filelist `repoFiles` README 栏的按钮的悬停背景颜色
* @issue `issueSidebar` 操作按钮的悬停背景颜色
* @issue `issueList` 头部菜单左侧开启关闭菜单的悬停背景颜色
* @dashboard `dashboard` 仓库列表项目的悬停背景颜色
* @notification `notification` 通知列表的按钮悬停背景颜色
*/
hover: null,
},
@@ -185,6 +197,17 @@ export const github = {
/** 悬浮阴影
* @tippy `tippyBox` 悬浮框阴影
* @dropdown `dropdown` 下拉框阴影
* @dashboard `dashboard` 仓库/组织切换按钮和列表边框和阴影
* @heatmap `heatmap` 热力图阴影
* @heatmap `activity` 动态活动阴影
*/
small: null,
},
resting: {
/** 静止阴影
* @button `primaryStyle` 主色调按钮阴影
* @button `redButton` 红色按钮悬浮阴影
* @setting `button` 红色按钮阴影
*/
small: null,
},
@@ -194,6 +217,7 @@ export const github = {
/** 下划线导航栏的边框颜色
* @clone `clone` 按钮组的按钮下划线颜色
* @menu `secondaryMenu` 二级菜单按钮的下划线颜色
* @filelist `repoFiles` README 栏的左边按钮下划线颜色
*/
active: null,
},
@@ -201,17 +225,17 @@ export const github = {
/** 热力图 */
contribution: {
default: {
/** 热力图方块的颜色 */
bgColor: {
num0: null,
num1: null,
num2: null,
num3: null,
num4: null,
/** github 无此颜色需自行计算
* @example 可参考这个颜色 `--color-prettylights-syntax-string-regexp`
*/
/** github 无此颜色需自行计算 */
num5: null,
},
/** 热力图方块的内边框颜色 */
borderColor: {
num0: null,
num1: null,

View File

@@ -1,3 +1,4 @@
export { chroma } from "./chroma";
export { ansi, console } from "./console";
export { diff } from "./diff";
export { github } from "./github";

View File

@@ -1,12 +1,4 @@
const num = {
num1: null,
num2: null,
num3: null,
num4: null,
num5: null,
num6: null,
num7: null,
};
const num = { num1: null, num2: null, num3: null, num4: null, num5: null, num6: null, num7: null };
const alpha = {
num10: null,
@@ -20,33 +12,12 @@ const alpha = {
num90: null,
};
export const primary = {
self: null,
contrast: null,
dark: num,
light: num,
alpha: alpha,
hover: null,
active: null,
};
export const primary = { self: null, contrast: null, dark: num, light: num, alpha: alpha, hover: null, active: null };
export const secondary = {
self: null,
dark: {
num8: null,
num9: null,
num10: null,
num11: null,
num12: null,
num13: null,
...num,
},
light: {
num1: null,
num2: null,
num3: null,
num4: null,
},
dark: { num8: null, num9: null, num10: null, num11: null, num12: null, num13: null, ...num },
light: { num1: null, num2: null, num3: null, num4: null },
alpha: alpha,
button: null,
hover: null,

View File

@@ -1,32 +1,8 @@
const msg = {
bg: null,
border: null,
text: null,
};
const msg = { bg: null, border: null, text: null };
const error = {
...msg,
bg: {
self: null,
active: null,
hover: null,
},
};
const error = { ...msg, bg: { self: null, active: null, hover: null } };
const success = { ...msg };
const warning = { ...msg };
const info = { ...msg };
const success = {
...msg,
};
const warning = {
...msg,
};
const info = {
...msg,
};
export const message = {
error,
success,
warning,
info,
};
export const message = { error, success, warning, info };

View File

@@ -1,11 +1,4 @@
const baseColor = {
self: null,
light: null,
dark: {
num1: null,
num2: null,
},
};
const baseColor = { self: null, light: null, dark: { num1: null, num2: null } };
const commitColor = {
/** 提交哈希值颜色 */
@@ -23,26 +16,14 @@ const commitColor = {
export const named = {
/** 红色/提交警告签名颜色 */
red: {
...commitColor,
...baseColor,
},
red: { ...commitColor, ...baseColor },
/** 橙色/提交未匹配签名颜色 */
orange: {
...commitColor,
...baseColor,
},
orange: { ...commitColor, ...baseColor },
/** 黄色/提交未信任签名颜色 */
yellow: {
...commitColor,
...baseColor,
},
yellow: { ...commitColor, ...baseColor },
olive: baseColor,
/** 绿色/提交信任签名颜色 */
green: {
...commitColor,
...baseColor,
},
green: { ...commitColor, ...baseColor },
teal: baseColor,
blue: baseColor,
violet: baseColor,
@@ -50,10 +31,7 @@ export const named = {
pink: baseColor,
brown: baseColor,
black: baseColor,
grey: {
self: null,
light: null,
},
grey: { self: null, light: null },
gold: null,
white: null,
};

View File

@@ -114,7 +114,7 @@ export const other = {
/** 点击后颜色 */
activeBg: "color-reaction-active-bg",
},
/** 不知道是干啥的 */
/** 鼠标悬浮时的提示文本, 比如提交的具体时间, 任务状态等 */
tooltip: {
text: null,
bg: null,

View File

@@ -1,6 +1,8 @@
import type { MapLeafNodes } from "src/core/types";
import * as color from "./color";
/** 代码高亮色 */
export type Chroma = MapLeafNodes<typeof color.chroma, string>;
/** 主色调(强调色) */
export type Primary = MapLeafNodes<typeof color.primary, string>;
/** 副色调(边框色) */

View File

@@ -1,17 +1,21 @@
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,
@@ -26,32 +30,24 @@ const vars = {
github: color.github,
};
const otherVars = {
border: {
radius: null,
},
color: {
...color.otherAuto,
},
};
const otherVars = { border: { radius: null }, color: { ...color.otherAuto } };
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",
},
},
branchMenuWidth: "branch-menu-width",
cloneMenuWidth: "clone-menu-width",
userMenuWidth: "user-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);
const themeInfo = {
version: null,
};
export const themeVars = createGlobalThemeContract(vars, varMapper());
export const otherThemeVars = createGlobalThemeContract(otherVars, varMapper());
export const customThemeVars = createGlobalThemeContract(customVars, varMapper("custom"));
export const themeInfoVars = createGlobalThemeContract(themeInfo, varMapper("theme"));
export { css } from "@linaria/core";

View File

@@ -180,7 +180,7 @@ export const actionViewLeft = css`
&:after {
overflow: visible;
background: ${themeVars.github.bgColor.accent.emphasis};
background: ${themeVars.github.borderColor.accent.emphasis};
border-radius: ${otherThemeVars.border.radius};
content: "";
height: 24px;
@@ -203,7 +203,7 @@ export const actionViewRight = css`
.job-info-header {
padding: 16px 12px 16px 24px;
height: auto;
height: 80px;
.job-info-header-title {
color: ${themeVars.github.fgColor.accent};
@@ -220,6 +220,11 @@ export const actionViewRight = css`
color: ${themeVars.color.console.fg.subtle};
padding: 8px 10px;
&.selected {
// 滚动时固定在顶部的高度与 job-info-header 高度相同
top: 80px;
}
&.step-expandable:hover {
color: ${themeVars.color.console.fg.subtle};
}

286
styles/components/chroma.ts Normal file
View File

@@ -0,0 +1,286 @@
import { css, themeVars } from "src/types/vars";
// https://github.com/go-gitea/gitea/blob/main/web_src/css/chroma/base.css
export const chromaBase = css`
.chroma {
// LineTableTD
.lntd {
vertical-align: top;
padding: 0;
margin: 0;
border: 0;
}
// LineTable
.lntable {
border-spacing: 0;
padding: 0;
margin: 0;
border: 0;
width: auto;
overflow: auto;
display: block;
}
// LineHighlight
.hl {
display: block;
width: 100%;
}
// LineNumbersTable
.lnt,
// LineNumbers
.ln {
margin-right: 0.4em;
padding: 0 0.4em;
}
// GenericStrong
.gs {
font-weight: var(--font-weight-semibold);
}
// GenericUnderline
.gl {
text-decoration: underline;
}
}
`;
// https://github.com/alecthomas/chroma/blob/6428fb4e65f3c1493491571c8a6a8f1add1da822/types.go#L208
export const chromaCode = css`
.chroma {
// TextWhiteSpace
.w {
color: ${themeVars.chroma.textWhiteSpace};
}
// Error
.err {
color: ${themeVars.chroma.err};
}
// Keyword
.k {
color: ${themeVars.chroma.keyword.self};
}
.kc {
color: ${themeVars.chroma.keyword.constant};
}
.kd {
color: ${themeVars.chroma.keyword.declaration};
}
.kn {
color: ${themeVars.chroma.keyword.namespace};
}
.kp {
color: ${themeVars.chroma.keyword.pseudo};
}
.kr {
color: ${themeVars.chroma.keyword.reserved};
}
.kt {
color: ${themeVars.chroma.keyword.type};
}
// Name
.n {
color: ${themeVars.chroma.name.self};
}
.na {
color: ${themeVars.chroma.name.attribute};
}
.nb {
color: ${themeVars.chroma.name.builtin};
}
.bp {
color: ${themeVars.chroma.name.builtinPseudo};
}
.nc {
color: ${themeVars.chroma.name.class};
}
.no {
color: ${themeVars.chroma.name.constant};
}
.nd {
color: ${themeVars.chroma.name.decorator};
}
.ni {
color: ${themeVars.chroma.name.entity};
}
.ne {
color: ${themeVars.chroma.name.exception};
}
.nf {
color: ${themeVars.chroma.name.function};
}
.fm {
color: ${themeVars.chroma.name.functionMagic};
}
.py {
color: ${themeVars.chroma.name.property};
}
.nl {
color: ${themeVars.chroma.name.label};
}
.nn {
color: ${themeVars.chroma.name.namespace};
}
.nx {
color: ${themeVars.chroma.name.other};
}
.nt {
color: ${themeVars.chroma.name.tag};
}
.nv {
color: ${themeVars.chroma.name.variable};
}
.vc {
color: ${themeVars.chroma.name.variableClass};
}
.vg {
color: ${themeVars.chroma.name.variableGlobal};
}
.vi {
color: ${themeVars.chroma.name.variableInstance};
}
.vm {
color: ${themeVars.chroma.name.variableMagic};
}
// Literal
.l {
color: ${themeVars.chroma.literal.self};
}
.ld {
color: ${themeVars.chroma.literal.date};
}
// String
.s {
color: ${themeVars.chroma.string.self};
}
.sa {
color: ${themeVars.chroma.string.affix};
}
.sb {
color: ${themeVars.chroma.string.backtick};
}
.sc {
color: ${themeVars.chroma.string.char};
}
.dl {
color: ${themeVars.chroma.string.delimiter};
}
.sd {
color: ${themeVars.chroma.string.doc};
}
.s2 {
color: ${themeVars.chroma.string.double};
}
.se {
color: ${themeVars.chroma.string.escape};
}
.sh {
color: ${themeVars.chroma.string.heredoc};
}
.si {
color: ${themeVars.chroma.string.interpol};
}
.sx {
color: ${themeVars.chroma.string.other};
}
.sr {
color: ${themeVars.chroma.string.regex};
}
.s1 {
color: ${themeVars.chroma.string.single};
}
.ss {
color: ${themeVars.chroma.string.symbol};
}
// Number
.m {
color: ${themeVars.chroma.number.self};
}
.mb {
color: ${themeVars.chroma.number.bin};
}
.mf {
color: ${themeVars.chroma.number.float};
}
.mh {
color: ${themeVars.chroma.number.hex};
}
.mi {
color: ${themeVars.chroma.number.integer};
}
.il {
color: ${themeVars.chroma.number.integerLong};
}
.mo {
color: ${themeVars.chroma.number.oct};
}
// Operator
.o {
color: ${themeVars.chroma.operator.self};
}
.ow {
color: ${themeVars.chroma.operator.word};
}
// Punctuation
.p {
color: ${themeVars.chroma.punctuation};
}
// Comment
.c {
color: ${themeVars.chroma.comment.self};
}
.ch {
color: ${themeVars.chroma.comment.hashbang};
}
.cm {
color: ${themeVars.chroma.comment.multiline};
}
.cp {
color: ${themeVars.chroma.comment.preproc};
}
.cpf {
color: ${themeVars.chroma.comment.preprocFile};
}
.c1 {
color: ${themeVars.chroma.comment.single};
}
.cs {
color: ${themeVars.chroma.comment.special};
}
// Generic
.g {
color: ${themeVars.chroma.generic.self};
}
.gd {
color: ${themeVars.chroma.generic.deleted};
}
.ge {
color: ${themeVars.chroma.generic.emph};
}
.gr {
color: ${themeVars.chroma.generic.error};
}
.gh {
color: ${themeVars.chroma.generic.heading};
}
.gi {
color: ${themeVars.chroma.generic.inserted};
}
.go {
color: ${themeVars.chroma.generic.output};
}
.gp {
color: ${themeVars.chroma.generic.prompt};
}
.gs {
color: ${themeVars.chroma.generic.strong};
}
.gu {
color: ${themeVars.chroma.generic.subheading};
}
.gt {
color: ${themeVars.chroma.generic.traceback};
}
.gu {
color: ${themeVars.chroma.generic.underline};
}
}
`;

View File

@@ -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};

View File

@@ -8,7 +8,7 @@ export const commit = css`
// 作者
.author {
// 作者名称
a.author-wrapper {
.author-wrapper {
color: ${themeVars.color.text.light.num1};
}
}
@@ -42,13 +42,24 @@ export const commit = css`
color: ${themeVars.color.text.light.num1};
}
}
// 整行悬停色
tr:hover {
background-color: ${themeVars.color.hover.opaque};
}
// 偶数行悬停色
tr:nth-child(2n):hover {
background-color: ${themeVars.color.hover.opaque} !important;
tr {
// 整行悬停色
&:hover {
background-color: ${themeVars.color.hover.opaque};
}
// 偶数行悬停色
&:nth-child(2n):hover {
background-color: ${themeVars.color.hover.opaque} !important;
}
// 尾行圆角
&:last-child {
td:first-child {
border-bottom-left-radius: ${otherThemeVars.border.radius};
}
td:last-child {
border-bottom-right-radius: ${otherThemeVars.border.radius};
}
}
}
}
}

View File

@@ -1,15 +1,137 @@
import { css } from "src/types/vars";
import { css, otherThemeVars, themeVars } from "src/types/vars";
export const dashboard = css`
.page-content.dashboard {
// 动态的右侧 svg 图标
.flex-item .flex-item-trailing svg {
height: 20px;
width: 20px;
}
// 首页仪表板, 避免选中管理员后台的维护管理面板
.page-content.dashboard.feeds {
// 仓库列表的仓库/组织切换按钮
.ui.two.item.menu {
background-color: unset;
background: ${themeVars.color.hover.self};
border: 0;
border-radius: 12px;
margin-bottom: 8px;
> .item {
background: unset;
border-radius: 12px;
padding: 6px 12px !important;
&.active {
background: ${themeVars.color.menu};
box-shadow: ${themeVars.github.shadow.floating.small};
font-weight: 600;
}
&::before {
display: none;
}
&:not(.active) {
border-radius: ${otherThemeVars.border.radius};
margin: 6px !important;
width: calc(50% - 12px);
&:hover {
background: ${themeVars.github.control.transparent.bgColor.hover};
}
}
}
}
// 仓库/组织列表标题
.ui.top.attached.header {
border: 0;
font-size: 20px;
font-weight: 400;
background-color: unset !important;
margin-bottom: 0.25rem;
}
// 仓库/组织列表
.ui.attached.segment {
background-color: ${themeVars.color.menu};
border: unset !important;
box-shadow: ${themeVars.github.shadow.floating.small};
&.repos-search {
border-top-left-radius: 12px;
border-top-right-radius: 12px;
}
&.table {
&:last-child {
border-bottom-left-radius: 12px !important;
border-bottom-right-radius: 12px !important;
}
ul {
padding: 8px;
li {
border-radius: ${otherThemeVars.border.radius};
padding: 6px 8px !important;
&:not(:last-child) {
border-bottom: 0;
}
&:hover {
background: ${themeVars.github.control.transparent.bgColor.hover};
}
a.muted:hover {
color: inherit;
text-decoration-line: none;
}
}
}
}
}
// 组织列表
.ui.tab.dashboard-orgs .ui.attached.segment.table {
border-top-left-radius: 12px;
border-top-right-radius: 12px;
}
}
`;
// 导航栏的工单/PR/里程碑仪表板
export const dashboardIssues = css`
.page-content.dashboard.issues {
.list-header {
background-color: ${themeVars.color.box.header};
border: 1px solid ${themeVars.color.light.border};
border-bottom: 0;
border-top-left-radius: ${otherThemeVars.border.radius};
border-top-right-radius: ${otherThemeVars.border.radius};
height: 54px;
padding: 16px 8px;
.list-header-toggle {
align-items: center;
border: 0;
> .item {
background: unset !important;
border-radius: ${otherThemeVars.border.radius};
color: ${themeVars.color.text.light.num1};
padding: 0px 8px;
height: 30px;
&:before {
display: none;
}
&:hover {
background: ${themeVars.github.control.transparent.bgColor.hover} !important;
}
&.active {
color: ${themeVars.color.text.self};
font-weight: 700;
}
}
}
.list-header-filters {
> .item {
border-radius: ${otherThemeVars.border.radius};
color: ${themeVars.color.text.light.num1};
padding: 0px 12px;
height: 32px;
&:hover {
background: ${themeVars.github.control.transparent.bgColor.hover};
}
}
}
}
}
`;
// 避免手机/平板下菜单错位
export const issueListMobile = css`
@media (max-width: 767.98px) {
.page-content.dashboard.issues .list-header {
height: auto;
}
}
`;

View File

@@ -29,15 +29,44 @@ export const diff = css`
}
/* 展开/收缩按钮 */
.code-expander-button {
height: 24px !important;
line-height: 24px;
color: ${themeVars.color.text.light.num1};
height: 28px !important;
&:hover {
background: ${themeVars.github.bgColor.accent.emphasis};
color: ${themeVars.color.white};
}
}
/* 行号居中 */
.lines-num {
text-align: center !important;
}
// 差异对比文件盒子
.diff-file-box {
// 差异对比文件头
.diff-file-header {
// 文件名
.diff-file-name {
font-weight: 400;
.fold-file.btn svg {
min-width: 16px;
min-height: 16px;
height: 16px;
width: 16px;
}
.diff-stats-bar {
height: 8px;
}
> div,
.file-link {
font-size: 12px;
}
}
// 操作按钮
.diff-file-header-actions {
color: ${themeVars.color.text.light.num1};
font-size: 12px;
font-weight: 400;
}
}
}
`;

View File

@@ -0,0 +1,14 @@
import { css, themeVars } from "src/types/vars";
export const monaco = css`
.monaco-editor {
--vscode-editor-background: ${themeVars.color.body} !important;
--vscode-editorGutter-background: ${themeVars.color.body} !important;
// 滚动时固定在顶部的行
.sticky-widget {
background: ${themeVars.color.body} !important;
box-shadow: 0 1px 0 ${themeVars.color.secondary.self} !important;
width: 100% !important;
}
}
`;

View File

@@ -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`
@@ -13,7 +13,8 @@ export const repoList = css`
.page-content.user.profile > .ui.container > .ui.stackable > .ui.twelve,
// 探索
.page-content.explore.repositories > .ui.container {
> .flex-list {
// 排除用户的公开活动页
> .flex-list:not(#activity-feed) {
display: grid;
> .flex-item {
border: 1px solid ${themeVars.color.light.border};
@@ -37,10 +38,6 @@ export const repoList = css`
&:not(a) {
color: ${themeVars.color.text.light.num1};
}
// 仓库类型和状态标签
> .label-list .label {
padding: 3px 6px;
}
}
// 仓库语言, 星标
> .flex-item-trailing {
@@ -77,7 +74,8 @@ export const repoList = css`
gap: min(${orgRepoVar} * 8px, 16px);
}
// 用户
.page-content.user.profile > .ui.container > .ui.stackable > .ui.twelve > .flex-list {
// 排除用户的公开活动页
.page-content.user.profile > .ui.container > .ui.stackable > .ui.twelve > .flex-list:not(#activity-feed) {
grid-template-columns: repeat(${userRepoVar}, 1fr);
gap: min(${userRepoVar} * 8px, 16px);
}
@@ -88,8 +86,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`
@@ -111,7 +109,6 @@ export const userList = css`
// 用户标签
> .label {
font-size: 12px;
padding: 3px 6px;
}
}
// 用户描述
@@ -152,7 +149,8 @@ export const mobileList = css`
.page-content.organization.members >.ui.container,
// 探索的用户和组织列表
.page-content.explore.users >.ui.container {
> .flex-list {
// 排除用户的公开活动页
> .flex-list:not(#activity-feed) {
grid-template-columns: 1fr;
gap: 8px;
}

View File

@@ -1,4 +1,4 @@
import { css, themeVars } from "src/types/vars";
import { css, otherThemeVars, themeVars } from "src/types/vars";
// 文件列表页面下的分支按钮
export const branchButton = css`
@@ -10,7 +10,7 @@ export const branchButton = css`
border: 1px solid ${themeVars.color.light.border};
margin-top: 1px;
margin-left: auto;
margin-right: 16px; // gitea 有 RSS 留出足够的空间
margin-right: 20px; // gitea 有 RSS 留出足够的空间
}
}
}
@@ -22,6 +22,7 @@ export const syncFork = css`
.repo-home-filelist > .ui.message {
background: ${themeVars.color.box.header};
padding: 8px 8px 8px 16px;
margin: 16px 0px;
.ui.button {
min-width: 96px;
}
@@ -31,8 +32,13 @@ export const syncFork = css`
// 仓库文件列表
export const repoFiles = css`
// 文件列表和提交列表的按钮组
.repo-button-row {
margin: 16px 0;
}
.repository.file.list {
#repo-files-table {
margin: 16px 0;
// 头部最后一次提交
.repo-file-line {
padding-right: 16px;
@@ -75,6 +81,7 @@ export const repoFiles = css`
// 文件列表
.repo-file-item {
.repo-file-cell {
height: 40px;
&.name {
display: flex;
align-items: center;
@@ -87,6 +94,43 @@ export const repoFiles = css`
}
}
}
#readme {
.file-header {
background: ${themeVars.color.body};
min-height: 48px;
padding: 0px 8px !important;
svg {
color: ${themeVars.color.text.light.num1};
}
.file-header-left {
padding: 8px !important;
// 伪元素宽度等于按钮宽度而不是父元素宽度
position: relative;
&:hover {
background: ${themeVars.github.control.transparent.bgColor.hover};
border-radius: ${otherThemeVars.border.radius};
}
&:after {
content: "";
background: ${themeVars.github.underlineNav.borderColor.active};
border-radius: ${otherThemeVars.border.radius};
bottom: -7px;
left: 0;
height: 2px;
position: absolute;
width: 100%;
}
a.muted:hover {
color: inherit;
text-decoration-line: none;
}
}
.file-header-right:hover {
background: ${themeVars.github.control.transparent.bgColor.hover};
border-radius: ${otherThemeVars.border.radius};
}
}
}
}
`;
@@ -112,15 +156,179 @@ export const repoFilesMobile = css`
// 仓库打开文件时的视图
export const repoFileView = css`
// 隐藏主内容的下内容和页脚, 避免滚动文件树时滚动条遮挡
body > .full.height:has(.repo-view-file-tree-container) {
padding-bottom: 0;
+ .page-footer {
display: none;
}
}
.page-content.repository.file.list {
&:has(.repo-view-file-tree-container) {
// 取消下间隔优化观看体验
.secondary-nav {
margin-bottom: 0 !important;
.ui.tabs.divider {
margin-bottom: 0;
}
}
}
> .ui.container.fluid {
max-width: calc(100% - calc(2 * 16px));
}
.repo-view-container {
position: sticky;
top: 0;
// 左侧文件树
.repo-view-file-tree-container {
height: calc(100vh - 64px); // 减去头部高度
// 固定头部
position: sticky;
top: 0;
&:after {
content: "";
position: absolute;
top: 0;
right: 0;
width: 1px;
height: calc(100% + 64px); // 头部高度
background: ${themeVars.color.secondary.self};
}
> .repo-button-row {
align-content: center;
background: ${themeVars.color.body};
font-size: 16px;
height: 64px;
margin: 0;
// 固定头部, 早期父元素有多余的页脚和内容高度导致滚动时无法固定, 修复后也可保留此属性无需删除
position: sticky;
top: 0;
&:after {
content: "";
position: absolute;
top: 64px;
left: -16px;
width: calc(100% + 16px);
height: 1px;
background: ${themeVars.color.secondary.self};
}
.ui.compact.icon.button {
border: 0;
}
}
.view-file-tree-items {
margin-right: 0;
padding: 12px 16px 8px 0;
}
}
// 右侧文件视图内容
.repo-view-content {
padding-bottom: 40px;
.repo-button-row {
align-content: center;
background: ${themeVars.color.box.header};
border: 1px solid ${themeVars.color.secondary.self};
border-radius: ${otherThemeVars.border.radius};
margin: 16px 0;
height: 46px;
min-height: 46px;
padding: 8px;
position: sticky;
top: 0;
z-index: 1;
.ui.button {
min-height: 32px;
}
// 打开文件树按钮
.repo-view-file-tree-toggle-show {
background: initial;
border-color: #0000;
padding: 0;
min-width: 32px;
}
// 分支选择按钮
.branch-dropdown-button {
padding: 0 12px;
}
// 路径
.repo-path {
gap: 4px;
.section {
&:first-child,
&.active {
font-weight: 600;
}
}
.btn {
svg {
margin-left: 4px;
color: ${themeVars.color.text.light.num1};
}
}
}
}
.non-diff-file-content {
// 避免分支菜单遮挡
position: relative;
z-index: 0;
h4.file-header {
padding: 8px 12px !important;
position: sticky;
// 重叠边框线, 避免过粗
top: 45px;
z-index: 1;
.file-header-left {
color: ${themeVars.color.text.light.num1};
font-size: 12px;
}
.file-header-right {
// 按钮组
> .ui.buttons {
margin: 0 8px 0 0 !important; // 完全不知道为什么浏览器最终效果没生效, 只能 !important 了
.ui.mini.button {
min-height: 28px;
height: 28px;
font-size: 12px;
padding: 0 8px;
}
}
// 右侧操作按钮
> .btn-octicon {
display: flex;
align-items: center;
background: ${themeVars.color.button};
border: 1px solid ${themeVars.color.light.border};
height: 28px;
padding: 0 8px;
svg {
color: ${themeVars.color.text.light.num1};
}
&:first-of-type {
border-top-left-radius: ${otherThemeVars.border.radius};
border-bottom-left-radius: ${otherThemeVars.border.radius};
}
&:last-of-type {
border-top-right-radius: ${otherThemeVars.border.radius};
border-bottom-right-radius: ${otherThemeVars.border.radius};
}
&:hover {
background: ${themeVars.color.hover.self};
color: ${themeVars.color.text.light.num1};
}
}
}
}
}
// 头部提交信息
#repo-file-commit-box {
.ui.segment#repo-file-commit-box {
padding: 8px 12px;
margin-bottom: 16px !important;
min-height: 46px;
> .latest-commit {
gap: 8px;
.commit-summary {
color: ${themeVars.color.text.light.num1};
}
}
// 右侧提交时间
> .age {
@@ -133,10 +341,29 @@ export const repoFileView = css`
}
`;
// 避免手机/平板下路径容器过长导致换行, 取消固定
export const repoFileViewMobile = css`
@media (max-width: 1023.98px) {
.page-content.repository.file.list .repo-view-container .repo-view-content {
.repo-button-row {
height: auto;
position: static;
z-index: 0;
}
.non-diff-file-content {
h4.file-header {
top: 0;
}
}
}
}
`;
// 仓库代码布局调整, 侧边栏宽度调整
export const repoGrid = css`
.repo-grid-filelist-sidebar {
grid-template-columns: auto 296px;
grid-template-columns: auto 312px;
gap: 24px;
}
@media (max-width: 767.98px) {
@@ -155,11 +382,15 @@ export const repoSidebarTop = css`
}
.flex-item {
padding: 10px 0 0 0;
// 仓库描述本身
.flex-item-title {
margin-top: 2px;
margin-top: 12px;
}
// 仓库描述内容
.flex-item-body {
padding: 8px 0 0 0;
> .tw-flex:first-child {
margin-top: 21px !important;
}
.repo-description {
color: ${themeVars.color.text.self};
}

View File

@@ -1,51 +1,100 @@
import { css, themeVars } from "src/types/vars";
export const heatmap = css`
.vch__container {
// 覆盖热力图和图例的背景色
.vch__day__square,
.vch__legend__wrapper rect {
// 圆角
rx: 2.5px;
ry: 2.5px;
// hover 时的圆角
border-radius: 0.75px;
// 宽度和高度可以用来控制间隔
width: 9px;
height: 9px;
// 边框
outline: 0.5px solid ${themeVars.github.contribution.default.borderColor.num0};
// 边框向内偏移
outline-offset: -0.5px;
#user-heatmap {
+ .divider:not(.divider-text) {
border-color: #0000;
margin: 8px 0px;
}
.total-contributions {
left: 25px + 20px;
bottom: 0 + 12px;
}
.total-contributions,
.vch__legend-right {
color: ${themeVars.color.text.light.num1};
}
.vch__container {
padding: 12px 20px;
box-shadow: ${themeVars.github.shadow.floating.small};
border-radius: 12px;
// 覆盖热力图和图例的背景色
.vch__day__square,
.vch__legend__wrapper rect {
// 圆角
rx: 2.5px;
ry: 2.5px;
// hover 时的圆角
border-radius: 0.75px;
// 宽度和高度可以用来控制间隔
width: 9px;
height: 9px;
// 边框
outline: 0.5px solid ${themeVars.github.contribution.default.borderColor.num0};
// 边框向内偏移
outline-offset: -0.5px;
&[style="fill: var(--color-secondary-alpha-60);"] {
fill: ${themeVars.github.contribution.default.bgColor.num0} !important;
}
&[style="fill: var(--color-secondary-alpha-60);"] {
fill: ${themeVars.github.contribution.default.bgColor.num0} !important;
}
&[style="fill: var(--color-primary-light-4);"] {
fill: ${themeVars.github.contribution.default.bgColor.num1} !important;
outline-color: ${themeVars.github.contribution.default.borderColor.num1};
}
&[style="fill: var(--color-primary-light-4);"] {
fill: ${themeVars.github.contribution.default.bgColor.num1} !important;
outline-color: ${themeVars.github.contribution.default.borderColor.num1};
}
&[style="fill: var(--color-primary-light-2);"] {
fill: ${themeVars.github.contribution.default.bgColor.num2} !important;
outline-color: ${themeVars.github.contribution.default.borderColor.num2};
}
&[style="fill: var(--color-primary-light-2);"] {
fill: ${themeVars.github.contribution.default.bgColor.num2} !important;
outline-color: ${themeVars.github.contribution.default.borderColor.num2};
}
&[style="fill: var(--color-primary);"] {
fill: ${themeVars.github.contribution.default.bgColor.num3} !important;
outline-color: ${themeVars.github.contribution.default.borderColor.num3};
}
&[style="fill: var(--color-primary);"] {
fill: ${themeVars.github.contribution.default.bgColor.num3} !important;
outline-color: ${themeVars.github.contribution.default.borderColor.num3};
}
&[style="fill: var(--color-primary-dark-2);"] {
fill: ${themeVars.github.contribution.default.bgColor.num4} !important;
outline-color: ${themeVars.github.contribution.default.borderColor.num4};
}
&[style="fill: var(--color-primary-dark-2);"] {
fill: ${themeVars.github.contribution.default.bgColor.num4} !important;
outline-color: ${themeVars.github.contribution.default.borderColor.num4};
}
&[style="fill: var(--color-primary-dark-4);"] {
fill: ${themeVars.github.contribution.default.bgColor.num5} !important;
outline-color: ${themeVars.github.contribution.default.borderColor.num5};
&[style="fill: var(--color-primary-dark-4);"] {
fill: ${themeVars.github.contribution.default.bgColor.num5} !important;
outline-color: ${themeVars.github.contribution.default.borderColor.num5};
}
}
}
}
`;
// 动态
export const activity = css`
.flex-list#activity-feed {
border-radius: 12px;
box-shadow: ${themeVars.github.shadow.floating.small};
> .flex-item {
gap: 12px;
padding: 12px 8px 16px 14px;
> .flex-item-main {
gap: 8px !important;
> div:not([class]) {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
relative-time {
color: ${themeVars.color.text.light.num1};
}
}
// 动态的右侧 svg 图标
.flex-item-trailing svg {
height: 20px;
width: 20px;
}
}
> .page.buttons {
border-top: 1px solid ${themeVars.color.secondary.self};
padding: 12px 0px;
}
}
`;

View File

@@ -1,13 +1,21 @@
import "./actions";
import "./chroma";
import "./clone";
import "./commit";
import "./dashboard";
import "./diff";
import "./editor";
import "./explore";
import "./filelist";
import "./heatmap";
import "./issue";
import "./milestones";
import "./newrepo";
import "./notification";
import "./org";
import "./packages";
import "./release";
import "./repo";
import "./setting";
import "./signin";
import "./user";

View File

@@ -1,6 +1,182 @@
import { css, otherThemeVars, themeVars } from "src/types/vars";
import { activeItemAfterStyle } from "styles/public/menu";
// 工单&PR 列表
export const issueList = css`
// 仓库页面的里程碑列表菜单栏
.page-content.repository.milestones,
.page-content.repository.milestone-issue-list,
.page-content.repository.issue-list {
// 头部筛选菜单栏
.issue-list-toolbar {
align-items: center;
align-content: center;
background-color: ${themeVars.color.box.header};
border: 1px solid ${themeVars.color.light.border};
border-bottom: 0;
border-top-left-radius: ${otherThemeVars.border.radius};
border-top-right-radius: ${otherThemeVars.border.radius};
height: 48px;
padding: 8px;
margin-top: 16px;
.issue-list-toolbar-left {
// 复选框
input {
margin: 0 8px !important;
}
> .ui.compact.menu {
align-items: center;
border: 0;
> .item {
background: unset !important;
border-radius: ${otherThemeVars.border.radius};
color: ${themeVars.color.text.light.num1};
padding: 0px 8px;
height: 30px;
&:before {
display: none;
}
&:hover {
background: ${themeVars.github.control.transparent.bgColor.hover} !important;
}
&.active {
color: ${themeVars.color.text.self};
font-weight: 700;
}
}
}
}
.issue-list-toolbar-right > .ui.menu {
align-items: center;
> .ui.button {
padding: 0 12px;
height: 32px;
}
}
}
}
// 里程碑详细页面的 Issue 列表
.page-content.repository.milestone-issue-list,
// 顶部仪表板的 Issue 列表
.page-content.dashboard.issues,
// 用户订阅的 Issue 列表
.page-content.user.notification,
// 仓库 Issue 列表
.page-content.repository.issue-list {
.flex-list#issue-list {
border: 1px solid ${themeVars.color.light.border};
border-bottom-left-radius: ${otherThemeVars.border.radius};
border-bottom-right-radius: ${otherThemeVars.border.radius};
> .flex-item {
align-items: center;
padding: 0;
&:last-child {
border-bottom-left-radius: ${otherThemeVars.border.radius};
border-bottom-right-radius: ${otherThemeVars.border.radius};
}
&:hover {
background-color: ${themeVars.color.hover.opaque};
}
> .flex-item-icon {
display: flex;
gap: 4px;
margin-left: 16px;
// 复选框
input {
background: unset;
margin-top: 14px;
margin-right: 8px !important;
}
svg {
margin-top: 14px;
}
}
> .flex-item-main {
gap: 4px;
.flex-item-header {
padding-top: 8px;
}
.flex-item-body {
font-size: 12px;
padding-bottom: 8px;
}
}
> .flex-item-trailing {
margin-right: 32px;
}
}
}
}
// 里程碑列表
// [TODO] 暂时排除项目的列表
.page-content.repository.milestones:not(.projects) .milestone-list {
border: 1px solid ${themeVars.color.light.border};
border-bottom-left-radius: ${otherThemeVars.border.radius};
border-bottom-right-radius: ${otherThemeVars.border.radius};
.milestone-card {
padding: 8px 16px 10px 16px;
.milestone-header {
h3 {
font-size: 16px;
font-weight: 500;
}
div span {
font-size: 14px;
font-weight: 600;
}
}
}
.milestone-toolbar {
font-size: 12px;
.group > a {
font-size: 13px;
}
}
}
`;
// 避免手机/平板下菜单错位
export const issueListMobile = css`
@media (max-width: 1023.98px) {
.page-content.repository.milestones,
.page-content.repository.milestone-issue-list,
.page-content.repository.issue-list {
.issue-list-toolbar {
height: auto;
}
}
}
`;
// 置顶 Issue
export const issuePins = css`
#issue-pins {
gap: 12px;
margin-bottom: 16px;
.issue-card {
padding: 16px 12px;
.content {
.issue-card-title {
font-size: 16px;
font-weight: 600;
}
svg {
color: ${themeVars.color.text.light.num1};
height: 100%;
margin-right: 3px;
}
.meta {
font-size: 12px;
padding-top: 4px;
}
}
.issue-card-bottom {
display: none;
}
}
}
`;
export const button = css`
.issue-content-left .field.footer {
// 关闭工单按钮
@@ -18,6 +194,11 @@ export const button = css`
color: ${themeVars.github.fgColor.success};
}
}
// 工单&PR标题右侧按钮
.repository.view.issue .issue-title-buttons > .ui.button {
padding: 0 12px;
height: 32px;
}
`;
export const babel = css`
@@ -42,19 +223,19 @@ export const babel = css`
border-radius: 25px !important;
&.green {
color: ${themeVars.color.text.self} !important;
color: ${themeVars.color.white} !important;
background-color: ${themeVars.github.bgColor.success.emphasis} !important;
border-color: ${themeVars.github.bgColor.success.emphasis} !important;
}
&.red {
color: ${themeVars.color.text.self} !important;
color: ${themeVars.color.white} !important;
background-color: ${themeVars.github.bgColor.done.emphasis} !important;
border-color: ${themeVars.github.bgColor.done.emphasis} !important;
}
&.purple {
color: ${themeVars.color.text.self} !important;
color: ${themeVars.color.white} !important;
background-color: ${themeVars.github.bgColor.done.emphasis} !important;
border-color: ${themeVars.github.bgColor.done.emphasis} !important;
}
@@ -103,6 +284,7 @@ export const comment = css`
}
.comment-header {
padding: 4px 4px 4px 16px;
min-height: 38px;
}
.comment-header-right {
> .item,
@@ -178,6 +360,16 @@ export const comment = css`
}
`;
// 评论书写框
export const commentForm = css`
.repository .comment.form .content .segment {
&::before,
&::after {
display: none;
}
}
`;
export const dropdown = css`
.repository {
// Issue/PR 列表下的所有筛选菜单
@@ -197,7 +389,7 @@ export const prMerge = css`
.repository.view.issue .comment-list .timeline-item.pull-merge-box {
// 头像
.timeline-avatar {
color: ${themeVars.color.text.self} !important;
color: ${themeVars.color.white} !important;
border-radius: ${otherThemeVars.border.radius};
width: 40px;
height: 40px;
@@ -277,6 +469,12 @@ export const prMerge = css`
padding: 16px;
display: grid;
gap: 8px;
&.no-header {
&::before,
&::after {
display: none;
}
}
}
}
`;
@@ -285,6 +483,11 @@ export const prMerge = css`
export const timeline = css`
.repository.view.issue {
.comment-list {
// 时间线本线
.timeline::before {
// 不遮挡归档信息框, 归档信息框背景色有透明度时会漏出线
height: calc(100% - 62px);
}
.timeline-item,
.timeline-item-group {
padding: 16px 0;
@@ -330,3 +533,122 @@ export const timeline = css`
}
}
`;
const sidebarPadding = {
padding: "4px 8px",
};
// 侧边栏
export const issueSidebar = css`
// 工单&创建工单&PR页面侧边栏
.page-content.repository.issue {
.issue-content {
gap: 24px;
.issue-content-right {
border: 0;
font-size: 12px;
padding: 0;
.ui.button {
font-size: 12px;
}
.ui.form,
a.fixed-text.muted,
span.text,
// 列表项为空时的文字
span.item.empty-list,
p {
color: ${themeVars.color.text.light.num1};
font-size: 12px;
}
.ui.dropdown.select-branch,
.ui.form,
a.fixed-text.muted,
span.text,
.ui.watching > div,
.ui.depending > div,
.flex-text-block,
.ui.list,
.toggle-wip,
p {
${sidebarPadding};
}
// 允许维护者编辑
> .ui.checkbox {
margin: 4px 8px;
strong {
font-weight: 400;
}
}
.issue-sidebar-combo {
.ui.dropdown > a.fixed-text.muted {
align-items: center;
border-radius: ${otherThemeVars.border.radius};
text-decoration-line: none;
height: 28px;
&:hover {
background: ${themeVars.github.control.transparent.bgColor.hover};
}
}
.ui.list {
margin-top: 0 !important;
margin-bottom: 0 !important;
}
}
// 时间追踪
> div:not([class]):not([id]) > .ui.dropdown.jump > a.fixed-text.muted {
align-items: center;
border-radius: ${otherThemeVars.border.radius};
text-decoration-line: none;
height: 28px;
&:hover {
background: ${themeVars.github.control.transparent.bgColor.hover};
}
}
// 选中日期颜色
.ui.form .due-date {
color: ${themeVars.color.text.self};
}
.divider {
margin: 12px 0 12px 8px;
width: calc(100% - 16px);
}
// 订阅按钮
.ui.watching .ui.button {
padding: 0px 8px;
height: 28px;
svg {
margin: 0 !important;
}
}
// PIN 按钮
.form-fetch-action.single-button-form .ui.button,
// 底部操作按钮
.ui.show-modal.button {
border: 0;
background: unset;
font-weight: 400;
${sidebarPadding};
// 好像是浏览器 BUG, 最后不生效, 必须 !important
margin: 0 !important;
justify-content: left;
&:hover {
background: ${themeVars.github.control.transparent.bgColor.hover};
}
}
.ui.show-modal.button[data-modal="#sidebar-delete-issue"] {
color: ${themeVars.color.red.self};
svg {
color: ${themeVars.color.red.self};
}
&:hover {
background-color: ${themeVars.color.red.badge.bg};
color: ${themeVars.color.red.light};
svg {
color: ${themeVars.color.red.light};
}
}
}
}
}
}
`;

View File

@@ -0,0 +1,59 @@
import { css, themeVars } from "src/types/vars";
export const milestone = css`
// 里程碑头部
.milestone-header {
gap: 16px;
// 进度条
progress {
height: 5px;
width: 300px;
max-width: 80vw;
}
}
// 里程碑 Issue 列表的进度条
.milestone-progress-big {
height: 8px;
}
// 里程碑 Issue 列表
.page-content.repository.milestone-issue-list {
> .ui.container {
> .flex-text-block:first-child {
margin-bottom: 16px;
> h1 {
font-size: 32px;
font-weight: 600;
line-height: 48px;
word-break: keep-all;
}
+ .tw-flex {
flex-direction: row !important;
align-items: center;
gap: 8px !important;
padding-top: 8px;
padding-bottom: 10px;
font-size: 14px;
color: ${themeVars.color.text.light.num1};
strong {
color: ${themeVars.color.text.self};
}
> .flex-text-block {
gap: 8px !important;
}
}
}
> .divider {
border-top-color: #0000;
}
}
}
`;
// 避免手机/平板下菜单错位
export const milestoneMobile = css`
@media (max-width: 767.98px) {
.page-content.repository.milestone-issue-list > .ui.container > .flex-text-block:first-child + .tw-flex {
flex-direction: column !important;
}
}
`;

View File

@@ -0,0 +1,179 @@
import { css, otherThemeVars, themeVars } from "src/types/vars";
// 用户订阅/关注页面
export const notification = css`
.page-content.user.notification {
> .ui.container {
> .ui.attached.segment {
border: 0;
padding: 0;
> .divider {
display: none;
}
// 订阅列表
&:has(#issue-list) {
> .tw-flex {
align-items: center;
align-content: center;
background-color: ${themeVars.color.box.header};
border: 1px solid ${themeVars.color.light.border};
border-bottom: 0;
border-top-left-radius: ${otherThemeVars.border.radius};
border-top-right-radius: ${otherThemeVars.border.radius};
height: 52px;
padding: 8px;
// 左侧菜单
> .tw-flex:first-child > .ui.compact.menu {
align-items: center;
border: 0;
> .item {
background: unset !important;
border-radius: ${otherThemeVars.border.radius};
color: ${themeVars.color.text.light.num1};
padding: 0px 8px;
height: 30px;
&:before {
display: none;
}
&:hover {
background: ${themeVars.github.control.transparent.bgColor.hover} !important;
}
&.active {
color: ${themeVars.color.text.self};
font-weight: 700;
}
}
}
// 右侧菜单
> .tw-flex:last-child > .ui.menu {
align-items: center;
> .item {
color: ${themeVars.color.text.light.num1};
}
> .ui.button {
padding: 0 12px;
height: 32px;
}
}
}
}
// 关注列表
> .flex-list:not([id]) {
border: 1px solid ${themeVars.color.light.border};
border-radius: ${otherThemeVars.border.radius};
> .flex-item {
padding: 16px;
> .flex-item-main {
gap: 4px;
> .flex-item-header {
> .flex-item-title {
gap: 12px;
}
> .flex-item-trailing {
color: ${themeVars.color.text.light.num1};
font-size: 12px;
font-weight: 400;
gap: 16px;
.color-icon {
width: 12px;
height: 12px;
margin-right: 0 !important;
}
}
}
> .flex-item-body:last-child {
font-size: 12px;
}
}
}
}
}
// 通知列表
&:has(#notification_table) {
> .tw-flex:first-child {
background-color: ${themeVars.color.box.header};
border: 1px solid ${themeVars.color.light.border};
border-bottom: 0;
border-top-left-radius: ${otherThemeVars.border.radius};
border-top-right-radius: ${otherThemeVars.border.radius};
height: 52px;
padding: 8px;
margin-bottom: 0 !important;
// 左侧菜单
> .ui.compact.menu {
align-items: center;
border: 0;
> .item {
background: unset !important;
border-radius: ${otherThemeVars.border.radius};
color: ${themeVars.color.text.light.num1};
padding: 0px 8px;
height: 30px;
&:before {
display: none;
}
&:hover {
background: ${themeVars.github.control.transparent.bgColor.hover} !important;
}
&.active {
color: ${themeVars.color.text.self};
font-weight: 700;
}
.notifications-unread-count {
margin-left: 4px;
}
}
}
}
// 通知全部确认按钮
.ui.ui.ui.ui.mini.button {
height: 32px;
}
}
// 通知列表
#notification_table {
border-top-left-radius: 0;
border-top-right-radius: 0;
color: ${themeVars.color.text.light.num1};
> .notifications-item {
border-top: 1px solid ${themeVars.color.light.border};
padding: 8px !important;
&:first-child {
border-top: 0;
}
&:last-child {
border-bottom-left-radius: ${otherThemeVars.border.radius};
border-bottom-right-radius: ${otherThemeVars.border.radius};
}
&:hover {
background: ${themeVars.github.bgColor.accent.muted};
box-shadow: 2px 0 0 ${themeVars.github.borderColor.accent.emphasis} inset;
color: ${themeVars.color.text.self};
}
> .notifications-link {
> .notifications-top-row {
font-size: 12px !important;
}
> .notifications-bottom-row {
font-size: 14px !important;
}
}
> .notifications-updated {
font-size: 12px;
}
> .notifications-buttons {
.interact-bg {
background: ${themeVars.github.bgColor.accent.muted} !important;
color: ${themeVars.color.text.light.num1};
padding: 8px !important;
&:hover {
background: ${themeVars.github.control.transparent.bgColor.hover} !important;
color: ${themeVars.color.text.self};
}
}
}
}
}
}
}
`;

21
styles/components/org.ts Normal file
View File

@@ -0,0 +1,21 @@
import { css, themeVars } from "src/types/vars";
export const org = css`
.page-content.organization {
#org-info {
.ui.header {
// 组织页面的 RSS 订阅按钮
.ui.label.button {
padding: 4px 16px;
.svg {
width: 20px;
min-width: 20px;
}
&:hover {
border-color: ${themeVars.color.light.border};
}
}
}
}
}
`;

View File

@@ -0,0 +1,124 @@
import { css, otherThemeVars, themeVars } from "src/types/vars";
// 组织/仓库的软件包列表(包含用户但未测试)
export const packagesList = css`
.page-content.packages {
// 这里必须要用 >, 否则会影响到软件包详细信息页的样式
> .ui.container > div:not([class]) {
border: 1px solid ${themeVars.color.light.border};
border-radius: ${otherThemeVars.border.radius};
margin-top: 16px;
.flex-list {
border-top: 1px solid ${themeVars.color.light.border};
&:first-child {
border-top: 0;
}
.flex-item {
padding: 16px;
.flex-item-main {
.flex-item-title {
gap: 8px;
> a {
min-height: 25px;
}
// 软件包类型的标签
.ui.label {
gap: 4px;
padding: 3px 6px;
min-height: 24.5px;
background-color: unset;
border: 1px solid ${themeVars.color.light.border};
color: ${themeVars.color.primary.self};
}
}
.flex-item-body {
font-size: 12px;
a {
text-decoration: underline;
text-underline-offset: 3px;
}
}
}
}
}
}
}
`;
// 软件包详细信息页
export const packagesDetail = css`
.page-content.packages {
.issue-title-header > div {
color: ${themeVars.color.text.light.num1};
}
.issue-content {
.issue-content-left {
.ui.top.attached.header {
font-size: 14px;
padding: 16px;
}
.ui.attached.segment {
color: ${themeVars.color.text.light.num1};
padding: 16px;
.ui.table,
.ui.form .field > label {
color: ${themeVars.color.text.light.num1};
}
.ui.form .field > label {
margin-bottom: 8px;
}
.markup {
color: ${themeVars.color.text.self};
pre {
font-size: 12px;
font-weight: 400;
padding: 12px 16px;
}
}
+ .ui.top.attached.header {
margin-top: 24px;
}
}
}
.issue-content-right {
border: 0;
padding: 0px 16px;
> strong {
font-size: 16px;
}
> .divider {
margin: 16px 0px;
}
// 详情
> .ui.relaxed.list {
margin: 16px 0px;
.item {
color: ${themeVars.color.text.light.num1};
svg {
color: ${themeVars.color.text.self};
}
// 应该只选中版本中的 a 标签
&.tw-flex {
justify-content: space-between;
> a {
border: 1px solid ${themeVars.color.light.border};
border-radius: 25px;
font-size: 12px;
padding: 0px 6px;
min-height: 20px;
flex: none !important;
&:hover {
text-decoration: none;
}
}
// 不知道什么东西
&::after {
display: none;
}
}
}
}
}
}
}
`;

View File

@@ -11,6 +11,7 @@ export const releaseTagMenu = css`
font-weight: 500;
&.active {
background: ${themeVars.github.bgColor.accent.emphasis} !important;
color: ${themeVars.color.white};
}
}
}
@@ -18,6 +19,27 @@ export const releaseTagMenu = css`
}
`;
// 顶部右侧按钮组
export const rightButton = css`
.page-content.repository {
&.releases,
&.tags {
.ui.small.button {
background-color: ${themeVars.color.button};
border-color: ${themeVars.color.light.border};
box-shadow: none;
color: ${themeVars.color.text.light.self};
padding: 5px 16px;
min-height: auto;
line-height: 20px;
&:hover {
background-color: ${themeVars.color.hover.self};
}
}
}
}
`;
// 标签页样式
export const tags = css`
.page-content.repository.tags {
@@ -40,74 +62,114 @@ export const tags = css`
// 发布页样式
export const releases = css`
.page-content.repository.releases {
#release-list .release-entry {
// 左侧发布元信息
.meta {
gap: 0.5rem;
padding-top: 24px;
padding-right: 40px;
text-align: left;
min-width: 0;
flex: 0.125;
a.muted {
color: ${themeVars.color.text.light.num1};
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
svg {
margin-right: 8px !important;
> .ui.container > .divider {
margin: 16px 0;
}
ul#release-list {
gap: 32px;
margin: 32px 0 16px 0;
.release-entry {
// 左侧发布元信息
.meta {
gap: 0.5rem;
padding-top: 24px;
padding-right: 40px;
text-align: left;
min-width: 0;
flex: 0.125;
a.muted {
color: ${themeVars.color.text.light.num1};
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
svg {
margin-right: 8px !important;
}
svg.tw-mr-1.svg.octicon-tag {
margin-top: 1px;
}
}
svg.tw-mr-1.svg.octicon-tag {
margin-top: 1px;
// 分支选择按钮
.ui.button.branch-dropdown-button {
min-height: 20px;
line-height: 20px;
padding: 3px 12px;
font-size: 12px;
}
}
// 分支选择按钮
.ui.button.branch-dropdown-button {
min-height: 20px;
line-height: 20px;
padding: 3px 12px;
font-size: 12px;
}
}
// 右侧发布详细信息
.segment.detail {
.svg {
color: ${themeVars.color.text.light.num1};
}
p.text.grey {
margin: 16px 0;
.time {
color: ${themeVars.color.text.self};
// 右侧发布详细信息
.segment.detail {
padding: 16px;
.svg {
color: ${themeVars.color.text.light.num1};
}
}
.markup {
> *:first-child {
margin-top: 16px !important;
// 标题
.release-list-title {
font-size: 32px;
gap: 16px;
}
> *:last-child {
margin-bottom: 16px !important;
// 提交信息
p.text.grey {
display: flex;
gap: 6px;
flex-wrap: wrap;
margin: 24px 0 0 0;
span {
word-break: break-word;
}
.time {
color: ${themeVars.color.text.self};
}
}
// 发布内容
.markup {
> *:first-child {
margin-top: 24px !important;
}
}
// 分割线
.divider {
position: relative;
left: -16px;
width: calc(100% + 32px);
border-top-width: 1.5px;
margin: 24px 0 16px 0;
}
// 下载列表
.download {
summary {
font-size: 18px;
font-weight: 600;
margin-top: 16px;
&::marker {
font-size: 14px;
}
}
.attachment-list {
margin-top: 16px;
.item {
align-items: center;
line-height: 17px;
padding: 8px 16px;
.flex-text-inline {
gap: 8px;
}
// 只选中左侧文件名称
strong.flex-text-inline:hover {
text-decoration: underline !important;
}
.attachment-right-info {
color: ${themeVars.color.text.light.num1};
.svg {
height: 28px;
}
}
}
}
}
}
}
}
}
`;
// 顶部右侧按钮组
export const rightButton = css`
.page-content.repository {
&.releases,
&.tags {
.ui.small.button {
background-color: ${themeVars.color.button};
padding: 5px 16px;
min-height: auto;
line-height: 20px;
&:hover {
background-color: ${themeVars.color.hover.self};
}
}
}
}
`;

View File

@@ -80,12 +80,13 @@ export const repoTopic = css`
#repo-topics .ui.label.repo-topic {
border-radius: 25px;
font-size: 12px;
font-weight: 500;
padding: 5px 10px;
background-color: ${themeVars.github.bgColor.accent.muted};
color: ${themeVars.github.fgColor.accent};
&:hover {
background-color: ${themeVars.github.bgColor.accent.emphasis};
color: ${themeVars.color.text.self};
color: ${themeVars.color.white};
}
}
`;

View File

@@ -25,7 +25,7 @@ export const button = css`
color: ${themeVars.color.text.light.self};
background-color: ${themeVars.color.button};
border-color: ${themeVars.color.light.border};
box-shadow: none;
&:hover {
background-color: ${themeVars.color.hover.self};
}
@@ -57,12 +57,19 @@ export const button = css`
}
}
// 管理员设置界面下的自定义主色调按钮
.admin-setting-content .ui.primary.button {
${tinyStyle}
padding: 5px 16px;
line-height: 22px;
&:hover {
${tinyHoverStyle}
.admin-setting-content {
.ui.primary.button {
${tinyStyle}
padding: 5px 16px;
line-height: 22px;
&:hover {
${tinyHoverStyle}
}
}
.ui.red.button {
box-shadow: ${themeVars.github.shadow.resting.small};
padding: 5px 16px;
line-height: 22px;
}
}
`;
@@ -76,33 +83,3 @@ export const label = css`
}
}
`;
// 设置右面板的内容
export const content = css`
.user-main-content,
.repo-setting-content,
.user-setting-content,
.org-setting-content,
.admin-setting-content {
.ui.top.attached.header {
border: 0;
font-size: 1.5rem;
font-weight: 400;
background-color: unset !important;
margin-bottom: 0.25rem;
}
.ui.attached.segment {
background-color: unset;
border-radius: 0.5rem !important;
}
.ui.attached.segment:not(.error) {
border: 1px solid ${themeVars.color.light.border} !important;
}
.ui.attached.segment.error {
border: 1px solid ${themeVars.color.error.border} !important;
}
}
`;

View File

@@ -0,0 +1,62 @@
import { css } from "src/types/vars";
// 注册/登录界面
export const signIn = css`
.page-content.user.signin {
.ui.grid {
justify-content: center;
> .column {
width: 384px;
padding: 16px;
> .ui.container {
max-width: unset;
}
}
}
.ui.top.attached.header {
border: 0;
font-size: 20px;
font-weight: 600;
background-color: unset !important;
text-align: center;
padding: 16px;
}
.ui.attached.segment {
border: 0;
padding: 16px 0 0 0;
.field:not(.inline) {
label {
font-size: 14px;
font-weight: 600;
}
input {
background: unset;
padding: 5px 12px;
height: 40px;
font-size: 16px;
}
}
.button {
height: 40px;
}
.divider.divider-text {
margin: 20px 0px;
}
#oauth2-login-navigator-inner {
gap: 8px;
.ui.button svg {
width: 18px;
}
}
}
.ui.top.attached.header.segment {
font-size: 14px;
font-weight: 400;
gap: 16px;
.signin-passkey {
font-weight: 500;
}
}
}
`;

62
styles/components/user.ts Normal file
View File

@@ -0,0 +1,62 @@
import { css, themeVars } from "src/types/vars";
// 用户点星仓库列表
export const stars = css`
.page-content.user.profile {
.stars {
> .flex-list {
> .flex-item {
padding: 24px 0;
&:first-child {
padding-top: 14px;
}
// 仓库头像
> .flex-item-leading {
img,
svg {
color: ${themeVars.color.text.light.num1};
}
}
// 仓库信息
> .flex-item-main {
// 仓库标题
> .flex-item-header {
// 仓库名称
> .flex-item-title {
font-size: 20px;
gap: 8px;
// 仓库中间的间隔线
&:not(a) {
color: ${themeVars.color.primary.self};
}
}
// 仓库语言, 星标
> .flex-item-trailing {
color: ${themeVars.color.text.light.num1};
gap: 16px;
font-size: 12px;
> .flex-text-inline .color-icon {
width: 12px;
height: 12px;
margin-right: 0 !important;
}
}
}
// 描述和更新时间
> .flex-item-body {
margin-top: 10px;
// 更新时间
&:last-child {
font-size: 12px;
}
}
// 主题标签
> .label-list {
margin-top: 10px;
}
}
}
}
}
}
`;

View File

@@ -0,0 +1,27 @@
import { overlayAppearDown, overlayAppearUp } from "src/core/theme";
import { css } from "src/types/vars";
export const keyframe = css`
// 向下出现动画
@keyframes ${overlayAppearDown} {
0% {
opacity: 0;
transform: translateY(-8px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
// 向上出现动画
@keyframes ${overlayAppearUp} {
0% {
opacity: 0;
transform: translateY(8px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
`;

36
styles/public/attached.ts Normal file
View File

@@ -0,0 +1,36 @@
import { css, otherThemeVars, themeVars } from "src/types/vars";
export const attached = css`
// 设置右面板的内容
.user-main-content,
.repo-setting-content,
.user-setting-content,
.org-setting-content,
.admin-setting-content,
// 新建页面内容
.page-content.repository.new-repo,
.page-content.repository.new.migrate,
.page-content.repository.new.fork,
.page-content.organization.new.org {
.ui.top.attached.header {
border: 0;
font-size: 20px;
font-weight: 400;
background-color: unset !important;
margin-bottom: 0.25rem;
}
.ui.attached.segment {
background-color: unset;
border-radius: ${otherThemeVars.border.radius} !important;
}
.ui.attached.segment:not(.error) {
border: 1px solid ${themeVars.color.light.border} !important;
}
.ui.attached.segment.error {
border: 1px solid ${themeVars.color.error.border} !important;
}
}
`;

View File

@@ -4,6 +4,7 @@ export const primaryStyle = {
color: themeVars.github.button.primary.fgColor.rest,
backgroundColor: themeVars.github.button.primary.bgColor.rest,
borderColor: themeVars.github.button.primary.borderColor.rest,
boxShadow: themeVars.github.shadow.resting.small,
};
export const primaryHoverStyle = {
@@ -27,7 +28,7 @@ export const baseButton = css`
}
// 主色调按钮保持白色
.ui.primary.buttons .button svg {
color: ${themeVars.color.text.self};
color: ${themeVars.color.white};
}
.ui.primary {
&.button,
@@ -45,6 +46,7 @@ export const baseButton = css`
background-color: ${themeVars.color.button};
color: ${themeVars.color.text.self};
border-color: ${themeVars.color.light.border};
box-shadow: none;
&:hover {
background-color: ${themeVars.color.hover.self};
color: ${themeVars.color.text.self};
@@ -85,17 +87,32 @@ export const redButton = css`
color: ${themeVars.github.button.danger.fgColor.hover};
background-color: ${themeVars.github.button.danger.bgColor.hover};
border-color: ${themeVars.github.button.danger.borderColor.hover};
box-shadow: ${themeVars.github.shadow.resting.small};
}
}
`;
// 修复按钮高度
export const fixButtonHeight = css`
// 修复一些主色调或者其他小按钮的高度避免过高
.ui.small.buttons .button,
.ui.ui.ui.ui.small.button {
min-height: 26px;
height: 32px;
}
.ui.tiny.buttons .button,
// 修复仓库页仓库操作按钮高度对齐和修正
.repo-button-row .ui.button {
min-height: 32px;
}
// 修复因上面小按钮高度导致仓库星标克隆等按钮高度过高
.repo-header {
.ui.ui.ui.ui.small.compact.button,
.ui.labeled.button > .label {
height: 28px;
min-height: 28px;
}
}
.ui.ui.ui.ui.small.button.compact .ui.tiny.buttons .button,
.ui.ui.ui.ui.tiny.button {
min-height: 20px;
}
@@ -106,4 +123,9 @@ export const fixButton = css`
.ui.ui.ui.ui.small.button {
z-index: 0;
}
// 代码复制按钮
.ui.button.code-copy {
padding: 4px 6px;
min-height: 28px;
}
`;

View File

@@ -1,277 +0,0 @@
import { css } from "src/types/vars";
export const chroma = css`
.chroma {
background-color: var(--color-code-bg);
.lntd {
vertical-align: top;
border: 0;
margin: 0;
padding: 0;
}
.lntable {
border-spacing: 0;
border: 0;
width: auto;
margin: 0;
padding: 0;
display: block;
overflow: auto;
}
.hl {
width: 100%;
display: block;
}
.lnt,
.ln {
margin-right: 0.4em;
padding: 0 0.4em;
}
.gs {
font-weight: var(--font-weight-semibold);
}
.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;
}
.w {
color: #7f8699;
}
}
`;

View File

@@ -1,5 +1,6 @@
import { animationDown, animationUp } from "src/core/theme";
import { css, otherThemeVars, themeVars } from "src/types/vars";
import { fallbackVar } from "src/functions";
import { css, customThemeVars, otherThemeVars, themeVars } from "src/types/vars";
import { activeItemAfterStyle } from "styles/public/menu";
export const dropdown = css`
@@ -16,19 +17,18 @@ export const dropdown = css`
> .item:not(.tw-hidden) {
display: flex !important;
align-items: center;
gap: 0.5rem;
padding: 8px 10px !important;
padding: 6px 8px !important;
border-radius: ${otherThemeVars.border.radius} !important;
&:not(.emoji) {
margin: 0 0.5rem;
margin: 0 8px;
}
&:not(.emoji):first-of-type {
margin-top: 0.5rem;
margin-top: 8px;
}
// 不知道为什么提交差异对比页面操作中的 cherrypick 按钮无法被选中
&.cherry-pick-button,
&:not(.emoji):last-of-type {
margin-bottom: 0.5rem;
margin-bottom: 8px;
}
&:hover {
background-color: ${themeVars.github.control.transparent.bgColor.hover} !important;
@@ -46,9 +46,17 @@ export const dropdown = css`
${activeItemAfterStyle};
}
}
svg {
margin-top: 2px;
margin-right: 8px;
}
// 复选框对齐
.ui.checkbox input[type="checkbox"] {
height: 100%;
}
}
> .divider {
margin: 0.5rem 0;
margin: 8px 0;
}
&:after {
display: none !important;
@@ -58,18 +66,26 @@ export const dropdown = css`
// 向下弹出的下拉菜单向下偏移
.ui.dropdown:not(.upward),
.ui.menu .ui.dropdown:not(.upward) {
.menu {
margin-top: 0.35em !important;
> .menu {
margin-top: 4px !important;
}
}
// 向上弹出的下拉菜单向上偏移
.ui.dropdown.upward,
.ui.menu .ui.dropdown.upward {
.menu {
> .menu {
animation: ${animationUp};
margin-bottom: 0.35em !important;
margin-bottom: 4px !important;
}
}
// 修复 wiki 的页面下拉菜单圆角
.ui.floating.dropdown > .menu {
border-radius: 12px !important;
}
// 修复嵌套菜单的圆角问题, wiki 页面和组织页面的用户下拉菜单
.ui.dropdown .menu .scrolling.menu {
border-radius: 0 0 12px 12px !important;
}
// 修复下拉菜单元素溢出问题
// 用户菜单
.user-menu>.item,
@@ -120,6 +136,15 @@ export const selectionDropdown = css`
${activeItemAfterStyle};
}
}
// 修复顶部导航栏工单管理/请求合并页面搜索框旁的选择下拉框按钮内容过窄
.list-header-search .ui.action.input > .dropdown.small {
padding: 8px 40px 8px 16px;
}
// 发布版本页面的分支按钮, 覆盖 Gitea 的样式, 避免按钮元素高度不一致
.repository.new.release .target .selection.dropdown {
padding-top: 8px;
padding-bottom: 8px;
}
// 这个按钮项目前只在创建仓库的拥有者
// 不实现伪元素, 因为 .item 设置溢出的元素会被截断
.ui.selection.dropdown.ellipsis-text-items,
@@ -178,8 +203,12 @@ export const fixSelectionDropdown = css`
// 分支菜单
export const branchDropdown = css`
.ui.dropdown.branch-selector-dropdown .menu > .item {
animation: ${animationDown};
.ui.dropdown.branch-selector-dropdown > .menu {
width: ${fallbackVar(customThemeVars.branchMenuWidth, "320px")};
max-width: 640px;
> .menu > .item {
animation: ${animationDown};
}
}
`;

View File

@@ -2,10 +2,10 @@
// tslint:disable:ordered-imports
// 组件导入有顺序, 禁止插件优化
import "./radius"; // 圆角, 此样式为基础样式, 确保在其他样式之前导入
import "./animation"; // 动画效果
import "./transition"; // 过渡效果
import "./text"; // 文本或 SVG 的基本颜色
import "./button"; // 按钮
import "./chroma"; // 代码高亮
import "./dropdown"; // 下拉框
import "./input"; // 输入框
import "./label"; // 标签
@@ -13,3 +13,5 @@ import "./menu"; // 菜单
import "./modal"; // 弹窗
import "./tippy"; // 提示框
import "./navbar"; // 导航栏
import "./attached"; // 附加样式
import "./other"; // 其他样式

View File

@@ -35,7 +35,8 @@ export const input = css`
height: 32px;
}
// 由于输入框高度, 需要输入框在表单中垂直居中
.ui.form {
// 管理员页面仓库搜索表单
.ui.form#repo-search-form {
align-items: center;
}
`;

View File

@@ -67,6 +67,12 @@ export const label = css`
}
}
}
.ui.small.label {
font-size: 12px;
}
.ui.mini.label {
font-size: 10px;
}
`;
// 提交中的 SHA 标签
@@ -78,6 +84,8 @@ export const shaLabel = css`
color: ${themeVars.color.text.light.num1};
font-size: 12px;
font-weight: 500;
// 仪表盘页的提交 SHA 标签居中对齐
margin-top: 2px;
&:hover {
background-color: ${themeVars.color.label.hoverBg};
}
@@ -166,26 +174,17 @@ export const taskStatusLabel = css`
// 仓库标签 (私有/公开/内部)
export const repoLabel = css`
span,
// 用户切换面板的标签
.org-visibility div {
&.ui.basic.label {
background-color: unset;
color: ${themeVars.color.text.light.num1};
font-size: 12px;
font-weight: 500;
padding: 3px 6px;
}
}
`;
// 软件包列表
export const packagesLabel = css`
.page-content {
&.packages {
> .ui.container > div > .flex-list {
// 软件包类型的标签
.ui.label {
background-color: unset;
border: 1px solid ${themeVars.color.light.border};
color: ${themeVars.color.primary.self};
}
}
}
.org-visibility span.ui.basic.label {
font-size: 14px;
}
`;

View File

@@ -148,6 +148,7 @@ export const secondaryMenu = css`
padding: 0px 12px;
height: 32px;
font-weight: 500;
color: ${themeVars.color.text.light.num1};
}
}
// 二级导航栏, 比如仓库的导航栏, 仓库列表的导航栏, 探索的类型导航栏
@@ -193,3 +194,99 @@ export const secondaryMenu = css`
}
}
`;
// 分页菜单
export const paginationMenu = css`
.ui.borderless.pagination.menu {
align-items: center;
background-color: unset;
border: 0;
gap: 4px;
min-height: fit-content;
.item {
border-radius: ${otherThemeVars.border.radius};
min-width: 32px;
min-height: 32px;
height: 32px;
justify-content: center;
// 避免一些 hover 效果调整内容
padding: 5px 10px !important;
&.active {
background: ${themeVars.github.bgColor.accent.emphasis};
color: ${themeVars.color.white};
}
// 设置透明边框线避免 hover 时元素大小变化
&:not(.active) {
border: 1px solid #ffffff00;
&:hover {
background: unset;
border-color: ${themeVars.color.secondary.self};
}
}
&.navigation {
&:not(.disabled) {
span,
svg {
color: ${themeVars.color.primary.self};
}
}
// 对齐文字
svg {
margin-top: 2px;
}
}
}
}
`;
// 单行双选项菜单
export const smallCompactMenu = css`
// 订阅/关注切换菜单(应只选中订阅/关注页面, 不能选中通知页面)
.page-content.user.notification > .ui.container:has(.flex-list),
// 里程碑/标签切换菜单(里程碑页)
.page-content.repository.milestones .list-header,
// 里程碑/标签切换菜单(新建里程碑页)
.page-content.repository.new.milestone .issue-navbar,
// 里程碑/标签切换菜单(标签页)
.page-content.repository.labels .issue-navbar {
.ui.compact.small.menu.small-menu-items {
background: ${themeVars.color.hover.self} !important;
border: 0;
font-size: 14px;
gap: 8px;
height: 32px;
min-height: 32px !important;
> .item {
background: unset !important;
border: 1px solid ${themeVars.color.hover.self};
border-radius: ${otherThemeVars.border.radius};
padding: 6px 12px !important;
&.active {
background: ${themeVars.color.menu} !important;
border-color: ${themeVars.color.light.border};
font-weight: 600;
}
&::before {
display: none;
}
&:not(.active) {
top: 4px;
padding: 4px 12px !important;
height: calc(100% - 8px);
position: relative;
// 该方案只适用于 2 个 item 的情况
// left / right 数值为 gap 数值的一半
&:first-child {
left: 4px;
}
&:last-child {
right: 4px;
}
&:hover {
background: ${themeVars.github.control.transparent.bgColor.hover} !important;
}
}
}
}
}
`;

View File

@@ -1,8 +1,10 @@
import { css, otherThemeVars, themeVars } from "src/types/vars";
import { fallbackVar } from "src/functions";
import { css, customThemeVars, otherThemeVars, themeVars } from "src/types/vars";
export const navbarRight = css`
#navbar {
.navbar-right {
// 进入用户页面后, 避免注册, 登录和首页等意外覆盖
.navbar-right:has(.user-menu) {
gap: 8px;
// 右侧按钮, 但不包括头像
> .item:not(:last-child) {
@@ -34,7 +36,7 @@ export const navbarRight = css`
grid-auto-flow: column;
align-items: center;
> svg {
margin-right: 8px;
margin-right: 4px;
}
// 三角号纠正高度保持居中
.not-mobile {
@@ -68,7 +70,7 @@ export const navbarRight = css`
.navbar-profile-admin {
background-color: ${themeVars.github.bgColor.accent.emphasis};
border-radius: 25px;
color: ${themeVars.color.text.self};
color: ${themeVars.color.white};
font-size: 8px;
font-weight: 600;
padding: 2px 5px;
@@ -76,15 +78,53 @@ export const navbarRight = css`
left: 22px;
}
}
// 通知和计时器的圆点
a.item {
.notification_count,
.header-stopwatch-dot {
background-color: ${themeVars.github.bgColor.accent.emphasis};
border-radius: 25px;
color: ${themeVars.color.white};
font-size: 8px;
font-weight: 600;
top: -14px;
left: 12px;
}
}
}
// 用户菜单
.navbar-right .user-menu {
width: ${fallbackVar(customThemeVars.userMenuWidth, "192px")};
max-width: 320px;
> .header {
font-size: 14px;
font-weight: 400;
margin: 0;
padding: 16px 16px 8px 16px;
strong {
font-weight: 600;
}
}
> .divider {
margin: 8px;
width: calc(100% - 16px);
}
}
}
// 手机下的创建菜单按钮
@media (max-width: 767.98px) {
#navbar .navbar-right > .item:not(:last-child) {
#navbar .navbar-right:has(.user-menu) > .item:not(:last-child) {
display: none;
}
#navbar.navbar-menu-open .navbar-right > .item:not(:last-child) {
#navbar.navbar-menu-open .navbar-right:has(.user-menu) > .item:not(:last-child) {
display: grid;
}
}
`;
// 二级导航栏
export const secondaryNav = css`
.page-content > :first-child.secondary-nav {
margin-bottom: 16px;
}
`;

16
styles/public/other.ts Normal file
View File

@@ -0,0 +1,16 @@
import { css, themeVars } from "src/types/vars";
// 一些列表头, 比如工单的搜索标签里程碑栏
export const listHeader = css`
.list-header {
align-items: center;
align-content: center;
}
`;
// 已标星的图标
export const star = css`
.octicon-star-fill {
color: ${themeVars.github.button.star.iconColor} !important;
}
`;

View File

@@ -5,16 +5,19 @@ import { css, otherThemeVars, themeVars } from "src/types/vars";
export const tippyBox = css`
.tippy-box {
margin-top: -3px;
border-radius: 12px;
border-radius: ${otherThemeVars.border.radius};
overflow: hidden;
animation: ${animationDown};
// 边框线同步 github 样式
// 克隆菜单和PR提示框为 default
&[data-theme="default"],
// 带标题的提示框 (Runner信息)
&[data-theme="box-with-header"] {
border: unset;
box-shadow: ${themeVars.github.shadow.floating.small};
}
// 带标题的提示框 (Runner信息)
&[data-theme="default"] {
border-radius: 12px;
}
&[data-theme="box-with-header"] {
.tippy-content {
background-color: ${themeVars.color.menu};
@@ -26,7 +29,7 @@ export const tippyBox = css`
// 差异对比中文件路径行右侧的三个点菜单
&[data-theme="menu"] {
.tippy-content {
padding: 0.5rem;
padding: 8px;
.item {
border-radius: ${otherThemeVars.border.radius};
&:hover {
@@ -35,5 +38,13 @@ export const tippyBox = css`
}
}
}
// 专门用于提示信息的提示框, 比如提交的具体时间, 任务状态等
&[data-theme="tooltip"] {
.tippy-content {
font-size: 12px;
font-weight: 400;
padding: 4px 8px;
}
}
}
`;

View File

@@ -2,6 +2,18 @@ import { css } from "src/types/vars";
// 简单的渐变过渡
export const transition = css`
// 差异对比的代码折叠按钮
.code-expander-button,
// 仓库 README 头部的按钮
.file-header-left,
.file-header-right,
// 仪表板仓库列表
.ui.attached.segment.table ul li,
// Issue 列表
.issue-list-toolbar .item,
.flex-list#issue-list > .flex-item,
// 分页菜单
.ui.borderless.pagination.menu .item,
// 迁移的元素
#navbar .item,
.header-wrapper .ui.tabular.menu .item,

View File

@@ -0,0 +1,82 @@
/**
* @author lutinglt
*/
import { defineTheme, themeVars, type Chroma } from "src";
import { github2ThemeColor, type GithubColor } from "src/core/github";
import { prettylights2Chroma, type prettylightsColor } from "src/core/prettylights";
import { darkGithubColors } from "themes/dark";
export const colorblindDarkGithubColors: GithubColor = {
isDarkTheme: true,
display: darkGithubColors.display,
diffBlob: {
addtionNum: { bgColor: "#58a6ff4d" },
addtionWord: { bgColor: "#388bfd66" },
deletionNum: { bgColor: "#db6d284d" },
deletionWord: { bgColor: "#db6d2866" },
hunkNum: { bgColor: { rest: "#2f3742" } },
},
fgColor: {
...darkGithubColors.fgColor,
danger: "#f0883e",
success: "#58a6ff",
},
bgColor: {
...darkGithubColors.bgColor,
danger: { muted: "#db6d281a" },
success: { emphasis: "#1f6feb", muted: "#388bfd33" },
},
borderColor: {
...darkGithubColors.borderColor,
success: { emphasis: "#1f6feb" },
},
button: {
primary: {
fgColor: { accent: "#58a6ff", rest: "#ffffff" },
bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#2a7aef" },
},
danger: { fgColor: { rest: "#f0883e", hover: "#ffffff" }, bgColor: { hover: "#9b4215" } },
star: darkGithubColors.button.star,
},
control: darkGithubColors.control,
shadow: darkGithubColors.shadow,
overlay: darkGithubColors.overlay,
underlineNav: darkGithubColors.underlineNav,
contribution: darkGithubColors.contribution,
};
export const colorblindDarkPrettylights: prettylightsColor = {
syntax: {
brackethighlighter: { angle: "#9198a1", unmatched: "#db6d28" },
carriage: { return: { bg: "#9b4215", text: "#f0f6fc" } },
comment: "#9198a1",
constant: "#79c0ff",
constantOtherReferenceLink: "#a5d6ff",
entity: "#d2a8ff",
entityTag: "#a5d6ff",
invalid: { illegal: { bg: "#762d0a", text: "#f0f6fc" } },
keyword: "#f0883e",
markup: {
bold: "#f0f6fc",
changed: { bg: "#5a1e02", text: "#ffdfb6" },
deleted: { bg: "#5a1e02", text: "#ffdfb6" },
heading: "#1f6feb",
ignored: { bg: "#1158c7", text: "#f0f6fc" },
inserted: { bg: "#0c2d6b", text: "#cae8ff" },
italic: "#f0f6fc",
list: "#f2cc60",
},
metaDiffRange: "#d2a8ff",
storageModifierImport: "#f0f6fc",
string: "#a5d6ff",
stringRegexp: "#a5d6ff",
sublimelinterGutterMark: "#3d444d",
variable: "#ffa657",
},
};
export const colorblindDarkColors = github2ThemeColor(colorblindDarkGithubColors);
export const colorblindDarkChroma: Chroma = prettylights2Chroma(colorblindDarkPrettylights);
export default defineTheme(colorblindDarkColors, colorblindDarkChroma);

View File

@@ -0,0 +1,82 @@
/**
* @author lutinglt
*/
import { defineTheme, themeVars, type Chroma } from "src";
import { github2ThemeColor, type GithubColor } from "src/core/github";
import { prettylights2Chroma, type prettylightsColor } from "src/core/prettylights";
import { lightGithubColors } from "themes/light";
export const colorblindLightGithubColors: GithubColor = {
isDarkTheme: false,
display: lightGithubColors.display,
diffBlob: {
addtionNum: { bgColor: "#b6e3ff" },
addtionWord: { bgColor: "#b6e3ff" },
deletionNum: { bgColor: "#ffd8b5" },
deletionWord: { bgColor: "#ffd8b5" },
hunkNum: { bgColor: { rest: "#e6eaef" } },
},
fgColor: {
...lightGithubColors.fgColor,
danger: "#bc4c00",
success: "#0969da",
},
bgColor: {
...lightGithubColors.bgColor,
danger: { muted: "#fff1e5" },
success: { emphasis: "#0969da", muted: "#ddf4ff" },
},
borderColor: {
...lightGithubColors.borderColor,
success: { emphasis: "#0969da" },
},
button: {
primary: {
fgColor: { accent: "#0969da", rest: "#ffffff" },
bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#0864d1" },
},
danger: { fgColor: { rest: "#bc4c00", hover: "#ffffff" }, bgColor: { hover: "#bc4c00" } },
star: lightGithubColors.button.star,
},
control: lightGithubColors.control,
shadow: lightGithubColors.shadow,
overlay: lightGithubColors.overlay,
underlineNav: lightGithubColors.underlineNav,
contribution: lightGithubColors.contribution,
};
export const colorblindLightPrettylights: prettylightsColor = {
syntax: {
brackethighlighter: { angle: "#59636e", unmatched: "#762c00" },
carriage: { return: { bg: "#bc4c00", text: "#f6f8fa" } },
comment: "#59636e",
constant: "#0550ae",
constantOtherReferenceLink: "#0a3069",
entity: "#6639ba",
entityTag: "#0550ae",
invalid: { illegal: { bg: "#762c00", text: "#f6f8fa" } },
keyword: "#bc4c00",
markup: {
bold: "#1f2328",
changed: { bg: "#ffd8b5", text: "#953800" },
deleted: { bg: "#fff1e5", text: "#762c00" },
heading: "#0550ae",
ignored: { bg: "#0550ae", text: "#d1d9e0" },
inserted: { bg: "#ddf4ff", text: "#0550ae" },
italic: "#1f2328",
list: "#3b2300",
},
metaDiffRange: "#8250df",
storageModifierImport: "#1f2328",
string: "#0a3069",
stringRegexp: "#0550ae",
sublimelinterGutterMark: "#818b98",
variable: "#953800",
},
};
export const colorblindLightColors = github2ThemeColor(colorblindLightGithubColors);
export const colorblindLightChroma: Chroma = prettylights2Chroma(colorblindLightPrettylights);
export default defineTheme(colorblindLightColors, colorblindLightChroma);

View File

@@ -1,8 +1,14 @@
import { defineGithubTheme, type GithubColor } from "src/core/github";
/**
* @author lutinglt
*/
const github: GithubColor = {
import { defineTheme, themeVars } from "src";
import { github2ThemeColor, type GithubColor } from "src/core/github";
export const darkGithubColors: GithubColor = {
isDarkTheme: true,
display: {
blue: { fgColor: "#4493f8" },
brown: { fgColor: "#b69a6d" },
cyan: { fgColor: "#07ace4" },
indigo: { fgColor: "#9899ec" },
@@ -22,53 +28,61 @@ const github: GithubColor = {
attention: "#d29922",
danger: "#f85149",
default: "#f0f6fc",
disabled: "#656c7699",
disabled: "#656c76",
done: "#ab7df8",
muted: "#9198a1",
neutral: "#9198a1",
severe: "#db6d28",
sponsors: "#db61a2",
success: "#3fb950",
black: "#010409",
white: "#ffffff",
muted: "#9198a1",
onEmphasis: "#ffffff",
},
bgColor: {
accent: { emphasis: "#1f6feb", muted: "#388bfd1a" },
attention: { muted: "#bb800926" },
success: { emphasis: "#238636", muted: "#2ea04326" },
danger: { muted: "#f851491a" },
done: { emphasis: "#8957e5" },
default: "#0d1117",
inset: "#010409",
done: { emphasis: "#8957e5" },
emphasis: "#3d444d",
muted: "#151b23",
neutral: { muted: "#656c7633" },
success: { emphasis: "#238636", muted: "#2ea04326" },
inset: "#010409",
},
borderColor: {
accent: { emphasis: "#1f6feb" },
default: "#3d444d",
attention: { emphasis: "#9e6a03" },
success: { emphasis: "#238636" },
default: "#3d444d",
done: { emphasis: "#8957e5" },
success: { emphasis: "#238636" },
muted: "#3d444db3",
translucent: "#ffffff26",
},
button: {
primary: { fgColor: { accent: "#39d353", rest: "#ffffff" }, bgColor: { rest: "#238636", hover: "#29903b" } },
primary: {
fgColor: { accent: "#3fb950", rest: "#ffffff" },
bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#29903b" },
},
danger: { fgColor: { rest: "#fa5e55", hover: "#ffffff" }, bgColor: { hover: "#b62324" } },
star: { iconColor: "#e3b341" },
},
control: {
bgColor: { active: "#2a313c", hover: "#262c36", rest: "#212830" },
transparent: { bgColor: { active: "#656c7640", hover: "#656c7633", selected: "#656c761a" } },
},
shadow: { floating: "#01040966" },
shadow: { floating: { small: "#01040966" }, resting: { small: "#01040999" } },
overlay: { backdrop: { bgColor: "#21283066" } },
underlineNav: { borderColor: { active: "#f78166" } },
contribution: {
default: {
bgColor: { num0: "#151b23", num1: "#033a16", num2: "#196c2e", num3: "#2ea043", num4: "#56d364", num5: "#7ee787" },
bgColor: { num0: "#151b23", num1: "#033a16", num2: "#196c2e", num3: "#2ea043", num4: "#56d364" },
borderColor: { num0: "#0104090d" },
},
},
};
export default defineGithubTheme(github);
export const darkColors = github2ThemeColor(darkGithubColors);
export default defineTheme(darkColors);

88
themes/light.css.ts Normal file
View File

@@ -0,0 +1,88 @@
/**
* @author lutinglt
*/
import { defineTheme, themeVars } from "src";
import { github2ThemeColor, type GithubColor } from "src/core/github";
export const lightGithubColors: GithubColor = {
isDarkTheme: false,
display: {
blue: { fgColor: "#0969da" },
brown: { fgColor: "#755f43" },
cyan: { fgColor: "#006a80" },
indigo: { fgColor: "#494edf" },
lemon: { fgColor: "#786002" },
olive: { fgColor: "#56682c" },
teal: { fgColor: "#106e75" },
},
diffBlob: {
addtionNum: { bgColor: "#aceebb" },
addtionWord: { bgColor: "#aceebb" },
deletionNum: { bgColor: "#ffcecb" },
deletionWord: { bgColor: "#ffcecb" },
hunkNum: { bgColor: { rest: "#b6e3ff" } },
},
fgColor: {
accent: "#0969da",
attention: "#9a6700",
danger: "#d1242f",
default: "#1f2328",
disabled: "#818b98",
done: "#8250df",
muted: "#59636e",
neutral: "#59636e",
severe: "#bc4c00",
sponsors: "#bf3989",
success: "#1a7f37",
black: "#1f2328",
white: "#ffffff",
onEmphasis: "#ffffff",
},
bgColor: {
accent: { emphasis: "#0969da", muted: "#ddf4ff" },
attention: { muted: "#fff8c5" },
danger: { muted: "#ffebe9" },
default: "#ffffff",
done: { emphasis: "#8250df" },
emphasis: "#25292e",
muted: "#f6f8fa",
neutral: { muted: "#818b981f" },
success: { emphasis: "#1f883d", muted: "#dafbe1" },
inset: "#f6f8fa",
},
borderColor: {
accent: { emphasis: "#0969da" },
attention: { emphasis: "#9a6700" },
default: "#d1d9e0",
done: { emphasis: "#8250df" },
success: { emphasis: "#1a7f37" },
muted: "#d1d9e0b3",
translucent: "#1f232826",
},
button: {
primary: {
fgColor: { accent: "#1a7f37", rest: "#ffffff" },
bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#1c8139" },
},
danger: { fgColor: { rest: "#d1242f", hover: "#ffffff" }, bgColor: { hover: "#cf222e" } },
star: { iconColor: "#eac54f" },
},
control: {
bgColor: { active: "#e6eaef", hover: "#eff2f5", rest: "#f6f8fa" },
transparent: { bgColor: { active: "#818b9826", hover: "#818b981a", selected: "#818b9826" } },
},
shadow: { floating: { small: "#25292e0a" }, resting: { small: "#1f23280f" } },
overlay: { backdrop: { bgColor: "#c8d1da66" } },
underlineNav: { borderColor: { active: "#fd8c73" } },
contribution: {
default: {
bgColor: { num0: "#eff2f5", num1: "#aceebb", num2: "#4ac26b", num3: "#2da44e", num4: "#116329" },
borderColor: { num0: "#1f23280d" },
},
},
};
export const lightColors = github2ThemeColor(lightGithubColors);
export default defineTheme(lightColors);

26
themes/pink-dark.css.ts Normal file
View File

@@ -0,0 +1,26 @@
/**
* @author lutinglt
*/
import { defineTheme } from "src";
import { display2GithubColor, type DisplayColor } from "src/core/display";
import { github2ThemeColor } from "src/core/github";
import { darkGithubColors } from "themes/dark";
export const pinkDarkDisplayColors: DisplayColor = {
num0: "#2d1524",
num1: "#451c35",
num2: "#65244a",
num3: "#842a5d",
num4: "#ac2f74",
num5: "#d34591",
num6: "#e57bb2",
num7: "#ec8dbd",
num8: "#f4a9cd",
num9: "#f9bed9",
};
export const pinkDarkGithubColors = display2GithubColor(pinkDarkDisplayColors, darkGithubColors);
export const pinkDarkColors = github2ThemeColor(pinkDarkGithubColors);
export default defineTheme(pinkDarkColors);

26
themes/pink-light.css.ts Normal file
View File

@@ -0,0 +1,26 @@
/**
* @author lutinglt
*/
import { defineTheme } from "src";
import { display2GithubColor, type DisplayColor } from "src/core/display";
import { github2ThemeColor } from "src/core/github";
import { lightGithubColors } from "themes/light";
export const pinkLightDisplayColors: DisplayColor = {
num0: "#ffe5f1",
num1: "#fdc9e2",
num2: "#f8a5cf",
num3: "#f184bc",
num4: "#e55da5",
num5: "#ce2c85",
num6: "#b12f79",
num7: "#8e2e66",
num8: "#6e2b53",
num9: "#4d233d",
};
export const pinkLightGithubColors = display2GithubColor(pinkLightDisplayColors, lightGithubColors);
export const pinkLightColors = github2ThemeColor(pinkLightGithubColors);
export default defineTheme(pinkLightColors);

View File

@@ -0,0 +1,14 @@
/**
* @author lutinglt
*/
import { defineTheme } from "src";
import { display2GithubColor } from "src/core/display";
import { github2ThemeColor } from "src/core/github";
import { softDarkGithubColors } from "themes/soft-dark";
import { pinkDarkDisplayColors } from "./pink-dark.css";
export const pinkSoftDarkGithubColors = display2GithubColor(pinkDarkDisplayColors, softDarkGithubColors, true);
export const pinkSoftDarkColors = github2ThemeColor(pinkSoftDarkGithubColors);
export default defineTheme(pinkSoftDarkColors);

113
themes/soft-dark.css.ts Normal file
View File

@@ -0,0 +1,113 @@
/**
* @author lutinglt
*/
import { defineTheme, themeVars, type Chroma } from "src";
import { github2ThemeColor, type GithubColor } from "src/core/github";
import { prettylights2Chroma, type prettylightsColor } from "src/core/prettylights";
import { darkGithubColors } from "themes/dark";
export const softDarkGithubColors: GithubColor = {
isDarkTheme: true,
display: darkGithubColors.display,
diffBlob: {
addtionNum: { bgColor: "#57ab5a4d" },
addtionWord: { bgColor: "#46954a66" },
deletionNum: { bgColor: "#e5534b4d" },
deletionWord: { bgColor: "#e5534b66" },
hunkNum: { bgColor: { rest: "#143d79" } },
},
fgColor: {
accent: "#478be6",
attention: "#c69026",
danger: "#e5534b",
default: "#d1d7e0",
disabled: "#656c76",
done: "#986ee2",
muted: "#9198a1",
neutral: "#9198a1",
severe: "#cc6b2c",
sponsors: "#c96198",
success: "#57ab5a",
black: "#010409",
white: "#cdd9e5",
onEmphasis: "#ffffff",
},
bgColor: {
accent: { emphasis: "#316dca", muted: "#4184e41a" },
attention: { muted: "#ae7c1426" },
danger: { muted: "#e5534b1a" },
default: "#212830",
done: { emphasis: "#8256d0" },
emphasis: "#3d444d",
muted: "#262c36",
neutral: { muted: "#656c7633" },
success: { emphasis: "#347d39", muted: "#46954a26" },
inset: "#151b23",
},
borderColor: {
accent: { emphasis: "#316dca" },
attention: { emphasis: "#966600" },
default: "#3d444d",
done: { emphasis: "#8256d0" },
success: { emphasis: "#347d39" },
muted: "#3d444db3",
translucent: "#cdd9e526",
},
button: {
primary: {
fgColor: { accent: "#57ab5a", rest: "#ffffff" },
bgColor: { rest: themeVars.github.bgColor.success.emphasis, hover: "#3b8640" },
},
danger: { fgColor: { rest: "#ea5c53", hover: "#ffffff" }, bgColor: { hover: "#ad2e2c" } },
star: { iconColor: "#daaa3f" },
},
control: {
bgColor: { active: "#3d444d", hover: "#2f3742", rest: "#2a313c" },
transparent: { bgColor: { active: "#656c7633", hover: "#656c7626", selected: "#656c761a" } },
},
shadow: { floating: { small: "#01040966" }, resting: { small: "#01040999" } },
overlay: { backdrop: { bgColor: "#262c3666" } },
underlineNav: { borderColor: { active: "#ec775c" } },
contribution: {
default: {
bgColor: { num0: "#2a313c", num1: "#1b4721", num2: "#2b6a30", num3: "#46954a", num4: "#6bc46d" },
borderColor: { num0: "#0104090d" },
},
},
};
export const softDarkPrettylights: prettylightsColor = {
syntax: {
brackethighlighter: { angle: "#9198a1", unmatched: "#e5534b" },
carriage: { return: { bg: "#ad2e2c", text: "#f0f6fc" } },
comment: "#9198a1",
constant: "#6cb6ff",
constantOtherReferenceLink: "#96d0ff",
entity: "#dcbdfb",
entityTag: "#8ddb8c",
invalid: { illegal: { bg: "#922323", text: "#f0f6fc" } },
keyword: "#f47067",
markup: {
bold: "#f0f6fc",
changed: { bg: "#682d0f", text: "#ffddb0" },
deleted: { bg: "#78191b", text: "#ffd8d3" },
heading: "#316dca",
ignored: { bg: "#255ab2", text: "#f0f6fc" },
inserted: { bg: "#1b4721", text: "#b4f1b4" },
italic: "#f0f6fc",
list: "#eac55f",
},
metaDiffRange: "#dcbdfb",
storageModifierImport: "#f0f6fc",
string: "#96d0ff",
stringRegexp: "#8ddb8c",
sublimelinterGutterMark: "#3d444d",
variable: "#f69d50",
},
};
export const softDarkColors = github2ThemeColor(softDarkGithubColors);
export const softDarkChroma: Chroma = prettylights2Chroma(softDarkPrettylights);
export default defineTheme(softDarkColors, softDarkChroma);

View File

@@ -0,0 +1,49 @@
/**
* @author lutinglt
*/
import { defineTheme, type Chroma } from "src";
import { darkPrettylights } from "src/core/chroma";
import { github2ThemeColor, type GithubColor } from "src/core/github";
import { prettylights2Chroma, type prettylightsColor } from "src/core/prettylights";
import { colorblindDarkGithubColors, colorblindDarkPrettylights } from "themes/colorblind-dark";
import { darkGithubColors } from "themes/dark";
export const tritanopiaDarkGithubColors: GithubColor = {
...colorblindDarkGithubColors,
diffBlob: {
...colorblindDarkGithubColors.diffBlob,
deletionNum: darkGithubColors.diffBlob.deletionNum,
deletionWord: darkGithubColors.diffBlob.deletionWord,
},
fgColor: {
...colorblindDarkGithubColors.fgColor,
danger: darkGithubColors.fgColor.danger,
},
bgColor: {
...colorblindDarkGithubColors.bgColor,
danger: darkGithubColors.bgColor.danger,
},
button: {
...colorblindDarkGithubColors.button,
danger: darkGithubColors.button.danger,
},
};
export const tritanopiaDarkPrettylights: prettylightsColor = {
syntax: {
...darkPrettylights.syntax,
markup: {
...darkPrettylights.syntax.markup,
changed: { bg: "#67060c", text: "#ffdcd7" },
inserted: colorblindDarkPrettylights.syntax.markup.inserted,
},
stringRegexp: colorblindDarkPrettylights.syntax.stringRegexp,
variable: "#ffa198",
},
};
export const tritanopiaDarkColors = github2ThemeColor(tritanopiaDarkGithubColors);
export const tritanopiaDarkChroma: Chroma = prettylights2Chroma(tritanopiaDarkPrettylights);
export default defineTheme(tritanopiaDarkColors, tritanopiaDarkChroma);

View File

@@ -0,0 +1,49 @@
/**
* @author lutinglt
*/
import { defineTheme, type Chroma } from "src";
import { lightPrettylights } from "src/core/chroma";
import { github2ThemeColor, type GithubColor } from "src/core/github";
import { prettylights2Chroma, type prettylightsColor } from "src/core/prettylights";
import { colorblindLightGithubColors, colorblindLightPrettylights } from "themes/colorblind-light";
import { lightGithubColors } from "themes/light";
export const tritanopiaLightGithubColors: GithubColor = {
...colorblindLightGithubColors,
diffBlob: {
...colorblindLightGithubColors.diffBlob,
deletionNum: lightGithubColors.diffBlob.deletionNum,
deletionWord: lightGithubColors.diffBlob.deletionWord,
},
fgColor: {
...colorblindLightGithubColors.fgColor,
danger: lightGithubColors.fgColor.danger,
},
bgColor: {
...colorblindLightGithubColors.bgColor,
danger: lightGithubColors.bgColor.danger,
},
button: {
...colorblindLightGithubColors.button,
danger: lightGithubColors.button.danger,
},
};
export const tritanopiaLightPrettylights: prettylightsColor = {
syntax: {
...lightPrettylights.syntax,
markup: {
...lightPrettylights.syntax.markup,
changed: { bg: "#ffcecb", text: "#a40e26" },
inserted: colorblindLightPrettylights.syntax.markup.inserted,
},
stringRegexp: colorblindLightPrettylights.syntax.stringRegexp,
variable: "#a40e26",
},
};
export const tritanopiaLightColors = github2ThemeColor(tritanopiaLightGithubColors);
export const tritanopiaLightChroma: Chroma = prettylights2Chroma(tritanopiaLightPrettylights);
export default defineTheme(tritanopiaLightColors, tritanopiaLightChroma);

View File

@@ -34,7 +34,7 @@ export default defineConfig(({ mode }) => {
},
plugins: [
linaria({
include: ["**/*.{ts,tsx}"],
include: ["**/*.ts"],
babelOptions: {
presets: ["@babel/preset-typescript"],
},