mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-10-02 16:37:53 +00:00
feat: 迁移前端资源文件并重构项目结构
refactor: 优化前端代码结构和资源管理 style: 调整前端代码格式和样式 chore: 更新.gitignore和构建配置 fix: 修复前端资源路径和引用问题 docs: 更新前端文档和注释 perf: 优化前端性能和加载速度 test: 更新前端测试用例 build: 调整前端构建配置 ci: 更新CI/CD配置
This commit is contained in:
Executable
+299
@@ -0,0 +1,299 @@
|
||||
// 全局样式
|
||||
// 顶部进度条颜色
|
||||
#nprogress .bar {
|
||||
z-index: 2400;
|
||||
background-color: color-mix(in srgb, var(--theme-color) 70%, white);
|
||||
}
|
||||
|
||||
#nprogress .peg {
|
||||
box-shadow:
|
||||
0 0 10px var(--theme-color),
|
||||
0 0 5px var(--theme-color) !important;
|
||||
}
|
||||
|
||||
#nprogress .spinner-icon {
|
||||
border-top-color: var(--theme-color) !important;
|
||||
border-left-color: var(--theme-color) !important;
|
||||
}
|
||||
|
||||
// 处理移动端组件兼容性
|
||||
@media screen and (max-width: 640px) {
|
||||
* {
|
||||
cursor: default !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 背景滤镜
|
||||
*,
|
||||
::before,
|
||||
::after {
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia: ;
|
||||
}
|
||||
|
||||
// 色弱模式
|
||||
.color-weak {
|
||||
filter: invert(80%);
|
||||
-webkit-filter: invert(80%);
|
||||
}
|
||||
|
||||
#noop {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// 语言切换选中样式
|
||||
.langDropDownStyle {
|
||||
// 选中项背景颜色
|
||||
.is-selected {
|
||||
background-color: var(--art-el-active-color) !important;
|
||||
}
|
||||
|
||||
// 语言切换按钮菜单样式优化
|
||||
.lang-btn-item {
|
||||
.el-dropdown-menu__item {
|
||||
padding-left: 13px !important;
|
||||
padding-right: 6px !important;
|
||||
margin-bottom: 3px !important;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
.el-dropdown-menu__item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-txt {
|
||||
min-width: 60px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 10px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 盒子默认边框
|
||||
.page-content {
|
||||
border: 1px solid var(--art-card-border) !important;
|
||||
}
|
||||
|
||||
@mixin art-card-base($border-color, $shadow: none, $radius-diff: 4px) {
|
||||
background: var(--default-box-color);
|
||||
border: 1px solid #{$border-color} !important;
|
||||
border-radius: calc(var(--custom-radius) + #{$radius-diff}) !important;
|
||||
box-shadow: #{$shadow} !important;
|
||||
|
||||
--el-card-border-color: var(--default-border) !important;
|
||||
}
|
||||
|
||||
.art-card,
|
||||
.art-card-sm,
|
||||
.art-card-xs {
|
||||
border: 1px solid var(--art-card-border);
|
||||
}
|
||||
|
||||
// 盒子边框
|
||||
[data-box-mode='border-mode'] {
|
||||
.page-content,
|
||||
.art-table-card {
|
||||
border: 1px solid var(--art-card-border) !important;
|
||||
}
|
||||
|
||||
.art-card {
|
||||
@include art-card-base(var(--art-card-border), none, 4px);
|
||||
}
|
||||
|
||||
.art-card-sm {
|
||||
@include art-card-base(var(--art-card-border), none, 0px);
|
||||
}
|
||||
|
||||
.art-card-xs {
|
||||
@include art-card-base(var(--art-card-border), none, -4px);
|
||||
}
|
||||
}
|
||||
|
||||
// 盒子阴影
|
||||
[data-box-mode='shadow-mode'] {
|
||||
.page-content,
|
||||
.art-table-card {
|
||||
box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.04) !important;
|
||||
border: 1px solid var(--art-gray-200) !important;
|
||||
}
|
||||
|
||||
.layout-sidebar {
|
||||
border-right: 1px solid var(--art-card-border) !important;
|
||||
}
|
||||
|
||||
.art-card {
|
||||
@include art-card-base(
|
||||
var(--art-gray-200),
|
||||
(0 1px 3px 0 rgba(0, 0, 0, 0.03), 0 1px 2px -1px rgba(0, 0, 0, 0.08)),
|
||||
4px
|
||||
);
|
||||
}
|
||||
|
||||
.art-card-sm {
|
||||
@include art-card-base(
|
||||
var(--art-gray-200),
|
||||
(0 1px 3px 0 rgba(0, 0, 0, 0.03), 0 1px 2px -1px rgba(0, 0, 0, 0.08)),
|
||||
2px
|
||||
);
|
||||
}
|
||||
|
||||
.art-card-xs {
|
||||
@include art-card-base(
|
||||
var(--art-gray-200),
|
||||
(0 1px 2px 0 rgba(0, 0, 0, 0.03), 0 1px 1px -1px rgba(0, 0, 0, 0.08)),
|
||||
-4px
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 元素全屏
|
||||
.el-full-screen {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100vw !important;
|
||||
height: 100% !important;
|
||||
z-index: 2300;
|
||||
margin-top: 0;
|
||||
padding: 15px;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--default-box-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
// 表格卡片
|
||||
.art-table-card {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
margin-top: 12px;
|
||||
border-radius: calc(var(--custom-radius) / 2 + 2px) !important;
|
||||
|
||||
.el-card__body {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
// 容器全高:沿布局 flex 链填满 `#app-scroll-main` 内剩余高度,底部自然对齐 #app-content 的 padding(勿再用 100vh 估算)
|
||||
.art-full-height {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
|
||||
@media (max-width: 640px) {
|
||||
flex: 0 1 auto;
|
||||
min-height: 0;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// 徽章样式
|
||||
.art-badge {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 20px;
|
||||
bottom: 0;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
margin: auto;
|
||||
background: #ff3860;
|
||||
border-radius: 50%;
|
||||
animation: breathe 1.5s ease-in-out infinite;
|
||||
|
||||
&.art-badge-horizontal {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&.art-badge-mixed {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&.art-badge-dual {
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
bottom: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// 文字徽章样式
|
||||
.art-text-badge {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 12px;
|
||||
bottom: 0;
|
||||
min-width: 20px;
|
||||
height: 18px;
|
||||
line-height: 17px;
|
||||
padding: 0 5px;
|
||||
margin: auto;
|
||||
font-size: 10px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background: #fd4e4e;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
@keyframes breathe {
|
||||
0% {
|
||||
opacity: 0.7;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0.7;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
// 修复老机型 loading 定位问题
|
||||
.art-loading-fix {
|
||||
position: fixed !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
bottom: 0 !important;
|
||||
width: 100vw !important;
|
||||
height: 100vh !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
}
|
||||
|
||||
.art-loading-fix .el-loading-spinner {
|
||||
position: static !important;
|
||||
top: auto !important;
|
||||
left: auto !important;
|
||||
transform: none !important;
|
||||
}
|
||||
|
||||
// 去除移动端点击背景色
|
||||
@media screen and (max-width: 1180px) {
|
||||
* {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
}
|
||||
Executable
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 深色主题
|
||||
* 单页面移除深色主题 document.getElementsByTagName("html")[0].removeAttribute('class')
|
||||
*/
|
||||
|
||||
$font-color: rgba(#ffffff, 0.85);
|
||||
|
||||
/* 覆盖element-plus默认深色背景色 */
|
||||
html.dark {
|
||||
// element-plus
|
||||
--el-bg-color: var(--default-box-color);
|
||||
--el-text-color-regular: #{$font-color};
|
||||
|
||||
// 富文本编辑器
|
||||
// 工具栏背景颜色
|
||||
--w-e-toolbar-bg-color: #18191c;
|
||||
// 输入区域背景颜色
|
||||
--w-e-textarea-bg-color: #090909;
|
||||
// 工具栏文字颜色
|
||||
--w-e-toolbar-color: var(--art-gray-600);
|
||||
// 选中菜单颜色
|
||||
--w-e-toolbar-active-bg-color: #25262b;
|
||||
// 弹窗边框颜色
|
||||
--w-e-toolbar-border-color: var(--default-border-dashed);
|
||||
// 分割线颜色
|
||||
--w-e-textarea-border-color: var(--default-border-dashed);
|
||||
// 链接输入框边框颜色
|
||||
--w-e-modal-button-border-color: var(--default-border-dashed);
|
||||
// 表格头颜色
|
||||
--w-e-textarea-slight-bg-color: #090909;
|
||||
// 按钮背景颜色
|
||||
--w-e-modal-button-bg-color: #090909;
|
||||
// hover toolbar 背景颜色
|
||||
--w-e-toolbar-active-color: var(--art-gray-800);
|
||||
}
|
||||
|
||||
.dark {
|
||||
.page-content .article-list .item .left .outer > div {
|
||||
border-right-color: var(--dark-border-color) !important;
|
||||
}
|
||||
|
||||
// 富文本编辑器
|
||||
.editor-wrapper {
|
||||
*:not(pre code *) {
|
||||
color: inherit !important;
|
||||
}
|
||||
}
|
||||
// 分隔线
|
||||
.w-e-bar-divider {
|
||||
background-color: var(--art-gray-300) !important;
|
||||
}
|
||||
|
||||
.w-e-select-list,
|
||||
.w-e-drop-panel,
|
||||
.w-e-bar-item-group .w-e-bar-item-menus-container,
|
||||
.w-e-text-container [data-slate-editor] pre > code {
|
||||
border: 1px solid var(--default-border) !important;
|
||||
}
|
||||
|
||||
// 下拉选择框
|
||||
.w-e-select-list {
|
||||
background-color: var(--default-box-color) !important;
|
||||
}
|
||||
|
||||
/* 下拉选择框 hover 样式调整 */
|
||||
.w-e-select-list ul li:hover,
|
||||
/* 工具栏 hover 按钮背景颜色 */
|
||||
.w-e-bar-item button:hover {
|
||||
background-color: #090909 !important;
|
||||
}
|
||||
|
||||
/* 代码块 */
|
||||
.w-e-text-container [data-slate-editor] pre > code {
|
||||
background-color: #25262b !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
/* 引用 */
|
||||
.w-e-text-container [data-slate-editor] blockquote {
|
||||
border-left: 4px solid var(--default-border-dashed) !important;
|
||||
background-color: var(--art-color);
|
||||
}
|
||||
|
||||
.editor-wrapper {
|
||||
.w-e-text-container [data-slate-editor] .table-container th:last-of-type {
|
||||
border-right: 1px solid var(--default-border-dashed) !important;
|
||||
}
|
||||
|
||||
.w-e-modal {
|
||||
background-color: var(--art-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
// 导入暗黑主题
|
||||
@use 'element-plus/theme-chalk/src/dark/css-vars.scss' as *;
|
||||
@@ -0,0 +1,34 @@
|
||||
// https://github.com/element-plus/element-plus/blob/dev/packages/theme-chalk/src/common/var.scss
|
||||
// 自定义Element 亮色主题
|
||||
|
||||
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
|
||||
$colors: (
|
||||
'white': #ffffff,
|
||||
'black': #000000,
|
||||
'success': (
|
||||
'base': #13deb9
|
||||
),
|
||||
'warning': (
|
||||
'base': #ffae1f
|
||||
),
|
||||
'danger': (
|
||||
'base': #ff4d4f
|
||||
),
|
||||
'error': (
|
||||
'base': #fa896b
|
||||
)
|
||||
),
|
||||
$button: (
|
||||
'hover-bg-color': var(--el-color-primary-light-9),
|
||||
'hover-border-color': var(--el-color-primary),
|
||||
'border-color': var(--el-color-primary),
|
||||
'text-color': var(--el-color-primary)
|
||||
),
|
||||
$messagebox: (
|
||||
'border-radius': '12px'
|
||||
),
|
||||
$popover: (
|
||||
'padding': '14px',
|
||||
'border-radius': '10px'
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,519 @@
|
||||
// 优化 Element Plus 组件库默认样式
|
||||
|
||||
:root {
|
||||
// 系统主色
|
||||
--main-color: var(--el-color-primary);
|
||||
--el-color-white: white !important;
|
||||
--el-color-black: white !important;
|
||||
// 输入框边框颜色
|
||||
// --el-border-color: #E4E4E7 !important; // DCDFE6
|
||||
// 按钮粗度
|
||||
--el-font-weight-primary: 400 !important;
|
||||
|
||||
--el-component-custom-height: 36px !important;
|
||||
|
||||
--el-component-size: var(--el-component-custom-height) !important;
|
||||
|
||||
// 边框、按钮圆角...
|
||||
--el-border-radius-base: calc(var(--custom-radius) / 3 + 2px) !important;
|
||||
|
||||
--el-border-radius-small: calc(var(--custom-radius) / 3 + 4px) !important;
|
||||
--el-messagebox-border-radius: calc(var(--custom-radius) / 3 + 4px) !important;
|
||||
--el-popover-border-radius: calc(var(--custom-radius) / 3 + 4px) !important;
|
||||
|
||||
.region .el-radio-button__original-radio:checked + .el-radio-button__inner {
|
||||
color: var(--theme-color);
|
||||
}
|
||||
}
|
||||
|
||||
// 优化 el-form-item 标签高度
|
||||
.el-form-item__label {
|
||||
height: var(--el-component-custom-height) !important;
|
||||
line-height: var(--el-component-custom-height) !important;
|
||||
}
|
||||
|
||||
// 日期选择器
|
||||
.el-date-range-picker {
|
||||
--el-datepicker-inrange-bg-color: var(--art-gray-200) !important;
|
||||
}
|
||||
|
||||
// el-card 背景色跟系统背景色保持一致
|
||||
html.dark .el-card {
|
||||
--el-card-bg-color: var(--default-box-color) !important;
|
||||
}
|
||||
|
||||
// 修改 el-pagination 大小
|
||||
.el-pagination--default {
|
||||
& {
|
||||
--el-pagination-button-width: 32px !important;
|
||||
--el-pagination-button-height: var(--el-pagination-button-width) !important;
|
||||
}
|
||||
|
||||
@media (max-width: 1180px) {
|
||||
& {
|
||||
--el-pagination-button-width: 28px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-select--default .el-select__wrapper {
|
||||
min-height: var(--el-pagination-button-width) !important;
|
||||
}
|
||||
|
||||
.el-pagination__jump .el-input {
|
||||
height: var(--el-pagination-button-width) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-pager li {
|
||||
padding: 0 10px !important;
|
||||
// border: 1px solid red !important;
|
||||
}
|
||||
|
||||
// 优化菜单折叠展开动画(提升动画流畅度)
|
||||
.el-menu.el-menu--inline {
|
||||
transition: max-height 0.26s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
||||
}
|
||||
|
||||
// 优化菜单 item hover 动画(提升鼠标跟手感)
|
||||
.el-sub-menu__title,
|
||||
.el-menu-item {
|
||||
transition: background-color 0s !important;
|
||||
}
|
||||
|
||||
// -------------------------------- 修改 el-size=default 组件默认高度 start --------------------------------
|
||||
// 修改 el-button 高度
|
||||
.el-button--default {
|
||||
height: var(--el-component-custom-height) !important;
|
||||
}
|
||||
|
||||
// circle 按钮宽度优化
|
||||
.el-button--default.is-circle {
|
||||
width: var(--el-component-custom-height) !important;
|
||||
}
|
||||
|
||||
// 修改 el-select 高度
|
||||
.el-select--default {
|
||||
.el-select__wrapper {
|
||||
min-height: var(--el-component-custom-height) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 修改 el-checkbox-button 高度
|
||||
.el-checkbox-button--default .el-checkbox-button__inner,
|
||||
// 修改 el-radio-button 高度
|
||||
.el-radio-button--default .el-radio-button__inner {
|
||||
padding: 10px 15px !important;
|
||||
}
|
||||
// -------------------------------- 修改 el-size=default 组件默认高度 end --------------------------------
|
||||
|
||||
.el-pagination.is-background .btn-next,
|
||||
.el-pagination.is-background .btn-prev,
|
||||
.el-pagination.is-background .el-pager li {
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.el-popover {
|
||||
min-width: 80px;
|
||||
border-radius: var(--el-border-radius-small) !important;
|
||||
}
|
||||
|
||||
.el-dialog {
|
||||
border-radius: 100px !important;
|
||||
border-radius: calc(var(--custom-radius) / 1.2 + 2px) !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.el-dialog__header {
|
||||
.el-dialog__title {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
padding: 25px 0 !important;
|
||||
position: relative; // 为了兼容 el-pagination 样式,需要设置 relative,不然会影响 el-pagination 的样式,比如 el-pagination__jump--small 会被影响,导致 el-pagination__jump--small 按钮无法点击,详见 URL_ADDRESS.com/element-plus/element-plus/issues/5684#issuecomment-1176299275;
|
||||
}
|
||||
|
||||
.el-dialog.el-dialog-border {
|
||||
.el-dialog__body {
|
||||
// 上边框
|
||||
&::before,
|
||||
// 下边框
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -16px;
|
||||
width: calc(100% + 32px);
|
||||
height: 1px;
|
||||
background-color: var(--art-gray-300);
|
||||
}
|
||||
|
||||
&::before {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&::after {
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// el-message 样式优化
|
||||
.el-message {
|
||||
background-color: var(--default-box-color) !important;
|
||||
border: 0 !important;
|
||||
box-shadow:
|
||||
0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
||||
0 3px 6px -4px rgba(0, 0, 0, 0.12),
|
||||
0 9px 28px 8px rgba(0, 0, 0, 0.05) !important;
|
||||
|
||||
p {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
// 修改 el-dropdown 样式
|
||||
.el-dropdown-menu {
|
||||
padding: 6px !important;
|
||||
border-radius: 10px !important;
|
||||
border: none !important;
|
||||
|
||||
.el-dropdown-menu__item {
|
||||
padding: 6px 16px !important;
|
||||
border-radius: 6px !important;
|
||||
|
||||
&:hover:not(.is-disabled) {
|
||||
color: var(--art-gray-900) !important;
|
||||
background-color: var(--art-el-active-color) !important;
|
||||
}
|
||||
|
||||
&:focus:not(.is-disabled) {
|
||||
color: var(--art-gray-900) !important;
|
||||
background-color: var(--art-gray-200) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 隐藏 select、dropdown 的三角
|
||||
.el-select__popper,
|
||||
.el-dropdown__popper {
|
||||
margin-top: -6px !important;
|
||||
|
||||
.el-popper__arrow {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.el-dropdown-selfdefine:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
// 处理移动端组件兼容性
|
||||
@media screen and (max-width: 640px) {
|
||||
.el-message-box,
|
||||
.el-dialog {
|
||||
width: calc(100% - 24px) !important;
|
||||
}
|
||||
|
||||
.el-date-picker.has-sidebar.has-time {
|
||||
width: calc(100% - 24px);
|
||||
left: 12px !important;
|
||||
}
|
||||
|
||||
.el-picker-panel *[slot='sidebar'],
|
||||
.el-picker-panel__sidebar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-picker-panel *[slot='sidebar'] + .el-picker-panel__body,
|
||||
.el-picker-panel__sidebar + .el-picker-panel__body {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 修改el-button样式
|
||||
.el-button {
|
||||
&.el-button--text {
|
||||
background-color: transparent !important;
|
||||
padding: 0 !important;
|
||||
|
||||
span {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 修改el-tag样式
|
||||
.el-tag {
|
||||
font-weight: 500;
|
||||
transition: all 0s !important;
|
||||
|
||||
&.el-tag--default {
|
||||
height: 26px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-checkbox-group {
|
||||
&.el-table-filter__checkbox-group label.el-checkbox {
|
||||
height: 17px !important;
|
||||
|
||||
.el-checkbox__label {
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-radio--default {
|
||||
// 优化单选按钮大小
|
||||
.el-radio__input {
|
||||
.el-radio__inner {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
&::after {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-checkbox {
|
||||
.el-checkbox__inner {
|
||||
border-radius: 2px !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 优化复选框样式
|
||||
.el-checkbox--default {
|
||||
.el-checkbox__inner {
|
||||
width: 16px !important;
|
||||
height: 16px !important;
|
||||
border-radius: 4px !important;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
height: 4px !important;
|
||||
top: 5px !important;
|
||||
background-color: #fff !important;
|
||||
transform: scale(0.6) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.is-checked {
|
||||
.el-checkbox__inner {
|
||||
&::after {
|
||||
width: 3px;
|
||||
height: 8px;
|
||||
margin: auto;
|
||||
border: 2px solid var(--el-checkbox-checked-icon-color);
|
||||
border-left: 0;
|
||||
border-top: 0;
|
||||
transform: translate(-45%, -60%) rotate(45deg) scale(0.86) !important;
|
||||
transform-origin: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-notification .el-notification__icon {
|
||||
font-size: 22px !important;
|
||||
}
|
||||
|
||||
// 修改 el-message-box 样式
|
||||
.el-message-box__headerbtn .el-message-box__close,
|
||||
.el-dialog__headerbtn .el-dialog__close {
|
||||
top: 7px;
|
||||
right: 7px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 5px;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--art-hover-color) !important;
|
||||
color: var(--art-gray-900) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-message-box {
|
||||
padding: 25px 20px !important;
|
||||
}
|
||||
|
||||
.el-message-box__title {
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
.el-table__column-filter-trigger i {
|
||||
color: var(--theme-color) !important;
|
||||
margin: -3px 0 0 2px;
|
||||
}
|
||||
|
||||
// 去除 el-dropdown 鼠标放上去出现的边框
|
||||
.el-tooltip__trigger:focus-visible {
|
||||
outline: unset;
|
||||
}
|
||||
|
||||
// ipad 表单右侧按钮优化
|
||||
@media screen and (max-width: 1180px) {
|
||||
.el-table-fixed-column--right {
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.login-out-dialog {
|
||||
padding: 30px 20px !important;
|
||||
border-radius: 10px !important;
|
||||
}
|
||||
|
||||
// 修改 dialog 动画
|
||||
.dialog-fade-enter-active {
|
||||
.el-dialog:not(.is-draggable) {
|
||||
animation: dialog-open 0.3s cubic-bezier(0.32, 0.14, 0.15, 0.86);
|
||||
|
||||
// 修复 el-dialog 动画后宽度不自适应问题
|
||||
.el-select__selected-item {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-fade-leave-active {
|
||||
animation: fade-out 0.2s linear;
|
||||
|
||||
.el-dialog:not(.is-draggable) {
|
||||
animation: dialog-close 0.5s;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dialog-open {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.2);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dialog-close {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: scale(0.2);
|
||||
}
|
||||
}
|
||||
|
||||
// 遮罩层动画
|
||||
@keyframes fade-out {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 修改 el-select 样式
|
||||
.el-select__popper:not(.el-tree-select__popper) {
|
||||
.el-select-dropdown__list {
|
||||
padding: 5px !important;
|
||||
|
||||
.el-select-dropdown__item {
|
||||
height: 34px !important;
|
||||
line-height: 34px !important;
|
||||
border-radius: 6px !important;
|
||||
|
||||
&.is-selected {
|
||||
color: var(--art-gray-900) !important;
|
||||
font-weight: 400 !important;
|
||||
background-color: var(--art-el-active-color) !important;
|
||||
margin-bottom: 4px !important;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--art-hover-color) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-select-dropdown__item:hover ~ .is-selected,
|
||||
.el-select-dropdown__item.is-selected:has(~ .el-select-dropdown__item:hover) {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 修改 el-tree-select 样式
|
||||
.el-tree-select__popper {
|
||||
.el-select-dropdown__list {
|
||||
padding: 5px !important;
|
||||
|
||||
.el-tree-node {
|
||||
.el-tree-node__content {
|
||||
height: 36px !important;
|
||||
border-radius: 6px !important;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--art-gray-200) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 实现水波纹在文字下面效果
|
||||
.el-button > span {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
// 优化颜色选择器圆角
|
||||
.el-color-picker__color {
|
||||
border-radius: 2px !important;
|
||||
}
|
||||
|
||||
// 优化日期时间选择器底部圆角
|
||||
.el-picker-panel {
|
||||
.el-picker-panel__footer {
|
||||
border-radius: 0 0 var(--el-border-radius-base) var(--el-border-radius-base);
|
||||
}
|
||||
}
|
||||
|
||||
// 优化树型菜单样式
|
||||
.el-tree-node__content {
|
||||
border-radius: 4px;
|
||||
margin-bottom: 4px;
|
||||
padding: 1px 0;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--art-hover-color) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.dark {
|
||||
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
|
||||
background-color: var(--art-gray-300) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 隐藏折叠菜单弹窗 hover 出现的边框
|
||||
.menu-left-popper:focus-within,
|
||||
.horizontal-menu-popper:focus-within {
|
||||
box-shadow: none !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
// 数字输入组件右侧按钮高度跟随自定义组件高度
|
||||
.el-input-number--default.is-controls-right {
|
||||
.el-input-number__decrease,
|
||||
.el-input-number__increase {
|
||||
height: calc((var(--el-component-size) / 2)) !important;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Executable
+157
@@ -0,0 +1,157 @@
|
||||
// sass 混合宏(函数)
|
||||
|
||||
/**
|
||||
* 溢出省略号
|
||||
* @param {Number} 行数
|
||||
*/
|
||||
@mixin ellipsis($rowCount: 1) {
|
||||
@if $rowCount <=1 {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
} @else {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: $rowCount;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 控制用户能否选中文本
|
||||
* @param {String} 类型
|
||||
*/
|
||||
@mixin userSelect($value: none) {
|
||||
user-select: $value;
|
||||
-moz-user-select: $value;
|
||||
-ms-user-select: $value;
|
||||
-webkit-user-select: $value;
|
||||
}
|
||||
|
||||
// 绝对定位居中
|
||||
@mixin absoluteCenter() {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* css3动画
|
||||
*
|
||||
*/
|
||||
@mixin animation(
|
||||
$from: (
|
||||
width: 0px
|
||||
),
|
||||
$to: (
|
||||
width: 100px
|
||||
),
|
||||
$name: mymove,
|
||||
$animate: mymove 2s 1 linear infinite
|
||||
) {
|
||||
-webkit-animation: $animate;
|
||||
-o-animation: $animate;
|
||||
animation: $animate;
|
||||
|
||||
@keyframes #{$name} {
|
||||
from {
|
||||
@each $key, $value in $from {
|
||||
#{$key}: #{$value};
|
||||
}
|
||||
}
|
||||
|
||||
to {
|
||||
@each $key, $value in $to {
|
||||
#{$key}: #{$value};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes #{$name} {
|
||||
from {
|
||||
@each $key, $value in $from {
|
||||
$key: $value;
|
||||
}
|
||||
}
|
||||
|
||||
to {
|
||||
@each $key, $value in $to {
|
||||
$key: $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 圆形盒子
|
||||
@mixin circle($size: 11px, $bg: #fff) {
|
||||
border-radius: 50%;
|
||||
width: $size;
|
||||
height: $size;
|
||||
line-height: $size;
|
||||
text-align: center;
|
||||
background: $bg;
|
||||
}
|
||||
|
||||
// placeholder
|
||||
@mixin placeholder($color: #bbb) {
|
||||
// Firefox
|
||||
&::-moz-placeholder {
|
||||
color: $color;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
// Internet Explorer 10+
|
||||
&:-ms-input-placeholder {
|
||||
color: $color;
|
||||
}
|
||||
|
||||
// Safari and Chrome
|
||||
&::-webkit-input-placeholder {
|
||||
color: $color;
|
||||
}
|
||||
|
||||
&:placeholder-shown {
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
//背景透明,文字不透明。兼容IE8
|
||||
@mixin betterTransparentize($color, $alpha) {
|
||||
$c: rgba($color, $alpha);
|
||||
$ie_c: ie_hex_str($c);
|
||||
background: rgba($color, 1);
|
||||
background: $c;
|
||||
background: transparent \9;
|
||||
zoom: 1;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#{$ie_c}, endColorstr=#{$ie_c});
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.gradient(startColorstr=#{$ie_c}, endColorstr=#{$ie_c})';
|
||||
}
|
||||
|
||||
//添加浏览器前缀
|
||||
@mixin browserPrefix($propertyName, $value) {
|
||||
@each $prefix in -webkit-, -moz-, -ms-, -o-, '' {
|
||||
#{$prefix}#{$propertyName}: $value;
|
||||
}
|
||||
}
|
||||
|
||||
// 边框
|
||||
@mixin border($color: red) {
|
||||
border: 1px solid $color;
|
||||
}
|
||||
|
||||
// 背景滤镜
|
||||
@mixin backdropBlur() {
|
||||
--tw-backdrop-blur: blur(30px);
|
||||
-webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
|
||||
var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate)
|
||||
var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
|
||||
var(--tw-backdrop-sepia);
|
||||
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast)
|
||||
var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert)
|
||||
var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
|
||||
}
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/*滚动条*/
|
||||
/*滚动条整体部分,必须要设置*/
|
||||
::-webkit-scrollbar {
|
||||
width: 8px !important;
|
||||
height: 0 !important;
|
||||
}
|
||||
|
||||
/*滚动条的轨道*/
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: var(--art-gray-200);
|
||||
}
|
||||
|
||||
/*滚动条的滑块按钮*/
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 5px;
|
||||
background-color: #cccccc !important;
|
||||
transition: all 0.2s;
|
||||
-webkit-transition: all 0.2s;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #b0abab !important;
|
||||
}
|
||||
|
||||
/*滚动条的上下两端的按钮*/
|
||||
::-webkit-scrollbar-button {
|
||||
height: 0px;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.dark {
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: var(--default-bg-color);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: var(--art-gray-300) !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
@use 'sass:map';
|
||||
|
||||
// === 变量区域 ===
|
||||
$transition: (
|
||||
// 动画持续时间
|
||||
duration: 0.25s,
|
||||
// 滑动动画的移动距离
|
||||
distance: 15px,
|
||||
// 默认缓动函数
|
||||
easing: cubic-bezier(0.25, 0.1, 0.25, 1),
|
||||
// 淡入淡出专用的缓动函数
|
||||
fade-easing: cubic-bezier(0.4, 0, 0.6, 1)
|
||||
);
|
||||
|
||||
// 抽取配置值函数,提高可复用性
|
||||
@function transition-config($key) {
|
||||
@return map.get($transition, $key);
|
||||
}
|
||||
|
||||
// 变量简写
|
||||
$duration: transition-config('duration');
|
||||
$distance: transition-config('distance');
|
||||
$easing: transition-config('easing');
|
||||
$fade-easing: transition-config('fade-easing');
|
||||
|
||||
// === 动画类 ===
|
||||
|
||||
// 淡入淡出动画
|
||||
.fade {
|
||||
&-enter-active,
|
||||
&-leave-active {
|
||||
transition: opacity $duration $fade-easing;
|
||||
will-change: opacity;
|
||||
}
|
||||
|
||||
&-enter-from,
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&-enter-to,
|
||||
&-leave-from {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 滑动动画通用样式
|
||||
@mixin slide-transition($direction) {
|
||||
$distance-x: 0;
|
||||
$distance-y: 0;
|
||||
|
||||
@if $direction == 'left' {
|
||||
$distance-x: -$distance;
|
||||
} @else if $direction == 'right' {
|
||||
$distance-x: $distance;
|
||||
} @else if $direction == 'top' {
|
||||
$distance-y: -$distance;
|
||||
} @else if $direction == 'bottom' {
|
||||
$distance-y: $distance;
|
||||
}
|
||||
|
||||
&-enter-active {
|
||||
transition:
|
||||
opacity $duration $easing,
|
||||
transform $duration $easing;
|
||||
will-change: opacity, transform;
|
||||
}
|
||||
|
||||
&-leave-active {
|
||||
transition:
|
||||
opacity calc($duration * 0.7) $easing,
|
||||
transform calc($duration * 0.7) $easing;
|
||||
will-change: opacity, transform;
|
||||
}
|
||||
|
||||
&-enter-from {
|
||||
opacity: 0;
|
||||
transform: translate3d($distance-x, $distance-y, 0);
|
||||
}
|
||||
|
||||
&-enter-to {
|
||||
opacity: 1;
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
&-leave-to {
|
||||
opacity: 0;
|
||||
transform: translate3d(-$distance-x, -$distance-y, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// 滑动动画方向类
|
||||
.slide-left {
|
||||
@include slide-transition('left');
|
||||
}
|
||||
.slide-right {
|
||||
@include slide-transition('right');
|
||||
}
|
||||
.slide-top {
|
||||
@include slide-transition('top');
|
||||
}
|
||||
.slide-bottom {
|
||||
@include slide-transition('bottom');
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
@import 'tailwindcss';
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
/* ==================== Light Mode Variables ==================== */
|
||||
:root {
|
||||
/* Base Colors */
|
||||
--art-color: #ffffff;
|
||||
--theme-color: var(--main-color);
|
||||
|
||||
/* Theme Colors - OKLCH Format */
|
||||
--art-primary: oklch(0.7 0.23 260);
|
||||
--art-secondary: oklch(0.72 0.19 231.6);
|
||||
--art-error: oklch(0.73 0.15 25.3);
|
||||
--art-info: oklch(0.58 0.03 254.1);
|
||||
--art-success: oklch(0.78 0.17 166.1);
|
||||
--art-warning: oklch(0.78 0.14 75.5);
|
||||
--art-danger: oklch(0.68 0.22 25.3);
|
||||
|
||||
/* Gray Scale - Light Mode */
|
||||
--art-gray-100: #f9fafb;
|
||||
--art-gray-200: #f2f4f5;
|
||||
--art-gray-300: #e6eaeb;
|
||||
--art-gray-400: #dbdfe1;
|
||||
--art-gray-500: #949eb7;
|
||||
--art-gray-600: #7987a1;
|
||||
--art-gray-700: #4d5875;
|
||||
--art-gray-800: #383853;
|
||||
--art-gray-900: #323251;
|
||||
|
||||
/* Border Colors */
|
||||
--art-card-border: rgba(0, 0, 0, 0.08);
|
||||
|
||||
--default-border: #e2e8ee;
|
||||
--default-border-dashed: #dbdfe9;
|
||||
|
||||
/* Background Colors */
|
||||
--default-bg-color: #fafbfc;
|
||||
--default-box-color: #ffffff;
|
||||
|
||||
/* Hover Color */
|
||||
--art-hover-color: #edeff0;
|
||||
|
||||
/* Active Color */
|
||||
--art-active-color: #f2f4f5;
|
||||
|
||||
/* Element Component Active Color */
|
||||
--art-el-active-color: #f2f4f5;
|
||||
}
|
||||
|
||||
/* ==================== Dark Mode Variables ==================== */
|
||||
.dark {
|
||||
/* Base Colors */
|
||||
--art-color: #000000;
|
||||
|
||||
/* Gray Scale - Dark Mode */
|
||||
--art-gray-100: #110f0f;
|
||||
--art-gray-200: #17171c;
|
||||
--art-gray-300: #393946;
|
||||
--art-gray-400: #505062;
|
||||
--art-gray-500: #73738c;
|
||||
--art-gray-600: #8f8fa3;
|
||||
--art-gray-700: #ababba;
|
||||
--art-gray-800: #c7c7d1;
|
||||
--art-gray-900: #e3e3e8;
|
||||
|
||||
/* Border Colors */
|
||||
--art-card-border: rgba(255, 255, 255, 0.08);
|
||||
|
||||
--default-border: rgba(255, 255, 255, 0.1);
|
||||
--default-border-dashed: #363843;
|
||||
|
||||
/* Background Colors */
|
||||
--default-bg-color: #070707;
|
||||
--default-box-color: #161618;
|
||||
|
||||
/* Hover Color */
|
||||
--art-hover-color: #252530;
|
||||
|
||||
/* Active Color */
|
||||
--art-active-color: #202226;
|
||||
|
||||
/* Element Component Active Color */
|
||||
--art-el-active-color: #2e2e38;
|
||||
}
|
||||
|
||||
/* ==================== Tailwind Theme Configuration ==================== */
|
||||
@theme {
|
||||
/* Box Color (Light: white / Dark: black) */
|
||||
--color-box: var(--default-box-color);
|
||||
|
||||
/* System Theme Color */
|
||||
--color-theme: var(--theme-color);
|
||||
|
||||
/* Hover Color */
|
||||
--color-hover-color: var(--art-hover-color);
|
||||
|
||||
/* Active Color */
|
||||
--color-active-color: var(--art-active-color);
|
||||
|
||||
/* Active Color */
|
||||
--color-el-active-color: var(--art-active-color);
|
||||
|
||||
/* ElementPlus Theme Colors */
|
||||
--color-primary: var(--art-primary);
|
||||
--color-secondary: var(--art-secondary);
|
||||
--color-error: var(--art-error);
|
||||
--color-info: var(--art-info);
|
||||
--color-success: var(--art-success);
|
||||
--color-warning: var(--art-warning);
|
||||
--color-danger: var(--art-danger);
|
||||
|
||||
/* Gray Scale Colors (Auto-adapts to dark mode) */
|
||||
--color-g-100: var(--art-gray-100);
|
||||
--color-g-200: var(--art-gray-200);
|
||||
--color-g-300: var(--art-gray-300);
|
||||
--color-g-400: var(--art-gray-400);
|
||||
--color-g-500: var(--art-gray-500);
|
||||
--color-g-600: var(--art-gray-600);
|
||||
--color-g-700: var(--art-gray-700);
|
||||
--color-g-800: var(--art-gray-800);
|
||||
--color-g-900: var(--art-gray-900);
|
||||
}
|
||||
|
||||
/* ==================== Custom Border Radius Utilities ==================== */
|
||||
@utility rounded-custom-xs {
|
||||
border-radius: calc(var(--custom-radius) / 2);
|
||||
}
|
||||
|
||||
@utility rounded-custom-sm {
|
||||
border-radius: calc(var(--custom-radius) / 2 + 2px);
|
||||
}
|
||||
|
||||
/* ==================== Custom Utility Classes ==================== */
|
||||
@layer utilities {
|
||||
/* Flexbox Layout Utilities */
|
||||
.flex-c {
|
||||
@apply flex items-center;
|
||||
}
|
||||
|
||||
.flex-b {
|
||||
@apply flex justify-between;
|
||||
}
|
||||
|
||||
.flex-cc {
|
||||
@apply flex items-center justify-center;
|
||||
}
|
||||
|
||||
.flex-cb {
|
||||
@apply flex items-center justify-between;
|
||||
}
|
||||
|
||||
/* Transition Utilities */
|
||||
.tad-200 {
|
||||
@apply transition-all duration-200;
|
||||
}
|
||||
|
||||
.tad-300 {
|
||||
@apply transition-all duration-300;
|
||||
}
|
||||
|
||||
/* Border Utilities */
|
||||
.border-full-d {
|
||||
@apply border border-[var(--default-border)];
|
||||
}
|
||||
|
||||
.border-b-d {
|
||||
@apply border-b border-[var(--default-border)];
|
||||
}
|
||||
|
||||
.border-t-d {
|
||||
@apply border-t border-[var(--default-border)];
|
||||
}
|
||||
|
||||
.border-l-d {
|
||||
@apply border-l border-[var(--default-border)];
|
||||
}
|
||||
|
||||
.border-r-d {
|
||||
@apply border-r border-[var(--default-border)];
|
||||
}
|
||||
|
||||
/* Cursor Utilities */
|
||||
.c-p {
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================== Custom Component Classes ==================== */
|
||||
@layer components {
|
||||
/* Art Card Header Component */
|
||||
.art-card-header {
|
||||
@apply flex justify-between pr-6 pb-1;
|
||||
|
||||
.title {
|
||||
h4 {
|
||||
@apply text-lg font-medium text-g-900;
|
||||
}
|
||||
|
||||
p {
|
||||
@apply mt-1 text-sm text-g-600;
|
||||
|
||||
span {
|
||||
@apply ml-2 font-medium;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// 定义基础变量
|
||||
$bg-animation-color-light: #000;
|
||||
$bg-animation-color-dark: #fff;
|
||||
$bg-animation-duration: 0.5s;
|
||||
|
||||
html {
|
||||
--bg-animation-color: $bg-animation-color-light;
|
||||
|
||||
&.dark {
|
||||
--bg-animation-color: $bg-animation-color-dark;
|
||||
}
|
||||
|
||||
// View transition styles
|
||||
&::view-transition-old(*) {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
&::view-transition-new(*) {
|
||||
animation: clip $bg-animation-duration ease-in both;
|
||||
}
|
||||
|
||||
&::view-transition-old(root) {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&::view-transition-new(root) {
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
&.dark {
|
||||
&::view-transition-old(*) {
|
||||
animation: clip $bg-animation-duration ease-in reverse both;
|
||||
}
|
||||
|
||||
&::view-transition-new(*) {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
&::view-transition-old(root) {
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
&::view-transition-new(root) {
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 定义动画
|
||||
@keyframes clip {
|
||||
from {
|
||||
clip-path: circle(0% at var(--x) var(--y));
|
||||
}
|
||||
|
||||
to {
|
||||
clip-path: circle(var(--r) at var(--x) var(--y));
|
||||
}
|
||||
}
|
||||
|
||||
// body 相关样式
|
||||
body {
|
||||
background-color: var(--bg-animation-color);
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// 主题切换过渡优化,优化除视觉上的不适感
|
||||
.theme-change {
|
||||
* {
|
||||
transition: 0s !important;
|
||||
}
|
||||
|
||||
.el-switch__core,
|
||||
.el-switch__action {
|
||||
transition: all 0.3s !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
|
||||
color: #a6accd;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-section,
|
||||
.hljs-selector-class,
|
||||
.hljs-template-variable,
|
||||
.hljs-deletion {
|
||||
color: #aed07e !important;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #6f747d;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-formula {
|
||||
color: #c792ea;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-tag,
|
||||
.hljs-deletion,
|
||||
.hljs-subst {
|
||||
color: #c86068;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #56b6c2;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-regexp,
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-meta-string {
|
||||
color: #abb2bf;
|
||||
}
|
||||
|
||||
.hljs-attribute {
|
||||
color: #c792ea;
|
||||
}
|
||||
|
||||
.hljs-function {
|
||||
color: #c792ea;
|
||||
}
|
||||
|
||||
.hljs-type {
|
||||
color: #f07178;
|
||||
}
|
||||
|
||||
.hljs-title {
|
||||
color: #82aaff !important;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-class {
|
||||
color: #82aaff;
|
||||
}
|
||||
|
||||
// 括号
|
||||
.hljs-params {
|
||||
color: #a6accd;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-number {
|
||||
color: #de7e61;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link,
|
||||
.hljs-meta,
|
||||
.hljs-selector-id {
|
||||
color: #61aeee;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
@@ -1,329 +0,0 @@
|
||||
/* 暗黑模式通过 CSS 自定义变量,官方链接:https://element-plus.org/zh-CN/guide/dark-mode.html#%E9%80%9A%E8%BF%87-css */
|
||||
/**
|
||||
* Element Plus 主题最小回退变量(合并版)
|
||||
*
|
||||
* === 配色层级(同一主色:哪里深、哪里浅)===
|
||||
* L0 页面画布:--el-bg-color / --el-bg-color-page(大面积)
|
||||
* L1 内容区块:--el-bg-color-overlay(卡片/表格等)
|
||||
* L2 卡片/表格容器面:--el-bg-color-overlay(抬升中性面)
|
||||
* L3 表头/侧栏条:使用 fill 层级(不再做混色)
|
||||
* L4 浮层(下拉/弹窗):面板底 = overlay,不用整板灌主色;强调在选项/按钮/focus
|
||||
* L5 再嵌套浅填充:--el-fill-color-light(hover 槽、禁用底等)
|
||||
* 标签栏 TagsView:使用 Element Plus fill/bg token
|
||||
* 主色强度:点线控件(按钮、focus、选中字)用实色 primary;面状 hover/范围/斑马用 fill 层级
|
||||
*
|
||||
* === 本文区块 ===
|
||||
* :root 亮色 / html.dark 暗色 / 运行时 theme.ts 覆盖
|
||||
* 弹层、浮层 Popper、Select 选项、DatePicker 范围、级联、表格见对应注释
|
||||
* 其余排期:Message、图表取 CSS 变量、登录全屏页;Tabs border-card 顶条 / Steps simple / Progress 轨道见下文
|
||||
*/
|
||||
|
||||
:root,
|
||||
html :root {
|
||||
/* 基础中性色(画布/浅分割线轻混主色,随 --el-color-primary 略偏主题,保持淡淡层次) */
|
||||
--el-bg-color: color-mix(in srgb, var(--el-color-primary, #4080ff) 5%, #f8fafc 95%);
|
||||
--el-bg-color-page: var(--el-bg-color);
|
||||
--el-bg-color-overlay: #ffffff;
|
||||
--el-fill-color: #e2e8f0;
|
||||
--el-fill-color-light: color-mix(in srgb, var(--el-color-primary, #4080ff) 3%, #f1f5f9 93%);
|
||||
/* 亮色:分割线偏淡(主色比例略降、灰底偏浅) */
|
||||
--el-border-color: color-mix(in srgb, var(--el-color-primary, #4080ff) 6%, #e2e8f0 94%);
|
||||
--el-border-color-light: color-mix(in srgb, var(--el-color-primary, #4080ff) 7.5%, #eef2f7 92.5%);
|
||||
--el-border-color-lighter: color-mix(in srgb, var(--el-color-primary, #4080ff) 15%, #f1f5f9 92%);
|
||||
--el-border-color-extra-light: color-mix(
|
||||
in srgb,
|
||||
var(--el-color-primary, #4080ff) 5.5%,
|
||||
#f4f6f8 94.5%
|
||||
);
|
||||
--el-text-color-primary: #0f172a;
|
||||
--el-text-color-regular: #475569;
|
||||
--el-text-color-secondary: #64748b;
|
||||
--el-text-color-placeholder: #94a3b8;
|
||||
|
||||
/* 阴影/遮罩 */
|
||||
--el-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
--el-box-shadow-light: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
--el-overlay-color: rgba(15, 23, 42, 0.5);
|
||||
--el-overlay-color-light: rgba(15, 23, 42, 0.3);
|
||||
--el-overlay-color-lighter: rgba(15, 23, 42, 0.15);
|
||||
|
||||
/* 菜单 hover 兼容 */
|
||||
--el-menu-hover-bg-color: color-mix(in srgb, var(--el-color-primary, #4080ff) 8%, #f3f6fb 92%);
|
||||
|
||||
/* 全局原生滚动条:轨道浅底 + 滑块混主色(随 theme.ts / --el-color-primary 变) */
|
||||
--app-scrollbar-track: color-mix(in srgb, var(--el-color-primary, #4080ff) 5%, #eef2f7 95%);
|
||||
--app-scrollbar-thumb: color-mix(in srgb, var(--el-color-primary, #4080ff) 35%, #bcc8d4 65%);
|
||||
--app-scrollbar-thumb-hover: color-mix(
|
||||
in srgb,
|
||||
var(--el-color-primary, #4080ff) 48%,
|
||||
#94a3b8 52%
|
||||
);
|
||||
|
||||
/*
|
||||
* 表格:表头 / 斑马 / 行悬停 — 同一主色,深浅分层(亮底;整体偏浅、主色占比低)
|
||||
* 表头略深 → 悬停中等 → 斑马最浅
|
||||
*/
|
||||
--el-table-theme-header-bg: color-mix(in srgb, var(--el-color-primary, #4080ff) 8%, #f4f6f9 92%);
|
||||
--el-table-theme-hover-bg: color-mix(
|
||||
in srgb,
|
||||
var(--el-color-primary, #4080ff) 5.5%,
|
||||
var(--el-bg-color-overlay) 94.5%
|
||||
);
|
||||
--el-table-theme-stripe-bg: color-mix(
|
||||
in srgb,
|
||||
var(--el-color-primary, #4080ff) 4%,
|
||||
var(--el-bg-color-overlay) 97%
|
||||
);
|
||||
/*
|
||||
* 表格线:浅灰为主、主色极淡,避免格线抢眼(接近分割线「若有若无」)
|
||||
*/
|
||||
--el-table-theme-border-color: color-mix(
|
||||
in srgb,
|
||||
var(--el-color-primary, #4080ff) 15.5%,
|
||||
#eef2f7 95.5%
|
||||
);
|
||||
|
||||
/* 画布/分割线交给 Element Plus:不再维护 layout-* 混色变量 */
|
||||
|
||||
/* Select / TreeSelect 选项行(EP 默认 hover=fill-light、选中无底,与主题脱节) */
|
||||
--el-select-option-hover-bg: var(--el-fill-color-light);
|
||||
--el-select-option-selected-bg: var(--el-color-primary-light-9);
|
||||
|
||||
/* DatePicker 区间内底(EP 默认 inrange≈极浅灰,与主题脱节) */
|
||||
--el-datepicker-range-bg: var(--el-color-primary-light-9);
|
||||
--el-datepicker-range-hover-bg: var(--el-color-primary-light-8);
|
||||
|
||||
/*
|
||||
* 弹层
|
||||
* - 遮罩:--el-overlay-color
|
||||
* - 面板底:纯中性 overlay(不要混主色);主题色交给内部 primary 按钮、表单 focus、链接等
|
||||
* - Drawer 继承 --el-dialog-bg-color;Dialog 见下方 html .el-dialog(压过 EP 的 var(--el-bg-color))
|
||||
*/
|
||||
--el-dialog-bg-color: var(--el-bg-color-overlay);
|
||||
--el-popover-bg-color: var(--el-dialog-bg-color);
|
||||
--el-popup-modal-bg-color: var(--el-overlay-color);
|
||||
--el-popup-modal-opacity: 1;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
/*
|
||||
* 布局分区(仅暗色):侧栏主色略高 → 顶栏次之 → 主内容最淡(大面积阅读区)→ 卡片 overlay 略亮
|
||||
*/
|
||||
--layout-nav-bg: color-mix(in srgb, var(--el-color-primary, #4080ff) 6.5%, #101828 93.5%);
|
||||
--layout-header-bg: color-mix(in srgb, var(--el-color-primary, #4080ff) 5%, #121a2a 95%);
|
||||
--layout-content-bg: color-mix(in srgb, var(--el-color-primary, #4080ff) 4%, #0f172a 96%);
|
||||
/* Logo 区与侧栏同一底(左侧布局下与 .layout__sidebar / --menu-background 一致,避免色差条) */
|
||||
--layout-sidebar-logo-bg: var(--layout-nav-bg);
|
||||
/* 卡片/表格面板:比主内容略「抬」一点 */
|
||||
--el-bg-color-overlay: color-mix(in srgb, var(--el-color-primary, #4080ff) 6%, #1e293b 94%);
|
||||
|
||||
/* 基础中性色(画布 = 主内容区) */
|
||||
--el-bg-color: var(--layout-content-bg);
|
||||
--el-bg-color-page: var(--layout-content-bg);
|
||||
--el-fill-color: #1e293b;
|
||||
--el-fill-color-light: color-mix(in srgb, var(--el-color-primary, #4080ff) 8%, #334155 92%);
|
||||
/* 暗色:缝隙/分割线略深一层,区划更清晰 */
|
||||
--el-border-color: color-mix(in srgb, var(--el-color-primary, #4080ff) 14%, #334155 86%);
|
||||
--el-border-color-light: color-mix(in srgb, var(--el-color-primary, #4080ff) 12%, #475569 88%);
|
||||
--el-border-color-lighter: color-mix(in srgb, var(--el-color-primary, #4080ff) 13%, #3d4f69 87%);
|
||||
--el-border-color-extra-light: color-mix(
|
||||
in srgb,
|
||||
var(--el-color-primary, #4080ff) 11%,
|
||||
#334155 89%
|
||||
);
|
||||
--el-text-color-primary: #f8fafc;
|
||||
--el-text-color-regular: #e2e8f0;
|
||||
--el-text-color-secondary: #94a3b8;
|
||||
--el-text-color-placeholder: #64748b;
|
||||
|
||||
/* 阴影/遮罩 */
|
||||
--el-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.4), 0 1px 2px 0 rgba(0, 0, 0, 0.24);
|
||||
--el-box-shadow-light: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
|
||||
--el-overlay-color: rgba(0, 0, 0, 0.7);
|
||||
--el-overlay-color-light: rgba(0, 0, 0, 0.5);
|
||||
--el-overlay-color-lighter: rgba(0, 0, 0, 0.3);
|
||||
|
||||
/*
|
||||
* 菜单 hover / 激活:真正颜色在 --_menu-*,再赋给 --el-menu-hover-bg-color。
|
||||
* EP 在 el-menu 根上内联 --el-menu-hover-bg-color = TinyColor(bg).shade(20),会盖掉仅在 html 上的定义;
|
||||
* 用下面 html.dark .el-menu { ... !important } 把同一套色压回组件根,子项即可用 EP 默认 hover。
|
||||
*/
|
||||
--_menu-hover-bg: color-mix(
|
||||
in srgb,
|
||||
var(--el-color-primary, #4080ff) 14%,
|
||||
var(--layout-nav-bg) 86%
|
||||
);
|
||||
--_menu-active-bg: color-mix(
|
||||
in srgb,
|
||||
var(--el-color-primary, #4080ff) 21%,
|
||||
var(--layout-nav-bg) 79%
|
||||
);
|
||||
--el-menu-hover-bg-color: var(--_menu-hover-bg);
|
||||
--el-menu-active-bg-color: var(--_menu-active-bg);
|
||||
|
||||
/* 暗色全局滚动条:与主内容区协调,滑块略柔 */
|
||||
--app-scrollbar-track: color-mix(in srgb, var(--el-color-primary, #4080ff) 7.5%, #0f172a 92.5%);
|
||||
--app-scrollbar-thumb: color-mix(in srgb, var(--el-color-primary, #4080ff) 33%, #475569 67%);
|
||||
--app-scrollbar-thumb-hover: color-mix(
|
||||
in srgb,
|
||||
var(--el-color-primary, #4080ff) 46%,
|
||||
#64748b 54%
|
||||
);
|
||||
|
||||
/*
|
||||
* 表格:暗底整体偏浅一档,主色占比降低,更接近面板底 --el-bg-color-overlay
|
||||
*/
|
||||
--el-table-theme-header-bg: color-mix(in srgb, var(--el-color-primary, #4080ff) 11%, #243044 89%);
|
||||
--el-table-theme-hover-bg: color-mix(
|
||||
in srgb,
|
||||
var(--el-color-primary, #4080ff) 7.5%,
|
||||
var(--el-bg-color-overlay) 92.5%
|
||||
);
|
||||
--el-table-theme-stripe-bg: color-mix(
|
||||
in srgb,
|
||||
var(--el-color-primary, #4080ff) 4%,
|
||||
var(--el-bg-color-overlay) 96%
|
||||
);
|
||||
/* 表格线:暗色下偏柔,与 overlay 接近、略亮一线即可辨认 */
|
||||
--el-table-theme-border-color: color-mix(
|
||||
in srgb,
|
||||
var(--el-color-primary, #4080ff) 9%,
|
||||
#3d4f63 91%
|
||||
);
|
||||
|
||||
/* 画布/分割线/Tags hover 不再维护 layout-* 混色变量 */
|
||||
|
||||
--el-select-option-hover-bg: var(--el-fill-color-light);
|
||||
--el-select-option-selected-bg: var(--el-color-primary-light-9);
|
||||
|
||||
--el-datepicker-range-bg: var(--el-color-primary-light-9);
|
||||
--el-datepicker-range-hover-bg: var(--el-color-primary-light-8);
|
||||
|
||||
--el-dialog-bg-color: var(--el-bg-color-overlay);
|
||||
--el-popover-bg-color: var(--el-dialog-bg-color);
|
||||
--el-popup-modal-bg-color: var(--el-overlay-color);
|
||||
--el-popup-modal-opacity: 1;
|
||||
}
|
||||
|
||||
/* 压过 EP 内联的 shade(20),使子项 hover 读到与 html 一致的主题混色 */
|
||||
html.dark .el-menu {
|
||||
--el-menu-hover-bg-color: var(--_menu-hover-bg) !important;
|
||||
}
|
||||
|
||||
/* Dialog:EP 在 .el-dialog 上写死 --el-dialog-bg-color: var(--el-bg-color),改为抬升中性底 */
|
||||
html .el-dialog {
|
||||
--el-dialog-bg-color: var(--el-bg-color-overlay);
|
||||
}
|
||||
|
||||
/*
|
||||
* 浮层 Popper(与弹窗同一 token:--el-dialog-bg-color,现为中性 overlay)
|
||||
* EP 部分组件写死 --el-bg-color-overlay;显式统一到 --el-dialog-bg-color 便于后续改一处全局同步。
|
||||
*/
|
||||
html .el-cascader {
|
||||
--el-cascader-menu-fill: var(--el-dialog-bg-color);
|
||||
}
|
||||
|
||||
html .el-mention {
|
||||
--el-mention-bg-color: var(--el-dialog-bg-color);
|
||||
}
|
||||
|
||||
html .el-select__popper.el-popper,
|
||||
html .el-tree-select__popper.el-popper,
|
||||
html .el-dropdown__popper.el-popper,
|
||||
html .el-autocomplete__popper.el-popper,
|
||||
html .el-mention__popper.el-popper,
|
||||
html .el-picker__popper.el-popper {
|
||||
background: var(--el-dialog-bg-color);
|
||||
}
|
||||
|
||||
html .el-select__popper.el-popper .el-popper__arrow:before,
|
||||
html .el-tree-select__popper.el-popper .el-popper__arrow:before,
|
||||
html .el-dropdown__popper.el-popper .el-popper__arrow:before,
|
||||
html .el-autocomplete__popper.el-popper .el-popper__arrow:before,
|
||||
html .el-mention__popper.el-popper .el-popper__arrow:before,
|
||||
html .el-picker__popper.el-popper .el-popper__arrow:before {
|
||||
background: var(--el-dialog-bg-color);
|
||||
}
|
||||
|
||||
html .el-picker-panel {
|
||||
background: var(--el-dialog-bg-color);
|
||||
--el-datepicker-inrange-bg-color: var(--el-datepicker-range-bg);
|
||||
--el-datepicker-inrange-hover-bg-color: var(--el-datepicker-range-hover-bg);
|
||||
}
|
||||
|
||||
html .el-dropdown-menu {
|
||||
background-color: var(--el-dialog-bg-color);
|
||||
}
|
||||
|
||||
html .el-color-picker-panel {
|
||||
background: var(--el-dialog-bg-color);
|
||||
}
|
||||
|
||||
html .el-transfer-panel {
|
||||
background: var(--el-dialog-bg-color);
|
||||
}
|
||||
|
||||
/* Select / TreeSelect:选项 hover、选中背景随主色(浮层底仍为 overlay) */
|
||||
html .el-select__popper .el-select-dropdown__item.is-hovering,
|
||||
html .el-tree-select__popper .el-select-dropdown__item.is-hovering {
|
||||
background-color: var(--el-select-option-hover-bg);
|
||||
}
|
||||
|
||||
html .el-select__popper .el-select-dropdown__item.is-selected,
|
||||
html .el-tree-select__popper .el-select-dropdown__item.is-selected {
|
||||
background-color: var(--el-select-option-selected-bg);
|
||||
}
|
||||
|
||||
/* 级联面板节点 hover 与 Select 一致(面板内自带 --el-cascader-node-background-hover) */
|
||||
html .el-cascader-panel {
|
||||
--el-cascader-node-background-hover: var(--el-select-option-hover-bg);
|
||||
}
|
||||
|
||||
/* Skeleton 动画条:跟随中性 fill */
|
||||
html .el-skeleton {
|
||||
--el-skeleton-to-color: var(--el-fill-color);
|
||||
}
|
||||
|
||||
/* Tabs border-card:使用中性 fill,避免混色 */
|
||||
html .el-tabs--border-card > .el-tabs__header,
|
||||
html.dark .el-tabs--border-card > .el-tabs__header {
|
||||
background: var(--el-fill-color-light);
|
||||
}
|
||||
|
||||
/* Steps 简约模式底条 */
|
||||
html .el-steps--simple,
|
||||
html.dark .el-steps--simple {
|
||||
background: var(--el-fill-color-light);
|
||||
}
|
||||
|
||||
/* Progress:轨道使用中性 fill */
|
||||
html .el-progress-bar__outer,
|
||||
html.dark .el-progress-bar__outer {
|
||||
background-color: var(--el-fill-color-light);
|
||||
}
|
||||
|
||||
/* ---------- Element Plus 表格(随 :root / html.dark 与 theme.ts 主色变) ---------- */
|
||||
html .el-table {
|
||||
--el-table-bg-color: var(--el-bg-color-overlay);
|
||||
--el-table-tr-bg-color: var(--el-bg-color-overlay);
|
||||
--el-table-header-bg-color: var(--el-table-theme-header-bg);
|
||||
--el-table-striped-row-bg: var(--el-table-theme-stripe-bg);
|
||||
--el-table-row-hover-bg-color: var(--el-table-theme-hover-bg);
|
||||
--el-table-border-color: var(--el-table-theme-border-color);
|
||||
--el-table-border: 1px solid var(--el-table-border-color);
|
||||
}
|
||||
|
||||
html .el-table.el-table--striped {
|
||||
--el-fill-color-lighter: var(--el-table-theme-stripe-bg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Element Plus 自绘滚动条(el-scrollbar):侧栏菜单、表格 body、TagsView、分页等
|
||||
* EP 默认 --el-scrollbar-bg-color 为 text-secondary + 低透明度,与主题无关;此处与上方「全局原生滚动条」同色
|
||||
*/
|
||||
html .el-scrollbar {
|
||||
--el-scrollbar-bg-color: var(--app-scrollbar-thumb);
|
||||
--el-scrollbar-hover-bg-color: var(--app-scrollbar-thumb-hover);
|
||||
--el-scrollbar-opacity: 1;
|
||||
--el-scrollbar-hover-opacity: 1;
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
$border: 1px solid var(--el-border-color-light);
|
||||
|
||||
/* el-dialog */
|
||||
.el-dialog {
|
||||
.el-dialog__header {
|
||||
padding: 15px 20px;
|
||||
margin: 0;
|
||||
border-bottom: $border;
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
padding: 15px;
|
||||
border-top: $border;
|
||||
}
|
||||
}
|
||||
|
||||
/** el-drawer */
|
||||
.el-drawer {
|
||||
.el-drawer__header {
|
||||
padding: 15px 20px;
|
||||
margin: 0;
|
||||
color: inherit;
|
||||
border-bottom: $border;
|
||||
}
|
||||
|
||||
.el-drawer__body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.el-drawer__footer {
|
||||
padding: 15px;
|
||||
border-top: $border;
|
||||
}
|
||||
}
|
||||
|
||||
// 抽屉和对话框底部按钮区域
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
// 列表
|
||||
.el-card {
|
||||
.el-card__body {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
// 表格内操作列:单元格 .cell 默认 overflow:hidden,会裁切 el-button 的 :focus-visible outline(常见为底边缺失)。
|
||||
// 仅对「含 el-button」的单元格放开裁剪,避免整表 .cell 全改为 visible 破坏省略号与长文本布局。
|
||||
.el-table .el-table__cell .cell:has(.el-button) {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
// 不支持 :has() 的环境:将 outline 略向内收,减轻裁切(效果弱于上一段)。
|
||||
@supports not selector(:has(*)) {
|
||||
.el-table .el-button:focus-visible {
|
||||
outline-offset: -1px;
|
||||
}
|
||||
}
|
||||
@@ -1,258 +1,23 @@
|
||||
// ==================== 主题变量导入 ====================
|
||||
// 1. 项目自定义变量(侧边栏、布局等)
|
||||
@use "./variables";
|
||||
// 重置默认样式
|
||||
@use './core/reset.scss';
|
||||
|
||||
// 2. 暗黑模式变量(合并)
|
||||
@use "./dark/css-vars";
|
||||
// 应用全局样式
|
||||
@use './core/app.scss';
|
||||
|
||||
// ==================== 基础样式 ====================
|
||||
@use "./reset";
|
||||
@use "./element-plus";
|
||||
// Element Plus 样式优化
|
||||
@use './core/el-ui.scss';
|
||||
|
||||
// ==================== layout内容样式 ====================
|
||||
.app-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* 不用 gap:否则 ExportModal/抽屉 等块级兄弟会与 PageContent 之间多出一道 16px,表格用 100vh 时高度也不对 */
|
||||
gap: 0;
|
||||
height: 100%;
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
border-radius: 4px;
|
||||
}
|
||||
// Element Plus 暗黑主题
|
||||
@use './core/el-dark.scss';
|
||||
|
||||
/* 与搜索区纵向间距(替代原 gap);主表格占满剩余高度,便于 el-table height:100% */
|
||||
.app-container > .el-card.data-table {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
margin-top: 16px;
|
||||
}
|
||||
// 暗黑主题样式优化
|
||||
@use './core/dark.scss';
|
||||
|
||||
.app-container > .el-card.data-table:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
// 路由切换动画
|
||||
@use './core/router-transition';
|
||||
|
||||
/* 用户管理等:首行是 el-row 时占满高度 */
|
||||
.app-container > .el-row {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
// 主题切换过渡优化
|
||||
@use './core/theme-change.scss';
|
||||
|
||||
/* 块级弹窗宿主不参与纵向 flex 分配,避免挤压主表格 */
|
||||
.app-container > .curd-export-modal-host,
|
||||
.app-container > .curd-import-modal-host {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
// ==================== 搜索区域样式 ====================
|
||||
.search-container {
|
||||
border: 1px solid var(--el-border-color-light);
|
||||
}
|
||||
|
||||
// ==================== 表格区域样式 ====================
|
||||
.data-table {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
/* 嵌套在 el-row/el-col 等内部时,与上方搜索区留白 */
|
||||
margin-top: 16px;
|
||||
|
||||
// 表格工具栏区域(与 PageSearch+PageContent 各业务页 #toolbar 插槽一致:flex 换行,避免 el-row 挤压右侧)
|
||||
&__toolbar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
row-gap: 8px;
|
||||
column-gap: 12px;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
|
||||
&--left,
|
||||
&--right {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.el-button {
|
||||
margin-right: 0 !important;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&--right {
|
||||
flex-shrink: 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
// 表格内容区域
|
||||
&__content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
transition:
|
||||
height 0.3s ease,
|
||||
flex 0.3s ease;
|
||||
}
|
||||
|
||||
// 分页区域
|
||||
.el-pagination {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
/* 主表格 margin-top 见上;此处保留嵌套在非直接子级时的默认 .data-table margin-top */
|
||||
|
||||
// 进度条颜色
|
||||
#nprogress .bar {
|
||||
background-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
// ==================== 全局原生滚动条(与主题主色混色,Firefox + WebKit) ====================
|
||||
* {
|
||||
scrollbar-color: var(--app-scrollbar-thumb) var(--app-scrollbar-track);
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
background: var(--app-scrollbar-track);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background: var(--app-scrollbar-thumb);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--app-scrollbar-thumb-hover);
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-corner {
|
||||
background: var(--app-scrollbar-track);
|
||||
}
|
||||
|
||||
// ==================== 菜单选中态(子菜单) ====================
|
||||
// 给左侧/混合左侧以及顶部弹层子菜单的选中项增加背景色,增强可见性
|
||||
.el-menu--vertical .el-menu-item.is-active,
|
||||
.el-menu--popup .el-menu-item.is-active {
|
||||
background-color: var(--el-color-primary-light-9) !important;
|
||||
}
|
||||
|
||||
// ==================== 侧边栏激活项「右侧竖杠」指示条 ====================
|
||||
// 仅作用于左侧布局、混合布局左侧侧栏(避免影响顶部菜单与弹层菜单)
|
||||
.layout__sidebar,
|
||||
.layout__sidebar--left {
|
||||
.el-menu--vertical {
|
||||
.el-menu-item.is-active {
|
||||
box-shadow: inset -3px 0 0 0 var(--menu-active-indicator, var(--el-color-primary));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 经典蓝:激活项背景不使用偏白色,改为蓝系轻色差背景
|
||||
html.sidebar-color-blue {
|
||||
.el-menu--vertical .el-menu-item.is-active,
|
||||
.el-menu--popup .el-menu-item.is-active {
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 混合布局左侧菜单 hover 不单独覆盖:
|
||||
// 统一交给 Element Plus 的 --el-menu-hover-bg-color 与 MenuItem.vue 的通用规则,
|
||||
// 确保 Mix-left 与 Left 侧边布局保持一致。
|
||||
|
||||
// 暗色:hover 由 EP + css-vars 中 html.dark .el-menu 覆写 --el-menu-hover-bg-color 生效;仅激活项需压过 primary-light-9
|
||||
html.dark .el-menu--vertical .el-menu-item.is-active,
|
||||
html.dark .el-menu--popup .el-menu-item.is-active {
|
||||
background-color: var(--el-menu-active-bg-color) !important;
|
||||
}
|
||||
|
||||
// 亮色 + 经典蓝:悬浮背景使用经典蓝体系(比底色略深),避免发白
|
||||
html.sidebar-color-blue .el-menu {
|
||||
.el-menu-item:hover,
|
||||
.el-sub-menu__title:hover {
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
}
|
||||
|
||||
html.sidebar-color-blue .el-menu--popup {
|
||||
.el-menu-item:hover {
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 窄屏时隐藏菜单文字,只显示图标 ====================
|
||||
// 窄屏时隐藏菜单文字,只显示图标
|
||||
.hideSidebar {
|
||||
// Top布局和Mix布局的水平菜单
|
||||
&.layout-top .layout__header .el-menu--horizontal,
|
||||
&.layout-mix .layout__header .el-menu--horizontal {
|
||||
.el-menu-item,
|
||||
.el-sub-menu__title {
|
||||
.menu-title,
|
||||
span:not([class*="i-svg"]):not(.el-icon) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mix布局的左侧菜单
|
||||
&.layout-mix .layout__sidebar--left .el-menu {
|
||||
.el-menu-item,
|
||||
.el-sub-menu__title {
|
||||
.menu-title,
|
||||
span:not([class*="i-svg"]):not(.el-icon) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 代码生成:写入本地确认 — 随内容变宽(不超过视口),路径单行、列表区内横向滚动
|
||||
.el-message-box.gencode-write-confirm-box {
|
||||
--gencode-write-confirm-max: min(1100px, calc(100vw - 32px));
|
||||
|
||||
--el-messagebox-width: var(--gencode-write-confirm-max);
|
||||
box-sizing: border-box;
|
||||
width: fit-content !important;
|
||||
min-width: min(360px, calc(100vw - 32px));
|
||||
max-width: var(--gencode-write-confirm-max) !important;
|
||||
padding-bottom: 8px;
|
||||
|
||||
.el-message-box__message {
|
||||
box-sizing: border-box;
|
||||
max-width: 100%;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.gencode-write-confirm-body {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.gencode-write-path-list-wrap {
|
||||
max-height: 44vh;
|
||||
overflow: auto;
|
||||
border: 1px solid var(--el-border-color-lighter);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 2px rgb(0 0 0 / 4%);
|
||||
}
|
||||
|
||||
.gencode-write-path-row:last-child {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
}
|
||||
// 主题切换圆形扩散动画
|
||||
@use './core/theme-animation.scss';
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
*,
|
||||
::before,
|
||||
::after {
|
||||
box-sizing: border-box;
|
||||
border-color: currentcolor;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
#app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: 1.5;
|
||||
tab-size: 4;
|
||||
text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
font-family:
|
||||
"Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑",
|
||||
Arial, sans-serif;
|
||||
line-height: inherit;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizelegibility;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
svg {
|
||||
// 因icon大小被设置为和字体大小一致,而span等标签的下边缘会和字体的基线对齐,故需设置一个往下的偏移比例,来纠正视觉上的未对齐效果
|
||||
vertical-align: -0.15em;
|
||||
}
|
||||
|
||||
ul,
|
||||
li {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
a,
|
||||
a:focus,
|
||||
a:hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a:focus,
|
||||
a:active,
|
||||
div:focus {
|
||||
outline: none;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* stylelint-disable property-no-unknown */
|
||||
:export {
|
||||
sidebar-width: $sidebar-width;
|
||||
navbar-height: $navbar-height;
|
||||
tags-view-height: $tags-view-height;
|
||||
menu-background: $menu-background;
|
||||
menu-text: $menu-text;
|
||||
menu-active-text: $menu-active-text;
|
||||
menu-hover: $menu-hover;
|
||||
}
|
||||
/* stylelint-enable property-no-unknown */
|
||||
@@ -1,100 +1,8 @@
|
||||
@forward "element-plus/theme-chalk/src/common/var.scss" with (
|
||||
$colors: (
|
||||
"primary": (
|
||||
// 默认主题色 - 修改此值时需同步修改 src/settings.ts 中的 themeColor
|
||||
"base": #4080ff,
|
||||
),
|
||||
"success": (
|
||||
"base": #23c343,
|
||||
),
|
||||
"warning": (
|
||||
"base": #ff9a2e,
|
||||
),
|
||||
"danger": (
|
||||
"base": #f76560,
|
||||
),
|
||||
"info": (
|
||||
"base": #a9aeb8,
|
||||
),
|
||||
"default": (
|
||||
"base": #f5f5f5,
|
||||
),
|
||||
),
|
||||
/**
|
||||
* 全局 SCSS 变量(由 vite.config.ts → css.preprocessorOptions.scss.additionalData 注入到每个 `.vue` 的 `lang="scss"`)
|
||||
*
|
||||
* 默认主色请与 `src/config/setting.ts` 中 `themeColorPresets` 首项、主题切换逻辑保持一致。
|
||||
*/
|
||||
|
||||
$bg-color: (
|
||||
"page": #f5f8fd,
|
||||
)
|
||||
);
|
||||
|
||||
/** 全局SCSS变量 */
|
||||
|
||||
:root {
|
||||
--menu-background: #fff; // 菜单背景色
|
||||
/* Logo 与侧栏导航同一底(亮色;暗色见 html.dark 与 css-vars --layout-nav-bg) */
|
||||
--sidebar-logo-background: var(--menu-background);
|
||||
--layout-logo-bg: var(--menu-background);
|
||||
--menu-text: #212121; // 菜单文字颜色 浅色主题-白色侧边栏配色下仅占位,实际颜色由 el-menu-item 组件决定
|
||||
--menu-active-text: var(
|
||||
--el-menu-active-color
|
||||
); // 菜单激活文字颜色 浅色主题-白色侧边栏配色下仅占位,实际颜色由 el-menu-item 组件决定
|
||||
|
||||
--menu-hover: #e6f4ff; // 菜单悬停背景色 浅色主题-白色侧边栏配色下仅占位,实际颜色由 el-menu-item 组件决定
|
||||
--sidebar-logo-text-color: #333; // 侧边栏 Logo 文字颜色
|
||||
}
|
||||
|
||||
/** 浅色主题-深蓝色侧边栏配色 */
|
||||
html.sidebar-color-blue {
|
||||
--menu-background: #304156; // 菜单背景色
|
||||
--menu-text: #bfcbd9; // 菜单文字颜色
|
||||
--menu-active-text: var(--el-menu-active-color); // 菜单激活文字颜色
|
||||
--menu-hover: #263445; // 菜单悬停背景色
|
||||
--el-menu-hover-bg-color: var(--menu-hover); // 顶部/侧边菜单 hover 统一
|
||||
--sidebar-logo-text-color: #fff; // 侧边栏 Logo 文字颜色
|
||||
}
|
||||
|
||||
/** 暗黑主题 */
|
||||
html.dark {
|
||||
/* 侧栏底:与主内容区分区,见 src/styles/dark/css-vars.css --layout-nav-bg */
|
||||
--menu-background: var(--layout-nav-bg);
|
||||
--menu-text: #fff;
|
||||
--menu-active-text: var(--el-menu-active-color);
|
||||
--menu-hover: var(--el-menu-hover-bg-color);
|
||||
--sidebar-logo-background: var(--layout-sidebar-logo-bg);
|
||||
--layout-logo-bg: var(--layout-sidebar-logo-bg);
|
||||
--sidebar-logo-text-color: #fff;
|
||||
|
||||
/** WangEditor Dark */
|
||||
/* Textarea - css vars */
|
||||
--w-e-textarea-bg-color: var(--el-bg-color); /* 深色背景 */
|
||||
--w-e-textarea-color: var(--el-text-color-primary); /* 浅色文字 */
|
||||
--w-e-textarea-border-color: var(--el-border-color); /* 较深的边框颜色 */
|
||||
--w-e-textarea-slight-border-color: var(--el-border-color-lighter); /* 更淡一些的边框颜色 */
|
||||
--w-e-textarea-slight-color: var(--el-text-color-secondary); /* 浅灰色,用于不那么重要的元素 */
|
||||
--w-e-textarea-slight-bg-color: var(--el-bg-color-overlay); /* 稍微亮一点的背景色 */
|
||||
--w-e-textarea-selected-border-color: var(--el-color-info-light-5); /* 选中元素时的高亮边框 */
|
||||
--w-e-textarea-handler-bg-color: var(--el-color-primary); /* 工具按钮或交互元素的背景色 */
|
||||
|
||||
/* Toolbar - css vars */
|
||||
--w-e-toolbar-color: var(--el-text-color-regular); /* 工具栏文字颜色 */
|
||||
--w-e-toolbar-bg-color: var(--el-bg-color); /* 工具栏背景颜色 */
|
||||
--w-e-toolbar-active-color: var(--el-text-color-primary); /* 当前激活项的文字颜色 */
|
||||
--w-e-toolbar-active-bg-color: var(--el-fill-color-light); /* 当前激活项的背景颜色 */
|
||||
--w-e-toolbar-disabled-color: var(--el-text-color-secondary); /* 禁用项的颜色 */
|
||||
--w-e-toolbar-border-color: var(--el-border-color-base); /* 工具栏边框颜色 */
|
||||
|
||||
/* Modal - css vars */
|
||||
--w-e-modal-button-bg-color: var(--el-bg-color-light-3); /* 弹出框按钮背景色 */
|
||||
--w-e-modal-button-border-color: var(--el-border-color-light); /* 弹出框按钮边框颜色 */
|
||||
}
|
||||
|
||||
$menu-background: var(--menu-background); // 菜单背景色
|
||||
$menu-text: var(--menu-text); // 菜单文字颜色
|
||||
$menu-active-text: var(--menu-active-text); // 菜单激活文字颜色
|
||||
$menu-hover: var(--menu-hover); // 菜单悬停背景色
|
||||
$sidebar-logo-background: var(--sidebar-logo-background); // 侧边栏 Logo 背景色
|
||||
$sidebar-logo-text-color: var(--sidebar-logo-text-color); // 侧边栏 Logo 文字颜色
|
||||
|
||||
$sidebar-width: 210px; // 侧边栏宽度
|
||||
$sidebar-width-collapsed: 54px; // 侧边栏收缩宽度
|
||||
$navbar-height: 50px; // 导航栏高度
|
||||
$tags-view-height: 34px; // TagsView 高度
|
||||
// 供组件内 `$primary-base` 等引用(可选)
|
||||
$primary-base: #4080ff !default;
|
||||
|
||||
Reference in New Issue
Block a user