diff --git a/web-react/craco.config.js b/web-react/craco.config.js index a83f185..2cde7a0 100644 --- a/web-react/craco.config.js +++ b/web-react/craco.config.js @@ -23,12 +23,13 @@ module.exports = { javascriptEnabled: true, }, }, + importLoaders: 2 }, }, ], webpack: { plugins: [ - // new MonacoWebpackPlugin() + new MonacoWebpackPlugin() ] } } \ No newline at end of file diff --git a/web-react/src/App.js b/web-react/src/App.js index d98b1cf..77a1d96 100644 --- a/web-react/src/App.js +++ b/web-react/src/App.js @@ -3,7 +3,6 @@ import { ConfigProvider } from 'antd' import zhCN from 'antd/lib/locale/zh_CN' import moment from 'moment' import 'moment/locale/zh-cn' -import './assets/style/app.less' moment.locale('zh-cn') diff --git a/web-react/src/assets/style/dark/extend.less b/web-react/src/assets/style/dark/extend.less new file mode 100644 index 0000000..9bdd94f --- /dev/null +++ b/web-react/src/assets/style/dark/extend.less @@ -0,0 +1,6 @@ +@import '~antd/dist/antd.dark.less'; +@padding-xxs: 4px; +@padding-xl: 32px; +body { + line-height: 1.42857143; +} diff --git a/web-react/src/assets/style/app.less b/web-react/src/assets/style/dark/index.less similarity index 85% rename from web-react/src/assets/style/app.less rename to web-react/src/assets/style/dark/index.less index 1e27ce4..8697d9b 100644 --- a/web-react/src/assets/style/app.less +++ b/web-react/src/assets/style/dark/index.less @@ -8,14 +8,6 @@ @import './lib/width-height.less'; @import './lib/scrollbar.less'; @import './main.less'; -@import './frame/dark.less'; -@import './frame/light.less'; -.yo-nav-theme--dark { - .dark(); -} -.yo-nav-theme--light { - .light(); -} @import './lib/button.less'; @import './lib/card.less'; @import './lib/table.less'; @@ -39,5 +31,5 @@ @import './lib/anchor.less'; @import './lib/disabled.less'; @import './theme/primary.less'; -// @import './lib/font-weight.less'; @import './public.less'; +@import './pages/index.less'; diff --git a/web-react/src/assets/style/lib/align.less b/web-react/src/assets/style/dark/lib/align.less similarity index 100% rename from web-react/src/assets/style/lib/align.less rename to web-react/src/assets/style/dark/lib/align.less diff --git a/web-react/src/assets/style/lib/anchor.less b/web-react/src/assets/style/dark/lib/anchor.less similarity index 100% rename from web-react/src/assets/style/lib/anchor.less rename to web-react/src/assets/style/dark/lib/anchor.less diff --git a/web-react/src/assets/style/lib/authority-view.less b/web-react/src/assets/style/dark/lib/authority-view.less similarity index 100% rename from web-react/src/assets/style/lib/authority-view.less rename to web-react/src/assets/style/dark/lib/authority-view.less diff --git a/web-react/src/assets/style/lib/button.less b/web-react/src/assets/style/dark/lib/button.less similarity index 100% rename from web-react/src/assets/style/lib/button.less rename to web-react/src/assets/style/dark/lib/button.less diff --git a/web-react/src/assets/style/lib/card.less b/web-react/src/assets/style/dark/lib/card.less similarity index 100% rename from web-react/src/assets/style/lib/card.less rename to web-react/src/assets/style/dark/lib/card.less diff --git a/web-react/src/assets/style/lib/cascader.less b/web-react/src/assets/style/dark/lib/cascader.less similarity index 100% rename from web-react/src/assets/style/lib/cascader.less rename to web-react/src/assets/style/dark/lib/cascader.less diff --git a/web-react/src/assets/style/lib/checkbox.less b/web-react/src/assets/style/dark/lib/checkbox.less similarity index 100% rename from web-react/src/assets/style/lib/checkbox.less rename to web-react/src/assets/style/dark/lib/checkbox.less diff --git a/web-react/src/assets/style/dark/lib/color-selector.less b/web-react/src/assets/style/dark/lib/color-selector.less new file mode 100644 index 0000000..e7da66e --- /dev/null +++ b/web-react/src/assets/style/dark/lib/color-selector.less @@ -0,0 +1,18 @@ +@import (reference) '../extend.less'; +.ant-select-dropdown { + .chrome-picker { + width: auto !important; + margin: -@padding-xxs 0; + + border-radius: 0 !important; + background: transparent !important; + box-shadow: none !important; + } +} +.color-selector--palette { + width: 32px; + height: 32px; + + border-radius: @border-radius-base; + box-shadow: inset 0 0 0 @border-width-base @border-color-base, inset 0 0 0 3px @black; +} diff --git a/web-react/src/assets/style/lib/container.less b/web-react/src/assets/style/dark/lib/container.less similarity index 100% rename from web-react/src/assets/style/lib/container.less rename to web-react/src/assets/style/dark/lib/container.less diff --git a/web-react/src/assets/style/lib/description.less b/web-react/src/assets/style/dark/lib/description.less similarity index 76% rename from web-react/src/assets/style/lib/description.less rename to web-react/src/assets/style/dark/lib/description.less index 05bf783..cfe090a 100644 --- a/web-react/src/assets/style/lib/description.less +++ b/web-react/src/assets/style/dark/lib/description.less @@ -4,7 +4,7 @@ >table { border-collapse: collapse; - background-color: @white; + background-color: @component-background; } } } diff --git a/web-react/src/assets/style/lib/disabled.less b/web-react/src/assets/style/dark/lib/disabled.less similarity index 100% rename from web-react/src/assets/style/lib/disabled.less rename to web-react/src/assets/style/dark/lib/disabled.less diff --git a/web-react/src/assets/style/lib/dropdown.less b/web-react/src/assets/style/dark/lib/dropdown.less similarity index 100% rename from web-react/src/assets/style/lib/dropdown.less rename to web-react/src/assets/style/dark/lib/dropdown.less diff --git a/web-react/src/assets/style/lib/font-size.less b/web-react/src/assets/style/dark/lib/font-size.less similarity index 100% rename from web-react/src/assets/style/lib/font-size.less rename to web-react/src/assets/style/dark/lib/font-size.less diff --git a/web-react/src/assets/style/lib/font-weight.less b/web-react/src/assets/style/dark/lib/font-weight.less similarity index 100% rename from web-react/src/assets/style/lib/font-weight.less rename to web-react/src/assets/style/dark/lib/font-weight.less diff --git a/web-react/src/assets/style/lib/form-page.less b/web-react/src/assets/style/dark/lib/form-page.less similarity index 95% rename from web-react/src/assets/style/lib/form-page.less rename to web-react/src/assets/style/dark/lib/form-page.less index ae47a95..270d18a 100644 --- a/web-react/src/assets/style/lib/form-page.less +++ b/web-react/src/assets/style/dark/lib/form-page.less @@ -16,7 +16,7 @@ margin-bottom: 0; padding: 0 @padding-md; - background-color: @white; + background-color: @component-background; &.ant-tabs-card-bar { .ant-tabs-nav-container { @@ -121,7 +121,7 @@ padding: @padding-xs @padding-md; border: @border-width-base @border-style-base @border-color-split; - background-color: fade(@white, 80%); + background-color: fade(@component-background, 80%); backdrop-filter: blur(5px); @@ -164,6 +164,6 @@ &--header { padding: @padding-md 0; - background-color: @white; + background-color: @component-background; } } \ No newline at end of file diff --git a/web-react/src/assets/style/dark/lib/form.less b/web-react/src/assets/style/dark/lib/form.less new file mode 100644 index 0000000..e770583 --- /dev/null +++ b/web-react/src/assets/style/dark/lib/form.less @@ -0,0 +1,399 @@ +@import (reference) '../extend.less'; +.yo-form { + &--fixed { + width: 660px; + margin: 0 auto; + } + .h1, + .h2, + .h3, + .h4, + .h5, + .h6 { + color: darken(@white, 40%); + } + .h3 { + font-size: 16px; + } + .h4 { + font-size: 15px; + } + .yo-form-group { + margin-bottom: @padding-md; + } + .ant-form-item { + display: flex; + justify-content: space-between; + + margin-bottom: -1px; + padding: @padding-xs @padding-md; + + border: @border-width-base @border-style-base @border-color-split; + background-color: @component-background; + + @box-shadow-focused: 0 0 0 2px fade(@primary-color, 50%); + @control-background: darken(@white, 95%) !important; + &::before, + &::after { + content: none; + } + .ant-form-item-control { + text-align: right; + } + .ant-input, + .ant-input-number, + .ant-mentions, + .ant-select-selector, + .ant-input-group-addon, + .ant-cascader-picker, + .ant-input-affix-wrapper, + .ant-picker { + z-index: 1; + + text-align: left; + + color: darken(@white, 10%); + border: 0; + background-color: @control-background; + } + .ant-mentions { + textarea { + background-color: @control-background; + } + } + .focus { + z-index: 2 !important; + + box-shadow: @box-shadow-focused; + } + .unfoucs { + z-index: 1 !important; + + box-shadow: none; + } + .ant-input { + &:focus { + .focus(); + } + } + .ant-input-affix-wrapper { + >.ant-input { + &:focus { + .unfoucs(); + } + } + } + .ant-input-number-focused, + .ant-mentions-focused { + .focus(); + } + .ant-select-focused, + .ant-select-open { + z-index: 2; + .ant-select-selection { + .focus(); + } + } + .ant-cascader-picker:focus { + .ant-cascader-input { + .focus(); + } + } + .ant-input-affix-wrapper:focus, + .ant-input-affix-wrapper-focused { + .focus(); + } + .ant-select-focused:not(.ant-select-disabled).ant-select:not(.ant-select-customize-input) { + .ant-select-selector { + .focus(); + } + } + .ant-picker-focused { + .focus(); + } + .ant-input-group { + .ant-row-flex { + .ant-select { + width: 100%; + } + } + .ant-input-group-addon { + z-index: 0; + } + } + .ant-cascader-picker-clear { + background-color: @control-background; + } + } + .ant-form-item-label { + overflow: hidden; + flex: 1 1 auto; + + margin-right: @padding-md; + + text-align: left; + text-overflow: ellipsis; + >label { + color: darken(@white, 10%); + &::after { + content: none; + } + } + } + .ant-form-item-control { + flex: 0 0 61.8%; + + width: 61.8%; + min-width: 220px; + } + .yo-form--fluid { + .ant-form-item-control { + flex: 0 0 100%; + + width: 100%; + } + } + .yo-form--short { + .ant-form-item-control { + flex: 0 0 38.2%; + + width: 38.2%; + } + } + // 上下布局 + .yo-form--vertical { + display: block; + .ant-form-item-control { + text-align: left; + } + &-radio { + .ant-radio-wrapper { + line-height: @padding-lg; + + display: block; + + margin-right: 0; + +.ant-radio-wrapper { + margin-top: @padding-sm; + } + } + } + .ant-form-item-control-wrapper { + margin-left: @padding-lg; + } + .ant-form-explain { + margin-left: 0; + } + } + .yo-form-link { + display: flex; + align-items: center; + + margin-bottom: -1px; + padding: @padding-md; + + cursor: pointer; + + border: @border-width-base @border-style-base @border-color-split; + background-color: @component-background; + &:hover { + background-color: lighten(@black, 1%); + } + &:active { + background-color: lighten(@black, 3%); + } + &--title { + font-size: @font-size-base + 1px; + + flex: 1; + } + &--content { + flex: 1; + + text-align: right; + + color: fade(@black, 35%); + } + &--right-icon { + margin-left: @padding-xs; + + color: fade(@black, 50%); + } + } + &.yo-form--no-border { + .ant-form-item { + padding: @padding-md 0; + + border-right: 0; + border-left: 0; + &:first-child { + border-top: 0; + } + &:last-child { + border-bottom: 0; + } + } + .yo-form-group { + margin-bottom: 0; + } + } +} +.yo-modal-form { + .ant-modal-body { + padding: 0; + } + .yo-form { + h1, + h2, + h3, + h4, + h5 { + margin: 0; + padding: @padding-sm @padding-md @padding-xs; + } + .yo-form-group { + margin-bottom: 0; + } + .ant-form-item { + border-right: 0; + border-left: 0; + &:first-child { + margin-top: -1px; + } + } + } +} +.yo-drawer-form { + .ant-drawer-wrapper-body { + display: flex; + flex-direction: column; + } + .ant-drawer-header { + flex: 0 0 auto; + } + .ant-drawer-body { + position: relative; + + flex: 1 1 100%; + + padding: 0; + } + .yo-drawer-form--body { + position: absolute; + top: 0; + bottom: @border-width-base + 20px + @padding-md * 2; + + overflow: auto; + + width: 100%; + padding: @padding-lg; + } + .ant-drawer-footer { + position: absolute; + left: 0; + bottom: 0; + + width: 100%; + padding: 10px @padding-md; + + text-align: right; + + border-top: @border-width-base @border-style-base @border-color-split; + background: @component-background; + button+button { + margin-left: @padding-xs; + } + } +} +.ant-form { + fieldset { + margin-bottom: @padding-lg; + padding: @padding-md; + + border: @border-width-base @border-style-base @border-color-split; + } + legend { + display: inline-block; + + width: auto; + margin-bottom: 0; + padding: 0 @padding-md; + + border: 0; + border-radius: @border-radius-base; + } +} +.ant-form-horizontal { + .ant-form-item-label { + line-height: 1.5; + + margin-right: @padding-xs; + + white-space: normal; + } +} +.ant-form-vertical { + .ant-form-item-label { + >label { + font-weight: bold; + } + } +} +.ant-form-item-required { + &::before { + content: '' !important; + vertical-align: middle; + + border-top: 4px solid transparent; + border-bottom: 4px solid transparent; + border-left: 5px solid @highlight-color; + background: none; + } +} +.yo-form-page { + .ant-form { + .ant-radio-button-wrapper { + margin-right: @padding-xs; + margin-bottom: @padding-xs; + + border-left: @border-width-base @border-style-base @border-color-base; + &.ant-radio-button-wrapper-checked { + border-left-color: @primary-color; + } + &:not(:first-child) { + &::before { + content: none; + } + } + } + } +} +.yo-filter-item { + display: flex; + flex-flow: row wrap; + + margin-bottom: 0; + .ant-tag-checkable { + font-size: @font-size-base; + } + .ant-radio-button-wrapper { + border: 0 !important; + background-color: transparent; + &:hover { + color: @red-6; + } + } + .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) { + border-color: @red-6; + background-color: @red-6; + &:hover { + border-color: @red-5; + background-color: @red-5; + } + &:active { + border-color: @red-7; + background-color: @red-7; + box-shadow: none; + } + } +} diff --git a/web-react/src/assets/style/lib/icon-selector.less b/web-react/src/assets/style/dark/lib/icon-selector.less similarity index 100% rename from web-react/src/assets/style/lib/icon-selector.less rename to web-react/src/assets/style/dark/lib/icon-selector.less diff --git a/web-react/src/assets/style/lib/input.less b/web-react/src/assets/style/dark/lib/input.less similarity index 100% rename from web-react/src/assets/style/lib/input.less rename to web-react/src/assets/style/dark/lib/input.less diff --git a/web-react/src/assets/style/lib/list.less b/web-react/src/assets/style/dark/lib/list.less similarity index 100% rename from web-react/src/assets/style/lib/list.less rename to web-react/src/assets/style/dark/lib/list.less diff --git a/web-react/src/assets/style/lib/margin.less b/web-react/src/assets/style/dark/lib/margin.less similarity index 100% rename from web-react/src/assets/style/lib/margin.less rename to web-react/src/assets/style/dark/lib/margin.less diff --git a/web-react/src/assets/style/lib/modal.less b/web-react/src/assets/style/dark/lib/modal.less similarity index 83% rename from web-react/src/assets/style/lib/modal.less rename to web-react/src/assets/style/dark/lib/modal.less index b066f86..8c9c850 100644 --- a/web-react/src/assets/style/lib/modal.less +++ b/web-react/src/assets/style/dark/lib/modal.less @@ -7,16 +7,17 @@ .ant-modal-header { padding: @padding-sm @padding-md; + border-bottom: 0; background-color: transparent; } .ant-modal-title { color: fade(@white, 85%); } .ant-modal-body { - background-color: @white; + background-color: @component-background; } .ant-modal-footer { - background-color: @white; + background-color: @component-background; } .ant-modal-close { top: 10px; diff --git a/web-react/src/assets/style/lib/page.less b/web-react/src/assets/style/dark/lib/page.less similarity index 100% rename from web-react/src/assets/style/lib/page.less rename to web-react/src/assets/style/dark/lib/page.less diff --git a/web-react/src/assets/style/lib/radio.less b/web-react/src/assets/style/dark/lib/radio.less similarity index 100% rename from web-react/src/assets/style/lib/radio.less rename to web-react/src/assets/style/dark/lib/radio.less diff --git a/web-react/src/assets/style/dark/lib/scrollbar.less b/web-react/src/assets/style/dark/lib/scrollbar.less new file mode 100644 index 0000000..84b7c04 --- /dev/null +++ b/web-react/src/assets/style/dark/lib/scrollbar.less @@ -0,0 +1,14 @@ +@import (reference) '../extend.less'; +::-webkit-scrollbar { + width: 7px; + height: 7px; + + background-color: fade(@white, 10%); +} +::-webkit-scrollbar-thumb { + border-radius: @border-radius-base; + background-color: fade(@white, 30%); +} +::-webkit-scrollbar-thumb:active { + background-color: fade(@white, 50%); +} diff --git a/web-react/src/assets/style/lib/select.less b/web-react/src/assets/style/dark/lib/select.less similarity index 100% rename from web-react/src/assets/style/lib/select.less rename to web-react/src/assets/style/dark/lib/select.less diff --git a/web-react/src/assets/style/dark/lib/table.less b/web-react/src/assets/style/dark/lib/table.less new file mode 100644 index 0000000..684a4ea --- /dev/null +++ b/web-react/src/assets/style/dark/lib/table.less @@ -0,0 +1,240 @@ +@import (reference) '../extend.less'; +.yo-query-bar { + margin-bottom: @padding-xs; + .ant-form-inline { + .ant-form-item { + margin-bottom: @padding-xs; + } + } +} +.yo-action-bar { + display: flex; + justify-content: space-between; + + margin-bottom: @padding-md; + &--actions { + >.ant-btn, + >.ant-btn-group { + +.ant-btn, + +.ant-btn-group { + margin-left: @padding-xs; + } + } + } +} +.ant-table { + .ant-table-container { + &::before, + &::after { + z-index: 3; + } + } +} +.ant-table-thead { + th.ant-table-column-has-sorters { + &:hover { + background-color: darken(@background-color-base, 5%); + } + } +} +.ant-table-tbody { + >tr { + >td { + transition-property: background, border-bottom-color; + } + } + >tr.ant-table-row:hover { + >td { + border-bottom-color: lighten(@primary-color, 30%); + } + } +} +.ant-table-small { + >.ant-table-content { + >.ant-table-body { + margin: 0; + >table { + >.ant-table-thead { + >tr { + >th { + background-color: @table-selected-row-bg; + } + } + } + } + } + } +} +.ant-table-thead { + >tr { + >th { + font-weight: bold; + } + } +} +.ant-table-sticky-scroll { + display: none; +} +.yo-table { + .ant-table { + margin: 0 !important; + } + .border-right-none { + border-right-width: 0 !important; + &:last-child { + border-right-width: 1px !important; + } + } + .ant-table-content { + .ant-table-body { + overflow-x: auto !important; + >table { + >.ant-table-thead { + >tr { + >th { + .border-right-none(); + } + } + } + >.ant-table-tbody { + >tr { + >td { + .border-right-none(); + } + } + } + } + } + .ant-table-fixed-left { + .ant-table-thead { + >tr { + >th { + border-right-width: 0 !important; + } + } + } + .ant-table-tbody { + >tr { + >td { + border-right-width: 0 !important; + } + } + } + } + .ant-table-fixed-right { + .ant-table-fixed { + border-left-width: 0 !important; + } + .ant-table-thead { + >tr { + >th { + .border-right-none(); + } + } + } + .ant-table-tbody { + >tr { + >td { + .border-right-none(); + } + } + } + } + } + .ant-table-bordered { + >.ant-table-container { + border-top: @border-width-base @border-style-base @table-border-color; + } + } + &--row-no { + width: 30px !important; + + background-color: @table-header-bg; + } +} +.yo-table-actions { + display: inline-block; + + vertical-align: middle; + &--inner { + display: flex; + align-items: center; + + height: 18px; + } +} +.yo-table--column-setting { + width: 240px; + .ant-dropdown-menu-item { + display: flex; + align-items: center; + justify-content: space-between; + } + .anticon-pushpin { + transition: @animation-duration-slow; + transform: rotate(45deg); + + color: darken(@white, 40%); + } + .yo-table--fixed { + transform: rotate(-45deg); + } +} +.yo-menu-table { + .ant-table { + .ant-table-expand-icon-col { + width: 28px; + } + .ant-table-row-expand-icon-cell { + z-index: 1; + + padding-right: 0 !important; + + border-right: none !important; + +.ant-table-cell { + padding-left: 0; + } + } + .ant-table-tbody { + >.ant-table-expanded-row-level-1>td { + padding: 0; + + border-right: none !important; + .ant-table-wrapper { + border: none; + .ant-table { + margin: 0 !important; + } + .ant-table-container { + border: none; + .ant-table-row-expand-icon-cell { + .ant-table-row-expand-icon { + left: @padding-md; + } + +.ant-table-cell { + padding-left: @padding-md; + } + } + .ant-table-expanded-row-level-1>td { + padding: @padding-sm @padding-xs @padding-sm @padding-xl; + + border-right: @border-width-base @border-style-base @table-border-color !important; + .ant-card { + max-width: fit-content; + margin-bottom: 0; + + background: none; + .ant-card-grid { + width: 300px; + padding: @padding-xs @padding-sm; + + background-color: @card-background; + } + } + } + } + } + } + } + } +} diff --git a/web-react/src/assets/style/lib/text-color.less b/web-react/src/assets/style/dark/lib/text-color.less similarity index 88% rename from web-react/src/assets/style/lib/text-color.less rename to web-react/src/assets/style/dark/lib/text-color.less index f1cd8ae..135d5a2 100644 --- a/web-react/src/assets/style/lib/text-color.less +++ b/web-react/src/assets/style/dark/lib/text-color.less @@ -22,10 +22,10 @@ color: @warning-color; } .text-gray { - color: gray; + color: fade(@white, 50%); } .text-normal { - color: @normal-color; + color: fade(@white, 30%); } .text-white { color: @white; diff --git a/web-react/src/assets/style/dark/lib/tree-layout.less b/web-react/src/assets/style/dark/lib/tree-layout.less new file mode 100644 index 0000000..5490376 --- /dev/null +++ b/web-react/src/assets/style/dark/lib/tree-layout.less @@ -0,0 +1,83 @@ +@import (reference) '../extend.less'; +@import (reference) './text-color.less'; +.yo-tree-layout { + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + .ant-layout-sider { + background-color: @component-background; + .ant-layout-header { + height: @layout-header-height - 20px; + + background-color: @component-background; + .header-actions { + .ant-input-search { + margin: (@layout-header-height - 20px - 32px) / 2 @padding-md; + } + } + } + } + &--collapsed { + position: absolute; + top: 0; + left: 0; + bottom: 0; + z-index: 4; + + transform: translateX(-100%); + &.open { + transform: translateX(0); + + box-shadow: 2px 0 8px fade(@black , 20%); + } + } + &--bar { + line-height: 20px; + + height: 20px; + padding: 0 @padding-md; + + text-align: right; + >.anticon { + margin-left: @padding-xs; + + cursor: pointer; + + color: fade(@white, 50%); + &:hover { + color: fade(@white, 80%); + } + } + } + &--content { + position: absolute; + top: @layout-header-height; + left: 0; + bottom: 0; + + overflow-y: auto; + + width: 100%; + &::-webkit-scrollbar { + width: 5px; + height: 5px; + + background-color: @component-background; + } + &::-webkit-scrollbar-thumb { + background-color: transparent; + } + &:hover::-webkit-scrollbar-thumb { + background-color: fade(@white, 30%); + } + &::-webkit-scrollbar-thumb:active { + background-color: fade(@white, 45%); + } + } + .ant-tree { + .text-gray(); + } +} diff --git a/web-react/src/assets/style/lib/upload.less b/web-react/src/assets/style/dark/lib/upload.less similarity index 100% rename from web-react/src/assets/style/lib/upload.less rename to web-react/src/assets/style/dark/lib/upload.less diff --git a/web-react/src/assets/style/lib/visibility.less b/web-react/src/assets/style/dark/lib/visibility.less similarity index 100% rename from web-react/src/assets/style/lib/visibility.less rename to web-react/src/assets/style/dark/lib/visibility.less diff --git a/web-react/src/assets/style/lib/width-height.less b/web-react/src/assets/style/dark/lib/width-height.less similarity index 100% rename from web-react/src/assets/style/lib/width-height.less rename to web-react/src/assets/style/dark/lib/width-height.less diff --git a/web-react/src/assets/style/dark/main.less b/web-react/src/assets/style/dark/main.less new file mode 100644 index 0000000..3ea8756 --- /dev/null +++ b/web-react/src/assets/style/dark/main.less @@ -0,0 +1,658 @@ +@import (reference) './extend.less'; +@import (reference) './lib/container.less'; +@import (reference) './lib/text-color.less'; +.yo-layout--spin { + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + background-color: @layout-header-background; + >.ant-spin-nested-loading { + height: 100%; + >div>.ant-spin { + max-height: none; + @-webkit-keyframes borderScale { + 0% { + border: 5px solid white; + } + 50% { + border: 25px solid transparent; + } + 100% { + border: 5px solid white; + } + } + @keyframes borderScale { + 0% { + border: 5px solid white; + } + 50% { + border: 25px solid transparent; + } + 100% { + border: 5px solid white; + } + } + .loader-container { + position: absolute; + top: 50%; + left: 50%; + + box-sizing: content-box; + width: 200px; + height: 200px; + margin: 0 auto; + margin-right: -50%; + + transform: translate(-50%, -50%); + -webkit-animation: borderScale 1s infinite ease-in-out; + animation: borderScale 1s infinite ease-in-out; + + color: white; + border: 5px solid transparent; + border-radius: 50%; + >p { + font-family: 'Raleway', sans-serif; + font-size: 2em; + font-weight: bold; + + position: absolute; + top: 50%; + left: 50%; + + margin-right: -50%; + + transform: translate(-50%, -50%); + } + } + } + >.ant-spin-container { + width: 100%; + height: 100%; + &.ant-spin-blur { + opacity: 0; + } + } + } +} +.ant-layout-header { + .header-actions { + display: flex; + .header-action { + display: inline-block; + + padding: 0 @padding-md; + + cursor: pointer; + transition: @animation-duration-slow; + transition-property: background-color; + .anticon { + font-size: @font-size-base + 6px; + + transition: @animation-duration-slow; + transition-property: color; + // 特殊工具按钮 + .theme-toggle { + position: relative; + + overflow: hidden; + + width: 20px; + height: 20px; + margin: 7px 0; + + border-radius: 50%; + &--real { + width: 100%; + height: 100%; + + border-radius: 50%; + background-color: #fff; + } + &--imaginary { + position: absolute; + top: 6px; + left: -6px; + + width: 18px; + height: 18px; + + transform: @animation-duration-slow transform; + transform: rotate(45deg) scaleY(1); + transform-origin: top right; + + border-radius: 50%; + background-color: fade(@layout-header-background, 70%); + } + } + } + &:active { + box-shadow: inset 1px 1px 10px rgba(0, 0, 0, .05); + } + } + .ant-select-auto-complete { + margin: (@layout-header-height - 10px - 30px) / 2 @padding-md; + .ant-input-affix-wrapper { + border: 0; + background-color: fade(@white, 15%); + &:focus, + &-focused { + background-color: fade(@white, 30%); + } + .ant-input { + color: fade(@white, 85%); + background-color: transparent; + } + .ant-input-suffix { + .anticon { + color: fade(@white, 60%); + } + } + } + } + } + .user-container { + z-index: 10; + + width: 32px + @padding-sm * 2; + height: @layout-header-height - 24px; + margin: 2px 0; + + transition: @animation-duration-slow; + .user-container-inner { + position: relative; + + transition: @animation-duration-slow; + + border-radius: @border-radius-base; + } + .user { + &--base { + line-height: @layout-header-height - 24px; + + position: relative; + + display: flex; + overflow: hidden; + align-items: center; + + width: 100%; + height: @layout-header-height - 24px; + padding: 0 @padding-sm; + + transition: @animation-duration-slow; + } + &--avatar { + box-shadow: 0 0 0 2px @white; + } + } + } +} +.ant-layout-content { + position: relative; + + overflow-y: auto; + >.yo-tab-external-mount { + position: absolute; + top: 0; + left: 0; + bottom: 0; + + display: flex; + flex-direction: column; + + width: 100%; + >.ant-tabs { + z-index: 5; + + overflow: visible; + >.ant-tabs-nav { + margin-bottom: 0; + + border-bottom: 0; + background-color: @layout-header-background; + box-shadow: 0 2px 12px fade(@black, 8%); + &::before { + content: none; + } + .ant-tabs-nav-container { + height: 30px; + margin-bottom: 0; + } + .ant-tabs-tab { + line-height: 30px; + + height: 30px; + margin-right: 0; + padding: 0; + + transition: none; + + border: 0; + background-color: transparent; + &:hover { + color: @white; + } + .ant-tabs-tab-btn { + transition: none; + } + &.ant-tabs-tab-active { + border-color: darken(@primary-color, 10%); + background-color: @primary-color; + .ant-tabs-tab-btn { + color: @white; + } + .ant-tabs-tab-remove { + color: fade(@white, 70%); + &:hover { + color: @white; + } + } + } + .yo-layout-tab-subtitle { + line-height: 1; + + display: inline-block; + overflow: hidden; + + max-width: 150px; + + transform: translateY(1px); + white-space: nowrap; + text-overflow: ellipsis; + + opacity: .75; + } + +.ant-tabs-tab { + margin-left: 0; + &::before { + position: absolute; + left: -.5px; + + width: 1px; + height: 24px; + + content: ''; + transform: scaleX(.5); + + background: linear-gradient(transparent, fade(@black, 30%), transparent); + } + } + .ant-dropdown-trigger { + padding: 0 @padding-md * 2 0 @padding-md; + } + .ant-tabs-tab-unclosable { + .ant-dropdown-trigger { + padding: 0 @padding-lg 0 @padding-md; + } + } + .ant-tabs-tab-remove { + line-height: 28px; + + position: absolute; + top: 0; + right: 0; + + margin: 0; + + transition: none; + } + } + .ant-tabs-nav-more { + padding: 5px @padding-md; + } + } + } + >.yo-tab-external-mount-content { + position: relative; + + height: 100%; + >.yo-tab-external-tabpane { + position: absolute; + top: 0; + left: 0; + + overflow-x: hidden; + overflow-y: auto; + + width: 100%; + height: 100%; + &.yo-tab-external-tabpane-inactive { + pointer-events: none; + + opacity: 0; + } + >iframe { + display: block; + + width: 100%; + height: 100%; + + border: 0; + } + } + } + } +} +.ant-layout-sider { + .ant-menu-inline { + border-right: 0; + } +} +.yo-nav { + padding-top: @padding-lg; + padding-bottom: @padding-lg; + &--row { + padding: 1px 0; + + column-gap: @padding-md; + column-count: 3; + } + &--col { + break-inside: avoid; + } + &--sub-item { + } + &--item-group { + font-size: @font-size-base; + line-height: 1.5; + + margin-bottom: @padding-xs; + padding-top: @padding-xs * 2; + + color: fade(@black, 35%); + border: @border-width-base @border-style-base transparent; + } + &--item { + font-size: @font-size-base; + line-height: 1.5; + + position: relative; + + margin-bottom: @padding-xs; + padding: @padding-xs @padding-sm; + + cursor: pointer; + transition: @animation-duration-fast; + + border: @border-width-base @border-style-base @border-color-split; + border-radius: @border-radius-base; + background-color: @white; + &:hover { + color: @white; + border-color: @primary-color; + background-color: @primary-color; + } + } +} +.yo-layout-sider { + height: 100%; + + background-color: @layout-header-background; + .ant-layout-sider-children { + display: flex; + flex-direction: column; + } + .logo { + font-size: @font-size-lg * 1.5; + font-weight: 500; + line-height: @layout-header-height + 10px; + + z-index: 11; + + display: flex; + overflow: hidden; + align-items: center; + flex: 0 0 @layout-header-height + 10px; + + height: @layout-header-height + 10px; + padding: 0 @padding-md 0 @padding-lg; + + color: @white; + box-shadow: none; + img { + max-height: 100%; + } + span { + margin-left: @padding-sm; + + transition: @animation-duration-slow; + transition-property: opacity; + } + } + &.ant-layout-sider-collapsed { + .logo { + span { + opacity: 0; + } + } + } + .yo-sider-nav { + position: relative; + z-index: 10; + + flex: 1 1 100%; + + box-shadow: 2px 0 8px fade(@black, 25%); + &--app { + font-size: @font-size-sm; + + margin-top: @padding-sm; + padding: 0 @padding-md; + +.text-gray(); + } + .ant-menu { + background-color: @layout-header-background; + } + .ant-menu-sub.ant-menu-inline { + background-color: fade(@white, 4%); + } + } + .swiper-container { + position: absolute; + top: 0; + left: 0; + bottom: 0; + + width: 100%; + .swiper-scrollbar { + transition: @animation-duration-slow; + transition-property: opacity; + + opacity: 0; + } + .swiper-scrollbar-drag { + background-color: fade(@white, 30%); + } + &:hover { + .swiper-scrollbar { + opacity: 1; + } + } + } + .swiper-slide { + height: auto; + min-height: 100%; + >.ant-spin-nested-loading { + height: 100%; + .ant-spin-blur { + &::after { + opacity: 0; + } + } + } + } +} +.yo-layout--left-menu, +.yo-layout--right-menu { + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + .ant-layout-header { + line-height: @layout-header-height - 20px; + + z-index: 6; + + height: @layout-header-height - 20px; + padding: 0; + + background-color: @white; + >section { + display: flex; + justify-content: space-between; + } + .header-actions { + .header-action { + line-height: @layout-header-height - 16px; + + height: @layout-header-height - 20px; + .anticon { + color: fade(@black, 35%); + } + &:hover { + background-color: fade(@black, 5%); + .anticon { + color: @icon-color-hover; + } + } + } + } + } + >section { + >.ant-layout-sider { + .yo-layout-sider(); + } + } +} +.yo-layout--top-nav { + position: absolute; + top: 0; + left: 0; + + display: flex; + flex-direction: column; + + width: 100%; + height: 100%; + + @layout-header-height: 54px; + .ant-layout-header { + line-height: @layout-header-height; + + z-index: 11; + + flex: 0 0 @layout-header-height; + + height: @layout-header-height; + padding: 0; + + background-color: @layout-header-background; + section { + display: flex; + justify-content: space-between; + + height: 100%; + } + .header-actions { + .header-action { + .anticon { + color: fade(@white, 60%); + } + &:hover { + background-color: fade(@white, 20%); + .anticon { + color: @white; + } + } + } + } + .user-container { + margin: (@layout-header-height - 40px) / 2 0; + } + .logo { + font-size: @font-size-lg * 1.5; + font-weight: 500; + line-height: @layout-header-height - 10px; + + display: flex; + overflow: hidden; + align-items: center; + + height: @layout-header-height 10px; + margin: 5px @padding-lg 5px 0; + + color: @white; + img { + max-height: 100%; + } + span { + margin-left: @padding-sm; + } + } + .ant-menu-horizontal { + line-height: @layout-header-height; + + border-bottom: 0; + >.ant-menu-submenu { + top: 0; + + border-bottom: 0; + } + } + .header-actions { + .header-action { + line-height: @layout-header-height - 16px; + + margin: 10px 0; + } + } + } + &--container { + .ant-layout-header { + .ant-menu-horizontal { + width: 400px; + } + } + .ant-layout-content { + .yo-tab-external-mount { + >.ant-tabs { + >.ant-tabs-bar { + .ant-tabs-nav-container { + width: @container-width - @padding-md * 2; + margin: 0 auto; + } + } + } + } + } + } + &--container-fluid { + .ant-layout-header { + .ant-menu-horizontal { + width: 800px; + } + @media (max-width: 1400px) { + .ant-menu-horizontal { + width: 600px; + } + } + } + } +} +.yo-user-popover { + width: 280px; + padding-top: 0; + .ant-popover-arrow { + display: none; + } + .ant-popover-inner-content { + padding: 0; + } +} diff --git a/web-react/src/pages/system/account/base.less b/web-react/src/assets/style/dark/pages/account-base.less similarity index 94% rename from web-react/src/pages/system/account/base.less rename to web-react/src/assets/style/dark/pages/account-base.less index 1ee4118..6ec0db8 100644 --- a/web-react/src/pages/system/account/base.less +++ b/web-react/src/assets/style/dark/pages/account-base.less @@ -1,4 +1,4 @@ -@import (reference) '~assets/style/app.less'; +@import (reference) '../extend.less'; .yo-avatar-info { position: relative; diff --git a/web-react/src/pages/home/index.less b/web-react/src/assets/style/dark/pages/home.less similarity index 87% rename from web-react/src/pages/home/index.less rename to web-react/src/assets/style/dark/pages/home.less index ffd71ba..e6b1a5f 100644 --- a/web-react/src/pages/home/index.less +++ b/web-react/src/assets/style/dark/pages/home.less @@ -1,9 +1,9 @@ -@import (reference) 'assets/style/app.less'; +@import (reference) '../extend.less'; .home-header { margin-bottom: @padding-md; padding: @padding-lg 0; - background-color: @white; + background-color: @component-background; } .home-header-row { display: flex; diff --git a/web-react/src/assets/style/dark/pages/index.less b/web-react/src/assets/style/dark/pages/index.less new file mode 100644 index 0000000..7927e7a --- /dev/null +++ b/web-react/src/assets/style/dark/pages/index.less @@ -0,0 +1,3 @@ +@import './login.less'; +@import './home.less'; +@import './account-base.less'; diff --git a/web-react/src/views/login/index.less b/web-react/src/assets/style/dark/pages/login.less similarity index 94% rename from web-react/src/views/login/index.less rename to web-react/src/assets/style/dark/pages/login.less index 3fdfe6a..b2e8e8e 100644 --- a/web-react/src/views/login/index.less +++ b/web-react/src/assets/style/dark/pages/login.less @@ -1,4 +1,4 @@ -@import (reference) 'assets/style/app.less'; +@import (reference) '../extend.less'; .yo-login { position: fixed; top: 0; @@ -57,6 +57,8 @@ transition: @animation-duration-base; transform: translate(0); >label { + font-weight: normal !important; + color: fade(@black, 40%); } } @@ -67,6 +69,7 @@ } .ant-input, .ant-input-affix-wrapper { + color: fade(@black, 85%); border-width: 0 0 @border-width-base 0 !important; border-color: fade(@black, 10%); background-color: transparent; diff --git a/web-react/src/assets/style/public.less b/web-react/src/assets/style/dark/public.less similarity index 89% rename from web-react/src/assets/style/public.less rename to web-react/src/assets/style/dark/public.less index 7714511..16a4aed 100644 --- a/web-react/src/assets/style/public.less +++ b/web-react/src/assets/style/dark/public.less @@ -7,7 +7,7 @@ border: @border-width-base @border-style-base @border-color-split; border-radius: @border-radius-base; - background-color: @white; + background-color: @component-background; .amap-icon { img { width: 25px; @@ -23,6 +23,7 @@ width: 25%; min-width: 300px; + background-color: @component-background; box-shadow: @box-shadow-base; } } diff --git a/web-react/src/assets/style/theme/README.md b/web-react/src/assets/style/dark/theme/README.md similarity index 100% rename from web-react/src/assets/style/theme/README.md rename to web-react/src/assets/style/dark/theme/README.md diff --git a/web-react/src/assets/style/dark/theme/primary.less b/web-react/src/assets/style/dark/theme/primary.less new file mode 100644 index 0000000..01fb33e --- /dev/null +++ b/web-react/src/assets/style/dark/theme/primary.less @@ -0,0 +1,5 @@ +@import '../index.less'; +@primary-color: #00a091; +@error-color: @red-7; +@font-size-base: 13px; +@border-radius-base: 0; diff --git a/web-react/src/assets/style/extend.less b/web-react/src/assets/style/default/extend.less similarity index 100% rename from web-react/src/assets/style/extend.less rename to web-react/src/assets/style/default/extend.less diff --git a/web-react/src/assets/style/default/index.less b/web-react/src/assets/style/default/index.less new file mode 100644 index 0000000..8697d9b --- /dev/null +++ b/web-react/src/assets/style/default/index.less @@ -0,0 +1,35 @@ +@import './extend.less'; +@import './lib/visibility.less'; +@import './lib/container.less'; +@import './lib/align.less'; +@import './lib/font-size.less'; +@import './lib/text-color.less'; +@import './lib/margin.less'; +@import './lib/width-height.less'; +@import './lib/scrollbar.less'; +@import './main.less'; +@import './lib/button.less'; +@import './lib/card.less'; +@import './lib/table.less'; +@import './lib/list.less'; +@import './lib/form.less'; +@import './lib/form-page.less'; +@import './lib/page.less'; +@import './lib/description.less'; +@import './lib/input.less'; +@import './lib/select.less'; +@import './lib/checkbox.less'; +@import './lib/radio.less'; +@import './lib/cascader.less'; +@import './lib/upload.less'; +@import './lib/dropdown.less'; +@import './lib/modal.less'; +@import './lib/tree-layout.less'; +@import './lib/authority-view.less'; +@import './lib/icon-selector.less'; +@import './lib/color-selector.less'; +@import './lib/anchor.less'; +@import './lib/disabled.less'; +@import './theme/primary.less'; +@import './public.less'; +@import './pages/index.less'; diff --git a/web-react/src/assets/style/default/lib/align.less b/web-react/src/assets/style/default/lib/align.less new file mode 100644 index 0000000..50f0bda --- /dev/null +++ b/web-react/src/assets/style/default/lib/align.less @@ -0,0 +1,9 @@ +.text-left { + text-align: left !important; +} +.text-center { + text-align: center !important; +} +.text-right { + text-align: right !important; +} diff --git a/web-react/src/assets/style/default/lib/anchor.less b/web-react/src/assets/style/default/lib/anchor.less new file mode 100644 index 0000000..e37e90f --- /dev/null +++ b/web-react/src/assets/style/default/lib/anchor.less @@ -0,0 +1,11 @@ +@import (reference) '../extend.less'; +.ant-anchor-ink-ball { + width: 2px; + height: 28px; + + transform: translate(-50%, -10px); + + border: 0; + border-radius: 0; + background-color: @primary-color; +} diff --git a/web-react/src/assets/style/default/lib/authority-view.less b/web-react/src/assets/style/default/lib/authority-view.less new file mode 100644 index 0000000..94c2f71 --- /dev/null +++ b/web-react/src/assets/style/default/lib/authority-view.less @@ -0,0 +1,53 @@ +@import (reference) '../extend.less'; +.yo-authority-view { + &--container { + >.ant-descriptions-view { + border: 0; + } + } + .ant-descriptions-item-label { + width: 150px; + } + .ant-descriptions { + clear: both; + + margin-bottom: @padding-sm; + .ant-descriptions-view { + overflow: visible; + } + &:last-child { + margin-bottom: 0; + } + } + .ant-descriptions-item-content { + padding: @padding-sm @padding-md; + .yo-authority-view--checkbox { + display: inline-block; + + width: 150px; + margin: @padding-xxs 0; + .ant-checkbox-wrapper { + margin: 0; + } + } + } + .ant-card-grid { + width: 25%; + margin-bottom: @padding-sm; + padding: @padding-xs; + + cursor: pointer; + } + .ant-card { + margin-bottom: 0; + + background-color: transparent; + &-body { + margin: -1px 0 0 -1px; + padding: 0; + } + .ant-card-grid { + margin-bottom: 0; + } + } +} diff --git a/web-react/src/assets/style/default/lib/button.less b/web-react/src/assets/style/default/lib/button.less new file mode 100644 index 0000000..c14e462 --- /dev/null +++ b/web-react/src/assets/style/default/lib/button.less @@ -0,0 +1,4 @@ +@import (reference) '../extend.less'; +.ant-btn { + box-shadow: none; +} diff --git a/web-react/src/assets/style/default/lib/card.less b/web-react/src/assets/style/default/lib/card.less new file mode 100644 index 0000000..7ae210e --- /dev/null +++ b/web-react/src/assets/style/default/lib/card.less @@ -0,0 +1,4 @@ +@import (reference) '../extend.less'; +.ant-card { + margin-bottom: @padding-md; +} diff --git a/web-react/src/assets/style/default/lib/cascader.less b/web-react/src/assets/style/default/lib/cascader.less new file mode 100644 index 0000000..88e0aee --- /dev/null +++ b/web-react/src/assets/style/default/lib/cascader.less @@ -0,0 +1,6 @@ +@import (reference) '../extend.less'; +.ant-cascader-picker-arrow { + svg { + transform: scaleY(.75); + } +} diff --git a/web-react/src/assets/style/default/lib/checkbox.less b/web-react/src/assets/style/default/lib/checkbox.less new file mode 100644 index 0000000..be80e3e --- /dev/null +++ b/web-react/src/assets/style/default/lib/checkbox.less @@ -0,0 +1,10 @@ +@import (reference) '../extend.less'; +.ant-checkbox-wrapper { + margin-right: @padding-xs; + &:last-child { + margin-right: 0; + } + +.ant-checkbox-wrapper { + margin-left: 0; + } +} diff --git a/web-react/src/assets/style/lib/color-selector.less b/web-react/src/assets/style/default/lib/color-selector.less similarity index 100% rename from web-react/src/assets/style/lib/color-selector.less rename to web-react/src/assets/style/default/lib/color-selector.less diff --git a/web-react/src/assets/style/default/lib/container.less b/web-react/src/assets/style/default/lib/container.less new file mode 100644 index 0000000..fba352e --- /dev/null +++ b/web-react/src/assets/style/default/lib/container.less @@ -0,0 +1,43 @@ +@import (reference) '../extend.less'; +@container-width: 1400px; +.container-base { + margin: 0 auto; + padding: 0 @padding-md; +} +.container { + width: @container-width; + +.container-base(); +} +@media (max-width: 1400px) { + .container { + width: auto; + } +} +.container-md { + width: @container-width - 200px; + +.container-base(); +} +.container-sm { + width: @container-width - 400px; + +.container-base(); +} +.container-xs { + width: @container-width - 600px; + +.container-base(); +} +.container-xxs { + width: @container-width - 700px; + +.container-base(); +} +.container-fluid { + .container-base(); +} +.container-flex { + display: flex; + justify-content: space-between; +} diff --git a/web-react/src/assets/style/default/lib/description.less b/web-react/src/assets/style/default/lib/description.less new file mode 100644 index 0000000..cfe090a --- /dev/null +++ b/web-react/src/assets/style/default/lib/description.less @@ -0,0 +1,10 @@ +@import (reference) '../extend.less'; +.ant-descriptions-bordered { + .ant-descriptions-view { + >table { + border-collapse: collapse; + + background-color: @component-background; + } + } +} diff --git a/web-react/src/assets/style/default/lib/disabled.less b/web-react/src/assets/style/default/lib/disabled.less new file mode 100644 index 0000000..c975e17 --- /dev/null +++ b/web-react/src/assets/style/default/lib/disabled.less @@ -0,0 +1,59 @@ +@import (reference) '../extend.less'; +.ant-btn-primary-disabled, +.ant-btn-primary.disabled, +.ant-btn-primary[disabled], +.ant-btn-primary-disabled:hover, +.ant-btn-primary.disabled:hover, +.ant-btn-primary[disabled]:hover, +.ant-btn-primary-disabled:focus, +.ant-btn-primary.disabled:focus, +.ant-btn-primary[disabled]:focus, +.ant-btn-primary-disabled:active, +.ant-btn-primary.disabled:active, +.ant-btn-primary[disabled]:active, +.ant-btn-primary-disabled.active, +.ant-btn-primary.disabled.active, +.ant-btn-primary[disabled].active { + opacity: .5; + color: @btn-primary-color; + border-color: @btn-primary-bg; + background-color: @btn-primary-bg; + box-shadow: @btn-primary-shadow; + text-shadow: @btn-text-shadow; +} +.ant-btn-danger-disabled, +.ant-btn-danger.disabled, +.ant-btn-danger[disabled], +.ant-btn-danger-disabled:hover, +.ant-btn-danger.disabled:hover, +.ant-btn-danger[disabled]:hover, +.ant-btn-danger-disabled:focus, +.ant-btn-danger.disabled:focus, +.ant-btn-danger[disabled]:focus, +.ant-btn-danger-disabled:active, +.ant-btn-danger.disabled:active, +.ant-btn-danger[disabled]:active, +.ant-btn-danger-disabled.active, +.ant-btn-danger.disabled.active, +.ant-btn-danger[disabled].active { + opacity: .5; + color: @btn-danger-color; + border-color: @btn-danger-border; + background-color: @btn-danger-bg; + box-shadow: @btn-primary-shadow; + text-shadow: @btn-text-shadow; +} +.ant-radio-button-wrapper-disabled, +.ant-radio-button-wrapper-disabled:first-child, +.ant-radio-button-wrapper-disabled:hover { + opacity: .5; + color: @radio-button-color; + background-color: @radio-button-bg; +} +.ant-radio-button-wrapper-disabled.ant-radio-button-wrapper-checked { + opacity: .5; + color: @btn-primary-color; + border-color: @btn-primary-bg; + background-color: @btn-primary-bg; + box-shadow: @btn-primary-shadow; +} diff --git a/web-react/src/assets/style/default/lib/dropdown.less b/web-react/src/assets/style/default/lib/dropdown.less new file mode 100644 index 0000000..4accbdb --- /dev/null +++ b/web-react/src/assets/style/default/lib/dropdown.less @@ -0,0 +1,6 @@ +@import (reference) '../extend.less'; +.ant-dropdown-trigger { + .anticon-down { + transform: scaleY(.75); + } +} diff --git a/web-react/src/assets/style/default/lib/font-size.less b/web-react/src/assets/style/default/lib/font-size.less new file mode 100644 index 0000000..67f8742 --- /dev/null +++ b/web-react/src/assets/style/default/lib/font-size.less @@ -0,0 +1,25 @@ +@import (reference) '../extend.less'; +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 32px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 16px; +} +h6, +.h6 { + font-size: 14px; +} diff --git a/web-react/src/assets/style/default/lib/font-weight.less b/web-react/src/assets/style/default/lib/font-weight.less new file mode 100644 index 0000000..b24c9c7 --- /dev/null +++ b/web-react/src/assets/style/default/lib/font-weight.less @@ -0,0 +1,24 @@ +@import (reference) '../extend.less'; +body { + font-weight: 100; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: 300; +} + +@btn-font-weight: 100; +.ant-card-meta-title { + font-weight: inherit; +} +.ant-table-thead { + >tr { + >th { + font-weight: 500; + } + } +} diff --git a/web-react/src/assets/style/default/lib/form-page.less b/web-react/src/assets/style/default/lib/form-page.less new file mode 100644 index 0000000..270d18a --- /dev/null +++ b/web-react/src/assets/style/default/lib/form-page.less @@ -0,0 +1,169 @@ +@import (reference) '../extend.less'; + +.yo-form-page { + position: relative; + + height: 100%; + + .yo-tab-external-mount { + display: flex; + flex-direction: column; + + height: 100%; + + >.ant-tabs { + >.ant-tabs-nav { + margin-bottom: 0; + padding: 0 @padding-md; + + background-color: @component-background; + + &.ant-tabs-card-bar { + .ant-tabs-nav-container { + height: @tabs-card-height + @padding-xs; + padding: (@tabs-card-height + @padding-xs - @btn-height-base) / 2 @padding-md; + } + + .ant-tabs-extra-content { + padding: (@tabs-card-height + @padding-xs - @btn-height-base) / 2 @padding-md; + } + + .ant-tabs-tab { + transition: none; + + .ant-btn(); + + &:hover { + border-color: @btn-default-border; + } + } + + .ant-tabs-tab { + line-height: @btn-height-base; + + margin-right: -1px; + } + + .ant-tabs-tab-active { + z-index: 2; + + color: @btn-primary-color; + border-color: @btn-primary-bg; + background-color: @btn-primary-bg; + + &:hover { + color: @btn-primary-color; + border-color: color(~`colorPalette('@{btn-primary-bg}', 5) `); + background-color: color(~`colorPalette('@{btn-primary-bg}', 5) `); + } + } + } + } + } + + >.yo-tab-external-mount-content { + position: relative; + + flex: 1; + + >.yo-tab-external-tabpane { + position: absolute; + top: 0; + left: 0; + + overflow: auto; + + width: 100%; + height: 100%; + + &.yo-tab-external-tabpane-inactive { + pointer-events: none; + + opacity: 0; + } + } + } + } + + &--bar { + position: sticky; + bottom: 0; + z-index: 200; + + &--with-tab { + position: absolute; + + display: flex; + align-items: flex-end; + + width: 100%; + height: 0; + padding-right: 7px; + + >.container-fluid { + width: 100%; + } + + ~.yo-tab-external-mount { + >.yo-tab-external-mount-content { + >.yo-tab-external-tabpane { + padding-bottom: @padding-xs * 2 + @btn-height-base + @border-width-base * 2; + } + } + } + } + } + + &--bar-inner { + display: flex; + justify-content: space-between; + + padding: @padding-xs @padding-md; + + border: @border-width-base @border-style-base @border-color-split; + background-color: fade(@component-background, 80%); + + backdrop-filter: blur(5px); + + >:first-child { + flex: 1; + } + + .ant-btn { + margin-left: @padding-sm; + } + } + + &--body { + >.ant-card-body { + padding: 0; + + >section { + padding: @padding-lg; + + >h5 { + padding-left: @padding-md; + + border-left: @padding-xs @border-style-base @primary-color; + } + } + } + } + + &-layout { + display: flex; + flex-direction: column; + + height: 100%; + + &--horizontal { + flex-direction: row; + } + } + + &--header { + padding: @padding-md 0; + + background-color: @component-background; + } +} \ No newline at end of file diff --git a/web-react/src/assets/style/lib/form.less b/web-react/src/assets/style/default/lib/form.less similarity index 96% rename from web-react/src/assets/style/lib/form.less rename to web-react/src/assets/style/default/lib/form.less index 4efbe7a..69ea80c 100644 --- a/web-react/src/assets/style/lib/form.less +++ b/web-react/src/assets/style/default/lib/form.less @@ -29,7 +29,7 @@ padding: @padding-xs @padding-md; border: @border-width-base @border-style-base @border-color-split; - background-color: @white; + background-color: @component-background; @box-shadow-focused: 0 0 0 2px fade(@primary-color, 50%); @control-background: lighten(@black, 95%) !important; @@ -58,7 +58,7 @@ } .ant-mentions { textarea { - background-color: lighten(@black, 95%); + background-color: @control-background; } } .focus { @@ -299,7 +299,7 @@ text-align: right; border-top: @border-width-base @border-style-base @border-color-split; - background: @white; + background: @component-background; button+button { margin-left: @padding-xs; } @@ -346,7 +346,7 @@ border-top: 4px solid transparent; border-bottom: 4px solid transparent; - border-left: 5px solid #f5222d; + border-left: 5px solid @highlight-color; background: none; } } @@ -356,7 +356,7 @@ margin-right: @padding-xs; margin-bottom: @padding-xs; - border-left: @border-width-base @border-style-base @normal-color; + border-left: @border-width-base @border-style-base @border-color-base; &.ant-radio-button-wrapper-checked { border-left-color: @primary-color; } diff --git a/web-react/src/assets/style/default/lib/icon-selector.less b/web-react/src/assets/style/default/lib/icon-selector.less new file mode 100644 index 0000000..3438d23 --- /dev/null +++ b/web-react/src/assets/style/default/lib/icon-selector.less @@ -0,0 +1,59 @@ +@import (reference) '../extend.less'; +.yo-icon-selector { + .ant-drawer-wrapper-body { + display: flex; + flex-direction: column; + } + .ant-drawer-body { + position: relative; + + flex: 1 1 100%; + + padding: 0; + } + .ant-tabs { + height: 100%; + .ant-tabs-content-left { + position: relative; + + height: 100%; + .ant-tabs-tabpane { + position: absolute; + top: 0; + left: 0; + + overflow-y: auto; + + width: 100%; + height: 100%; + padding: @padding-lg; + } + } + } + .ant-card { + margin: 0; + } + .ant-card-grid { + width: 25%; + + text-align: center; + >span { + font-size: @font-size-sm; + + display: block; + + margin: @padding-xxs -@padding-lg 0; + + white-space: nowrap; + + color: fade(@black, 50%); + } + &.yo-icon--selected { + color: @white; + background-color: @primary-color; + >span { + color: fade(@white, 50%); + } + } + } +} diff --git a/web-react/src/assets/style/default/lib/input.less b/web-react/src/assets/style/default/lib/input.less new file mode 100644 index 0000000..d464a3c --- /dev/null +++ b/web-react/src/assets/style/default/lib/input.less @@ -0,0 +1,4 @@ +@import (reference) '../extend.less'; +.yo-addon { + padding: 0 @padding-xs; +} diff --git a/web-react/src/assets/style/default/lib/list.less b/web-react/src/assets/style/default/lib/list.less new file mode 100644 index 0000000..2dbb2de --- /dev/null +++ b/web-react/src/assets/style/default/lib/list.less @@ -0,0 +1,95 @@ +@import (reference) '../extend.less'; +.ant-list-bordered { + border-color: @border-color-split; + background-color: @white; +} +.yo-list { + @title-color: lighten(@black, 70%); + @value-color: lighten(@black, 30%); + &-content--h { + display: flex; + align-items: center; + &--item { + margin-left: @padding-xl; + >span { + line-height: 20px; + + color: @title-color; + } + >p { + line-height: 22px; + + margin-top: @padding-xxs; + margin-bottom: 0; + + color: @value-color; + } + } + } + .ant-pagination { + margin: @padding-md 0; + } + .ant-descriptions { + .ant-descriptions-item-label { + color: @title-color; + } + .ant-descriptions-item-content { + color: @value-color; + } + .ant-descriptions-row { + &:last-child { + >td { + padding-bottom: 0; + } + } + } + } + &--scroll { + position: relative; + + overflow-x: auto; + } + .ant-list-items { + min-width: 1000px; + } + .ant-list-item { + transition: @animation-duration-slow; + transition-property: background, border-bottom-color; + &:hover { + border-bottom-color: lighten(@primary-color, 30%); + background: linear-gradient(90deg, transparent 10%, @background-color-light 70%, transparent); + } + } + &-container { + position: relative; + &::before, + &::after { + position: absolute; + top: 0; + bottom: 0; + z-index: 3; + + width: 30px; + + content: ''; + transition: box-shadow @animation-duration-slow; + pointer-events: none; + } + &::before { + left: 0; + } + &::after { + right: 0; + } + &.yo-list--ping-left { + &::before { + box-shadow: inset 10px 0 8px -8px fade(@black, 15%); + } + } + &.yo-list--ping-right { + &::after { + box-shadow: inset -10px 0 8px -8px fade(@black, 15%); + } + } + } +} diff --git a/web-react/src/assets/style/default/lib/margin.less b/web-react/src/assets/style/default/lib/margin.less new file mode 100644 index 0000000..bdc8235 --- /dev/null +++ b/web-react/src/assets/style/default/lib/margin.less @@ -0,0 +1,68 @@ +@import (reference) '../extend.less'; +@margin-padding-position: ~'', ~'-top', ~'-left', ~'-right', ~'-bottom'; +@margin-padding-position-name: ~'', ~'t', ~'l', ~'r', ~'b'; + +.margin-padding (@i) when (@i <=length(@margin-padding-position)) { + @position: extract(@margin-padding-position, @i); + @name: extract(@margin-padding-position-name, @i); + + .m@{name}-xl { + margin@{position}: @padding-xl !important; + } + + .m@{name}-lg { + margin@{position}: @padding-lg !important; + } + + .m@{name}-md { + margin@{position}: @padding-md !important; + } + + .m@{name}-sm { + margin@{position}: @padding-sm !important; + } + + .m@{name}-xs { + margin@{position}: @padding-xs !important; + } + + .m@{name}-xxs { + margin@{position}: @padding-xxs !important; + } + + .p@{name}-xl { + padding@{position}: @padding-xl !important; + } + + .p@{name}-lg { + padding@{position}: @padding-lg !important; + } + + .p@{name}-md { + padding@{position}: @padding-md !important; + } + + .p@{name}-sm { + padding@{position}: @padding-sm !important; + } + + .p@{name}-xs { + padding@{position}: @padding-xs !important; + } + + .p@{name}-xxs { + padding@{position}: @padding-xxs !important; + } + + .m@{name}-none { + margin@{position}: 0 !important; + } + + .p@{name}-none { + padding@{position}: 0 !important; + } + + .margin-padding(@i + 1); +} + +.margin-padding(1); \ No newline at end of file diff --git a/web-react/src/assets/style/default/lib/modal.less b/web-react/src/assets/style/default/lib/modal.less new file mode 100644 index 0000000..8c9c850 --- /dev/null +++ b/web-react/src/assets/style/default/lib/modal.less @@ -0,0 +1,38 @@ +@import (reference) '../extend.less'; +.ant-modal-content { + background-color: fade(@primary-color, 50%); + + backdrop-filter: blur(5px); +} +.ant-modal-header { + padding: @padding-sm @padding-md; + + border-bottom: 0; + background-color: transparent; +} +.ant-modal-title { + color: fade(@white, 85%); +} +.ant-modal-body { + background-color: @component-background; +} +.ant-modal-footer { + background-color: @component-background; +} +.ant-modal-close { + top: 10px; + right: 10px; + + color: fade(@white, 75%); + background-color: @error-color; + &:hover, + &:focus { + color: @white; + } +} +.ant-modal-close-x { + line-height: 26px; + + width: 26px; + height: 26px; +} diff --git a/web-react/src/assets/style/default/lib/page.less b/web-react/src/assets/style/default/lib/page.less new file mode 100644 index 0000000..bda6aa4 --- /dev/null +++ b/web-react/src/assets/style/default/lib/page.less @@ -0,0 +1,8 @@ +@import (reference) '../extend.less'; +.yo-page { + &--header { + padding: @padding-md 0; + + background-color: @white; + } +} diff --git a/web-react/src/assets/style/default/lib/radio.less b/web-react/src/assets/style/default/lib/radio.less new file mode 100644 index 0000000..ab0b99f --- /dev/null +++ b/web-react/src/assets/style/default/lib/radio.less @@ -0,0 +1,7 @@ +@import (reference) '../extend.less'; +.ant-radio-button-wrapper-checked { + &:not(.ant-radio-button-wrapper-disabled), + &:not(.ant-radio-button-wrapper-disabled):hover { + box-shadow: none; + } +} diff --git a/web-react/src/assets/style/lib/scrollbar.less b/web-react/src/assets/style/default/lib/scrollbar.less similarity index 100% rename from web-react/src/assets/style/lib/scrollbar.less rename to web-react/src/assets/style/default/lib/scrollbar.less diff --git a/web-react/src/assets/style/default/lib/select.less b/web-react/src/assets/style/default/lib/select.less new file mode 100644 index 0000000..5f80810 --- /dev/null +++ b/web-react/src/assets/style/default/lib/select.less @@ -0,0 +1,6 @@ +@import (reference) '../extend.less'; +.ant-select-arrow { + .anticon-down { + transform: scaleY(.75); + } +} diff --git a/web-react/src/assets/style/lib/table.less b/web-react/src/assets/style/default/lib/table.less similarity index 98% rename from web-react/src/assets/style/lib/table.less rename to web-react/src/assets/style/default/lib/table.less index 6ed273f..48fbda4 100644 --- a/web-react/src/assets/style/lib/table.less +++ b/web-react/src/assets/style/default/lib/table.less @@ -228,7 +228,7 @@ width: 300px; padding: @padding-xs @padding-sm; - background-color: @white; + background-color: @card-background; } } } diff --git a/web-react/src/assets/style/default/lib/text-color.less b/web-react/src/assets/style/default/lib/text-color.less new file mode 100644 index 0000000..7ba0e79 --- /dev/null +++ b/web-react/src/assets/style/default/lib/text-color.less @@ -0,0 +1,35 @@ +@import (reference) '../extend.less'; +.text-primary { + color: @primary-color; +} +.text-info { + color: @info-color; +} +.text-success { + color: @success-color; +} +.text-processing { + color: @processing-color; +} +.text-error, +.text-danger { + color: @error-color; +} +.text-highlight { + color: @highlight-color; +} +.text-warning { + color: @warning-color; +} +.text-gray { + color: fade(@black, 50%); +} +.text-normal { + color: fade(@black, 30%); +} +.text-white { + color: @white; +} +.text-black { + color: @black; +} diff --git a/web-react/src/assets/style/lib/tree-layout.less b/web-react/src/assets/style/default/lib/tree-layout.less similarity index 87% rename from web-react/src/assets/style/lib/tree-layout.less rename to web-react/src/assets/style/default/lib/tree-layout.less index a54090a..5140cea 100644 --- a/web-react/src/assets/style/lib/tree-layout.less +++ b/web-react/src/assets/style/default/lib/tree-layout.less @@ -1,4 +1,5 @@ @import (reference) '../extend.less'; +@import (reference) './text-color.less'; .yo-tree-layout { position: absolute; top: 0; @@ -7,11 +8,11 @@ width: 100%; height: 100%; .ant-layout-sider { - background-color: @white; + background-color: @component-background; .ant-layout-header { height: @layout-header-height - 20px; - background-color: @white; + background-color: @component-background; .header-actions { .ant-input-search { margin: (@layout-header-height - 20px - 32px) / 2 @padding-md; @@ -64,7 +65,7 @@ width: 5px; height: 5px; - background-color: @white; + background-color: @component-background; } &::-webkit-scrollbar-thumb { background-color: transparent; @@ -77,6 +78,6 @@ } } .ant-tree { - color: fade(@black, 60%); + .text-gray(); } } diff --git a/web-react/src/assets/style/default/lib/upload.less b/web-react/src/assets/style/default/lib/upload.less new file mode 100644 index 0000000..a2aa434 --- /dev/null +++ b/web-react/src/assets/style/default/lib/upload.less @@ -0,0 +1,29 @@ +@import (reference) '../extend.less'; +.ant-upload-list-text { + display: flex; + flex-wrap: wrap; + .ant-upload-list-item { + height: auto; + margin-right: @padding-xs; + } + .ant-upload-list-item-info { + position: relative; + + padding: @padding-xxs @padding-xs; + + border: @border-width-base @border-style-base @border-color-split; + .anticon-paper-clip { + top: 7.5px; + } + >span { + display: flex; + } + } + .ant-upload-list-item-card-actions { + position: relative; + + margin-left: @padding-xs; + + white-space: nowrap; + } +} diff --git a/web-react/src/assets/style/default/lib/visibility.less b/web-react/src/assets/style/default/lib/visibility.less new file mode 100644 index 0000000..3e16f62 --- /dev/null +++ b/web-react/src/assets/style/default/lib/visibility.less @@ -0,0 +1,46 @@ +@import (reference) '../extend.less'; +.hide { + visibility: hidden !important; +} +.hidden { + display: none !important; +} +.block { + display: block; +} +.inline-block { + display: inline-block; +} +.inline { + display: inline; +} +.inline-flex { + display: inline-flex; +} +.flex { + display: flex; +} +.ellipsis { + overflow: hidden; + + white-space: nowrap; + text-overflow: ellipsis; +} +.ellipsis-2 { + display: -webkit-box; + overflow: hidden; + -webkit-box-orient: vertical; + + text-overflow: ellipsis; + + -webkit-line-clamp: 2; +} +.ellipsis-3 { + display: -webkit-box; + overflow: hidden; + -webkit-box-orient: vertical; + + text-overflow: ellipsis; + + -webkit-line-clamp: 3; +} diff --git a/web-react/src/assets/style/default/lib/width-height.less b/web-react/src/assets/style/default/lib/width-height.less new file mode 100644 index 0000000..ae39ddc --- /dev/null +++ b/web-react/src/assets/style/default/lib/width-height.less @@ -0,0 +1,47 @@ +@import (reference) '../extend.less'; + +.width-height (@i) when (@i <=20) { + + @n : @i * 50; + @px : @n * 1px; + + .w-@{n} { + width: @px !important; + } + + .w-@{n}-min { + min-width: @px !important; + } + + .w-@{n}-max { + max-width: @px !important; + } + + .h-@{n} { + height: @px !important; + } + + .h-@{n}-min { + min-height: @px !important; + } + + .h-@{n}-max { + max-height: @px !important; + } + + .w-@{n}-p { + width: @n * 1% !important; + } + + .h-@{n}-p { + height: @n * 1% !important; + } + + .width-height(@i + 1); +} + +.width-height(0); + +.flex-1 { + flex: 1; +} \ No newline at end of file diff --git a/web-react/src/assets/style/default/main.less b/web-react/src/assets/style/default/main.less new file mode 100644 index 0000000..fa81795 --- /dev/null +++ b/web-react/src/assets/style/default/main.less @@ -0,0 +1,618 @@ +@import (reference) './extend.less'; +@import (reference) './lib/container.less'; +@import (reference) './lib/text-color.less'; +.yo-layout--spin { + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + background-color: @layout-header-background; + >.ant-spin-nested-loading { + height: 100%; + >div>.ant-spin { + max-height: none; + @-webkit-keyframes borderScale { + 0% { + border: 5px solid white; + } + 50% { + border: 25px solid transparent; + } + 100% { + border: 5px solid white; + } + } + @keyframes borderScale { + 0% { + border: 5px solid white; + } + 50% { + border: 25px solid transparent; + } + 100% { + border: 5px solid white; + } + } + .loader-container { + position: absolute; + top: 50%; + left: 50%; + + box-sizing: content-box; + width: 200px; + height: 200px; + margin: 0 auto; + margin-right: -50%; + + transform: translate(-50%, -50%); + -webkit-animation: borderScale 1s infinite ease-in-out; + animation: borderScale 1s infinite ease-in-out; + + color: white; + border: 5px solid transparent; + border-radius: 50%; + >p { + font-family: 'Raleway', sans-serif; + font-size: 2em; + font-weight: bold; + + position: absolute; + top: 50%; + left: 50%; + + margin-right: -50%; + + transform: translate(-50%, -50%); + } + } + } + >.ant-spin-container { + width: 100%; + height: 100%; + &.ant-spin-blur { + opacity: 0; + } + } + } +} +.ant-layout-header { + .header-actions { + display: flex; + .header-action { + display: inline-block; + + padding: 0 @padding-md; + + cursor: pointer; + transition: @animation-duration-slow; + transition-property: background-color; + .anticon { + font-size: @font-size-base + 6px; + + transition: @animation-duration-slow; + transition-property: color; + } + &:active { + box-shadow: inset 1px 1px 10px rgba(0, 0, 0, .05); + } + } + .ant-select-auto-complete { + margin: (@layout-header-height - 10px - 30px) / 2 @padding-md; + .ant-input-affix-wrapper { + border: 0; + background-color: fade(@white, 15%); + &:focus, + &-focused { + background-color: fade(@white, 30%); + } + .ant-input { + color: fade(@white, 85%); + background-color: transparent; + } + .ant-input-suffix { + .anticon { + color: fade(@white, 60%); + } + } + } + } + } + .user-container { + z-index: 10; + + width: 32px + @padding-sm * 2; + height: @layout-header-height - 24px; + margin: 2px 0; + + transition: @animation-duration-slow; + .user-container-inner { + position: relative; + + transition: @animation-duration-slow; + + border-radius: @border-radius-base; + } + .user { + &--base { + line-height: @layout-header-height - 24px; + + position: relative; + + display: flex; + overflow: hidden; + align-items: center; + + width: 100%; + height: @layout-header-height - 24px; + padding: 0 @padding-sm; + + transition: @animation-duration-slow; + } + &--avatar { + box-shadow: 0 0 0 2px @white; + } + } + } +} +.ant-layout-content { + position: relative; + + overflow-y: auto; + >.yo-tab-external-mount { + position: absolute; + top: 0; + left: 0; + bottom: 0; + + display: flex; + flex-direction: column; + + width: 100%; + >.ant-tabs { + z-index: 5; + + overflow: visible; + >.ant-tabs-nav { + margin-bottom: 0; + + border-bottom: 0; + background-color: @card-background; + box-shadow: 0 2px 12px fade(@black, 8%); + &::before { + content: none; + } + .ant-tabs-nav-container { + height: 30px; + margin-bottom: 0; + } + .ant-tabs-tab { + line-height: 30px; + + height: 30px; + margin-right: 0; + padding: 0; + + transition: none; + + border: 0; + background-color: transparent; + &:hover { + color: @black; + } + .ant-tabs-tab-btn { + transition: none; + } + &.ant-tabs-tab-active { + border-color: darken(@primary-color, 10%); + background-color: @primary-color; + .ant-tabs-tab-btn { + color: @white; + } + .ant-tabs-tab-remove { + color: fade(@white, 70%); + &:hover { + color: @white; + } + } + } + .yo-layout-tab-subtitle { + line-height: 1; + + display: inline-block; + overflow: hidden; + + max-width: 150px; + + transform: translateY(1px); + white-space: nowrap; + text-overflow: ellipsis; + + opacity: .75; + } + +.ant-tabs-tab { + margin-left: 0; + &::before { + position: absolute; + left: -.5px; + + width: 1px; + height: 24px; + + content: ''; + transform: scaleX(.5); + + background: linear-gradient(transparent, fade(@black, 30%), transparent); + } + } + .ant-dropdown-trigger { + padding: 0 @padding-md * 2 0 @padding-md; + } + .ant-tabs-tab-unclosable { + .ant-dropdown-trigger { + padding: 0 @padding-lg 0 @padding-md; + } + } + .ant-tabs-tab-remove { + line-height: 28px; + + position: absolute; + top: 0; + right: 0; + + margin: 0; + + transition: none; + } + } + .ant-tabs-nav-more { + padding: 5px @padding-md; + } + } + } + >.yo-tab-external-mount-content { + position: relative; + + height: 100%; + >.yo-tab-external-tabpane { + position: absolute; + top: 0; + left: 0; + + overflow-x: hidden; + overflow-y: auto; + + width: 100%; + height: 100%; + &.yo-tab-external-tabpane-inactive { + pointer-events: none; + + opacity: 0; + } + >iframe { + display: block; + + width: 100%; + height: 100%; + + border: 0; + } + } + } + } +} +.ant-layout-sider { + .ant-menu-inline { + border-right: 0; + } +} +.yo-nav { + padding-top: @padding-lg; + padding-bottom: @padding-lg; + &--row { + padding: 1px 0; + + column-gap: @padding-md; + column-count: 3; + } + &--col { + break-inside: avoid; + } + &--sub-item { + } + &--item-group { + font-size: @font-size-base; + line-height: 1.5; + + margin-bottom: @padding-xs; + padding-top: @padding-xs * 2; + + color: fade(@black, 35%); + border: @border-width-base @border-style-base transparent; + } + &--item { + font-size: @font-size-base; + line-height: 1.5; + + position: relative; + + margin-bottom: @padding-xs; + padding: @padding-xs @padding-sm; + + cursor: pointer; + transition: @animation-duration-fast; + + border: @border-width-base @border-style-base @border-color-split; + border-radius: @border-radius-base; + background-color: @white; + &:hover { + color: @white; + border-color: @primary-color; + background-color: @primary-color; + } + } +} +.yo-layout-sider { + height: 100%; + + background-color: @white; + .ant-layout-sider-children { + display: flex; + flex-direction: column; + } + .logo { + font-size: @font-size-lg * 1.5; + font-weight: 500; + line-height: @layout-header-height + 10px; + + z-index: 11; + + display: flex; + overflow: hidden; + align-items: center; + flex: 0 0 @layout-header-height + 10px; + + height: @layout-header-height + 10px; + padding: 0 @padding-md 0 @padding-lg; + + color: @white; + box-shadow: none; + img { + max-height: 100%; + } + span { + margin-left: @padding-sm; + + transition: @animation-duration-slow; + transition-property: opacity; + } + } + &.ant-layout-sider-collapsed { + .logo { + span { + opacity: 0; + } + } + } + .yo-sider-nav { + position: relative; + z-index: 10; + + flex: 1 1 100%; + + box-shadow: 2px 0 8px fade(@black, 25%); + &--app { + font-size: @font-size-sm; + + margin-top: @padding-sm; + padding: 0 @padding-md; + +.text-gray(); + } + } + .swiper-container { + position: absolute; + top: 0; + left: 0; + bottom: 0; + + width: 100%; + .swiper-scrollbar { + transition: @animation-duration-slow; + transition-property: opacity; + + opacity: 0; + } + .swiper-scrollbar-drag { + background-color: fade(@white, 30%); + } + &:hover { + .swiper-scrollbar { + opacity: 1; + } + } + } + .swiper-slide { + height: auto; + min-height: 100%; + >.ant-spin-nested-loading { + height: 100%; + .ant-spin-blur { + &::after { + opacity: 0; + } + } + } + } +} +.yo-layout--left-menu, +.yo-layout--right-menu { + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + .ant-layout-header { + line-height: @layout-header-height - 20px; + + z-index: 6; + + height: @layout-header-height - 20px; + padding: 0; + + background-color: @white; + >section { + display: flex; + justify-content: space-between; + } + .header-actions { + .header-action { + line-height: @layout-header-height - 16px; + + height: @layout-header-height - 20px; + .anticon { + color: fade(@black, 35%); + } + &:hover { + background-color: fade(@black, 5%); + .anticon { + color: @icon-color-hover; + } + } + } + } + } + >section { + >.ant-layout-sider { + .yo-layout-sider(); + } + } +} +.yo-layout--top-nav { + position: absolute; + top: 0; + left: 0; + + display: flex; + flex-direction: column; + + width: 100%; + height: 100%; + + @layout-header-height: 54px; + .ant-layout-header { + line-height: @layout-header-height; + + z-index: 11; + + flex: 0 0 @layout-header-height; + + height: @layout-header-height; + padding: 0; + + background-color: @layout-header-background; + section { + display: flex; + justify-content: space-between; + + height: 100%; + } + .header-actions { + .header-action { + .anticon { + color: fade(@white, 60%); + } + &:hover { + background-color: fade(@white, 20%); + .anticon { + color: @white; + } + } + } + } + .user-container { + margin: (@layout-header-height - 40px) / 2 0; + } + .logo { + font-size: @font-size-lg * 1.5; + font-weight: 500; + line-height: @layout-header-height - 10px; + + display: flex; + overflow: hidden; + align-items: center; + + height: @layout-header-height 10px; + margin: 5px @padding-lg 5px 0; + + color: @white; + img { + max-height: 100%; + } + span { + margin-left: @padding-sm; + } + } + .ant-menu-horizontal { + line-height: @layout-header-height; + + border-bottom: 0; + >.ant-menu-submenu { + top: 0; + + border-bottom: 0; + } + } + .header-actions { + .header-action { + line-height: @layout-header-height - 16px; + + margin: 10px 0; + } + } + } + &--container { + .ant-layout-header { + .ant-menu-horizontal { + width: 400px; + } + } + .ant-layout-content { + .yo-tab-external-mount { + >.ant-tabs { + >.ant-tabs-bar { + .ant-tabs-nav-container { + width: @container-width - @padding-md * 2; + margin: 0 auto; + } + } + } + } + } + } + &--container-fluid { + .ant-layout-header { + .ant-menu-horizontal { + width: 800px; + } + @media (max-width: 1400px) { + .ant-menu-horizontal { + width: 600px; + } + } + } + } +} +.yo-user-popover { + width: 280px; + padding-top: 0; + .ant-popover-arrow { + display: none; + } + .ant-popover-inner-content { + padding: 0; + } +} diff --git a/web-react/src/assets/style/default/pages/account-base.less b/web-react/src/assets/style/default/pages/account-base.less new file mode 100644 index 0000000..6ec0db8 --- /dev/null +++ b/web-react/src/assets/style/default/pages/account-base.less @@ -0,0 +1,51 @@ +@import (reference) '../extend.less'; +.yo-avatar-info { + position: relative; + + overflow: hidden; + + width: 128px; + margin: 0 auto; + + border-radius: 50%; + &--cover { + font-size: @font-size-lg * 2; + + position: absolute; + top: 0; + left: 0; + + display: flex; + align-items: center; + justify-content: center; + + width: 100%; + height: 100%; + + cursor: pointer; + transition: @animation-duration-slow; + + opacity: 0; + color: @white; + background-color: fade(@black, 50%); + &:hover { + opacity: 1; + } + } +} +.yo-avatar-cropper { + overflow: hidden; + + border-radius: @border-radius-base; + background-color: #ccc; +} +.yo-avatar-preview { + overflow: hidden; + + width: 200px; + height: 200px; + margin: 0 auto; + + border-radius: 50%; + background: #ccc; +} diff --git a/web-react/src/assets/style/default/pages/home.less b/web-react/src/assets/style/default/pages/home.less new file mode 100644 index 0000000..e6b1a5f --- /dev/null +++ b/web-react/src/assets/style/default/pages/home.less @@ -0,0 +1,42 @@ +@import (reference) '../extend.less'; +.home-header { + margin-bottom: @padding-md; + padding: @padding-lg 0; + + background-color: @component-background; +} +.home-header-row { + display: flex; +} +.home-header-content { + margin-left: @padding-lg; + h4 { + span { + color: @primary-color; + } + } + p { + margin: 0; + } +} +.home-container { + .ant-card-meta-title { + font-size: @font-size-base + 1px; + + display: -webkit-box; + -webkit-box-orient: vertical; + + height: 42px; + + white-space: normal; + + -webkit-line-clamp: 2; + } + .ant-card-meta-description { + .ant-row { + line-height: 24px; + + height: 24px; + } + } +} diff --git a/web-react/src/assets/style/default/pages/index.less b/web-react/src/assets/style/default/pages/index.less new file mode 100644 index 0000000..7927e7a --- /dev/null +++ b/web-react/src/assets/style/default/pages/index.less @@ -0,0 +1,3 @@ +@import './login.less'; +@import './home.less'; +@import './account-base.less'; diff --git a/web-react/src/assets/style/default/pages/login.less b/web-react/src/assets/style/default/pages/login.less new file mode 100644 index 0000000..b2e8e8e --- /dev/null +++ b/web-react/src/assets/style/default/pages/login.less @@ -0,0 +1,86 @@ +@import (reference) '../extend.less'; +.yo-login { + position: fixed; + top: 0; + left: 0; + + width: 100%; + height: 100%; + >img { + display: block; + + width: 100%; + height: 100%; + + object-fit: cover; + } + &::before { + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + content: ''; + + background: fade(@black, 30%) url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABZJREFUeNpiMLJ0+w8EDIwgAgQAAgwAUdAHrAFSJ6cAAAAASUVORK5CYII=); + } + &--placeholder { + position: absolute; + top: 50%; + left: 0; + + width: 100%; + height: 0; + .container-sm { + display: flex; + align-items: center; + justify-content: flex-end; + + height: 0; + } + } + .ant-form { + width: 300px; + padding: @padding-lg; + + border-radius: @border-radius-base + 2px; + background: linear-gradient(45deg, @white, fade(@white, 80%)); + } + .ant-form-item { + margin-bottom: 0; + } + .ant-form-item-label { + padding: @padding-xs 0 0 !important; + + transition: @animation-duration-base; + transform: translate(0); + >label { + font-weight: normal !important; + + color: fade(@black, 40%); + } + } + &--label { + .ant-form-item-label { + transform: translate(11px, 28px); + } + } + .ant-input, + .ant-input-affix-wrapper { + color: fade(@black, 85%); + border-width: 0 0 @border-width-base 0 !important; + border-color: fade(@black, 10%); + background-color: transparent; + } + .ant-input:hover, + .ant-input:focus, + .ant-input-affix-wrapper:not(.ant-input-affix-wrapper-disabled):hover, + .ant-input-affix-wrapper:focus, + .ant-input-affix-wrapper-focused { + border-width: 0 0 @border-width-base 0 !important; + border-color: @primary-color; + box-shadow: none !important; + } +} diff --git a/web-react/src/assets/style/default/public.less b/web-react/src/assets/style/default/public.less new file mode 100644 index 0000000..16a4aed --- /dev/null +++ b/web-react/src/assets/style/default/public.less @@ -0,0 +1,45 @@ +@import (reference) './extend.less'; +.yo-map { + &-container { + position: relative; + + padding: @padding-sm; + + border: @border-width-base @border-style-base @border-color-split; + border-radius: @border-radius-base; + background-color: @component-background; + .amap-icon { + img { + width: 25px; + } + } + } + &--search { + position: absolute; + top: @padding-md; + left: @padding-md; + z-index: 20; + + width: 25%; + min-width: 300px; + + background-color: @component-background; + box-shadow: @box-shadow-base; + } +} +.yo-adorn { + &--house-top { + height: 65px; + + background: url('~assets/image/adorn/house-top-01.png') no-repeat bottom right; + } +} +a.link-gray { + color: fade(@black, 50%); + &:hover { + color: @link-hover-color; + } + &:active { + color: @link-active-color; + } +} diff --git a/web-react/src/assets/style/default/theme/README.md b/web-react/src/assets/style/default/theme/README.md new file mode 100644 index 0000000..d6f8b27 --- /dev/null +++ b/web-react/src/assets/style/default/theme/README.md @@ -0,0 +1 @@ +/** 在此文件夹中添加控制主题颜色的less文件 **/ \ No newline at end of file diff --git a/web-react/src/assets/style/theme/primary.less b/web-react/src/assets/style/default/theme/primary.less similarity index 81% rename from web-react/src/assets/style/theme/primary.less rename to web-react/src/assets/style/default/theme/primary.less index 3d4f9b8..5b6f5a8 100644 --- a/web-react/src/assets/style/theme/primary.less +++ b/web-react/src/assets/style/default/theme/primary.less @@ -1,4 +1,4 @@ -@import '../app.less'; +@import '../index.less'; @primary-color: #007bff; @font-size-base: 13px; @border-radius-base: 0; diff --git a/web-react/src/assets/style/frame/dark.less b/web-react/src/assets/style/frame/dark.less deleted file mode 100644 index 19da8cd..0000000 --- a/web-react/src/assets/style/frame/dark.less +++ /dev/null @@ -1,13 +0,0 @@ -@import (reference) '../main.less'; -@layout-header-background: #1c2127; -.dark { - .main(@nav-background: @layout-header-background; - @nav-box-shadow-color: fade(@black, 25%); - @nav-scrollbar-background: fade(@white, 50%); - @nav-app-color: fade(@white, 35%); - @logo-color: @white; - @logo-box-shadow: none; - @header-action-color: fade(@white, 60%); - @header-action-hover-color: @white; - @header-action-hover-background: fade(@white, 20%)); -} diff --git a/web-react/src/assets/style/frame/light.less b/web-react/src/assets/style/frame/light.less deleted file mode 100644 index ea9fb10..0000000 --- a/web-react/src/assets/style/frame/light.less +++ /dev/null @@ -1,12 +0,0 @@ -@import (reference) '../main.less'; -.light { - .main(@nav-background: @white; - @nav-box-shadow-color: fade(@black, 5%); - @nav-scrollbar-background: fade(@black, 30%); - @nav-app-color: fade(@black, 35%); - @logo-color: @black; - @logo-box-shadow: inset -1px -1px 1px @border-color-split; - @header-action-color: fade(@black, 35%); - @header-action-hover-color: @icon-color-hover; - @header-action-hover-background: fade(@black, 5%)); -} diff --git a/web-react/src/assets/style/main.less b/web-react/src/assets/style/main.less deleted file mode 100644 index 3abb0d5..0000000 --- a/web-react/src/assets/style/main.less +++ /dev/null @@ -1,628 +0,0 @@ -@import (reference) './extend.less'; -@import (reference) './lib/container.less'; - -.main(@nav-background: @layout-header-background, - @nav-box-shadow-color: fade(@black, 25%), - @nav-scrollbar-background: fade(@white, 30%), - @nav-app-color: fade(@white, 35%), - @logo-color: @white, - @logo-box-shadow: none, - @header-action-color: fade(@white, 60%), - @header-action-hover-color: @white, - @header-action-hover-background: fade(@white, 20%)) { - .yo-layout--spin { - position: absolute; - top: 0; - left: 0; - - width: 100%; - height: 100%; - - background-color: @layout-header-background; - >.ant-spin-nested-loading { - height: 100%; - >div>.ant-spin { - max-height: none; - @-webkit-keyframes borderScale { - 0% { - border: 5px solid white; - } - 50% { - border: 25px solid transparent; - } - 100% { - border: 5px solid white; - } - } - @keyframes borderScale { - 0% { - border: 5px solid white; - } - 50% { - border: 25px solid transparent; - } - 100% { - border: 5px solid white; - } - } - .loader-container { - position: absolute; - top: 50%; - left: 50%; - - box-sizing: content-box; - width: 200px; - height: 200px; - margin: 0 auto; - margin-right: -50%; - - transform: translate(-50%, -50%); - -webkit-animation: borderScale 1s infinite ease-in-out; - animation: borderScale 1s infinite ease-in-out; - - color: white; - border: 5px solid transparent; - border-radius: 50%; - >p { - font-family: 'Raleway', sans-serif; - font-size: 2em; - font-weight: bold; - - position: absolute; - top: 50%; - left: 50%; - - margin-right: -50%; - - transform: translate(-50%, -50%); - } - } - } - >.ant-spin-container { - width: 100%; - height: 100%; - &.ant-spin-blur { - opacity: 0; - } - } - } - } - .ant-layout-header { - .header-actions { - display: flex; - .header-action { - display: inline-block; - - padding: 0 @padding-md; - - cursor: pointer; - transition: @animation-duration-slow; - transition-property: background-color; - .anticon { - font-size: @font-size-base + 6px; - - transition: @animation-duration-slow; - transition-property: color; - } - &:active { - box-shadow: inset 1px 1px 10px rgba(0, 0, 0, .05); - } - } - .ant-select-auto-complete { - margin: (@layout-header-height - 10px - 30px) / 2 @padding-md; - .ant-input-affix-wrapper { - border: 0; - background-color: fade(@white, 15%); - &:focus, - &-focused { - background-color: fade(@white, 30%); - } - .ant-input { - color: fade(@white, 85%); - background-color: transparent; - } - .ant-input-suffix { - .anticon { - color: fade(@white, 60%); - } - } - } - } - } - .user-container { - z-index: 10; - - width: 32px + @padding-sm * 2; - height: @layout-header-height - 24px; - margin: 2px 0; - - transition: @animation-duration-slow; - .user-container-inner { - position: relative; - - transition: @animation-duration-slow; - - border-radius: @border-radius-base; - } - .user { - &--base { - line-height: @layout-header-height - 24px; - - position: relative; - - display: flex; - overflow: hidden; - align-items: center; - - width: 100%; - height: @layout-header-height - 24px; - padding: 0 @padding-sm; - - transition: @animation-duration-slow; - } - &--avatar { - box-shadow: 0 0 0 2px @white; - } - } - } - } - .ant-layout-content { - position: relative; - - overflow-y: auto; - >.yo-tab-external-mount { - position: absolute; - top: 0; - left: 0; - bottom: 0; - - display: flex; - flex-direction: column; - - width: 100%; - >.ant-tabs { - z-index: 5; - - overflow: visible; - >.ant-tabs-nav { - margin-bottom: 0; - - border-bottom: 0; - background-color: @white; - box-shadow: 0 2px 12px fade(@black, 8%); - &::before { - content: none; - } - .ant-tabs-nav-container { - height: 30px; - margin-bottom: 0; - } - .ant-tabs-tab { - line-height: 30px; - - height: 30px; - margin-right: 0; - padding: 0; - - transition: none; - - border: 0; - background-color: transparent; - &:hover { - color: @black; - } - .ant-tabs-tab-btn { - transition: none; - } - &.ant-tabs-tab-active { - border-color: darken(@primary-color, 10%); - background-color: @primary-color; - .ant-tabs-tab-btn { - color: @white; - } - .ant-tabs-tab-remove { - color: fade(@white, 70%); - &:hover { - color: @white; - } - } - } - .yo-layout-tab-subtitle { - line-height: 1; - - display: inline-block; - overflow: hidden; - - max-width: 150px; - - transform: translateY(1px); - white-space: nowrap; - text-overflow: ellipsis; - - opacity: .75; - } - +.ant-tabs-tab { - margin-left: 0; - &::before { - position: absolute; - left: -.5px; - - width: 1px; - height: 24px; - - content: ''; - transform: scaleX(.5); - - background: linear-gradient(transparent, fade(@black, 30%), transparent); - } - } - .ant-dropdown-trigger { - padding: 0 @padding-md * 2 0 @padding-md; - } - .ant-tabs-tab-unclosable { - .ant-dropdown-trigger { - padding: 0 @padding-lg 0 @padding-md; - } - } - .ant-tabs-tab-remove { - line-height: 28px; - - position: absolute; - top: 0; - right: 0; - - margin: 0; - - transition: none; - } - } - .ant-tabs-nav-more { - padding: 5px @padding-md; - } - } - } - >.yo-tab-external-mount-content { - position: relative; - - height: 100%; - >.yo-tab-external-tabpane { - position: absolute; - top: 0; - left: 0; - - overflow-x: hidden; - overflow-y: auto; - - width: 100%; - height: 100%; - &.yo-tab-external-tabpane-inactive { - pointer-events: none; - - opacity: 0; - } - >iframe { - display: block; - - width: 100%; - height: 100%; - - border: 0; - } - } - } - } - } - .ant-layout-sider { - .ant-menu-inline { - border-right: 0; - } - } - .yo-nav { - padding-top: @padding-lg; - padding-bottom: @padding-lg; - &--row { - padding: 1px 0; - - column-gap: @padding-md; - column-count: 3; - } - &--col { - break-inside: avoid; - } - &--sub-item { - } - &--item-group { - font-size: @font-size-base; - line-height: 1.5; - - margin-bottom: @padding-xs; - padding-top: @padding-xs * 2; - - color: fade(@black, 35%); - border: @border-width-base @border-style-base transparent; - } - &--item { - font-size: @font-size-base; - line-height: 1.5; - - position: relative; - - margin-bottom: @padding-xs; - padding: @padding-xs @padding-sm; - - cursor: pointer; - transition: @animation-duration-fast; - - border: @border-width-base @border-style-base @border-color-split; - border-radius: @border-radius-base; - background-color: @white; - &:hover { - color: @white; - border-color: @primary-color; - background-color: @primary-color; - } - } - } - .yo-layout-sider { - height: 100%; - - background-color: @nav-background; - .ant-layout-sider-children { - display: flex; - flex-direction: column; - } - .logo { - font-size: @font-size-lg * 1.5; - font-weight: 500; - line-height: @layout-header-height + 10px; - - z-index: 11; - - display: flex; - overflow: hidden; - align-items: center; - flex: 0 0 @layout-header-height + 10px; - - height: @layout-header-height + 10px; - padding: 0 @padding-md 0 @padding-lg; - - color: @logo-color; - box-shadow: @logo-box-shadow; - img { - max-height: 100%; - } - span { - margin-left: @padding-sm; - - transition: @animation-duration-slow; - transition-property: opacity; - } - } - &.ant-layout-sider-collapsed { - .logo { - span { - opacity: 0; - } - } - } - .yo-sider-nav { - position: relative; - z-index: 10; - - flex: 1 1 100%; - - box-shadow: 2px 0 8px @nav-box-shadow-color; - &--app { - font-size: @font-size-sm; - - margin-top: @padding-sm; - padding: 0 @padding-md; - - color: @nav-app-color; - } - } - .swiper-container { - position: absolute; - top: 0; - left: 0; - bottom: 0; - - width: 100%; - .swiper-scrollbar { - transition: @animation-duration-slow; - transition-property: opacity; - - opacity: 0; - } - .swiper-scrollbar-drag { - background-color: @nav-scrollbar-background; - } - &:hover { - .swiper-scrollbar { - opacity: 1; - } - } - } - .swiper-slide { - height: auto; - min-height: 100%; - >.ant-spin-nested-loading { - height: 100%; - .ant-spin-blur { - &::after { - opacity: 0; - } - } - } - } - } - .yo-layout--left-menu, - .yo-layout--right-menu { - position: absolute; - top: 0; - left: 0; - - width: 100%; - height: 100%; - .ant-layout-header { - line-height: @layout-header-height - 20px; - - z-index: 6; - - height: @layout-header-height - 20px; - padding: 0; - - background-color: @white; - >section { - display: flex; - justify-content: space-between; - } - .header-actions { - .header-action { - line-height: @layout-header-height - 16px; - - height: @layout-header-height - 20px; - .anticon { - color: fade(@black, 35%); - } - &:hover { - background-color: fade(@black, 5%); - .anticon { - color: @icon-color-hover; - } - } - } - } - } - >section { - >.ant-layout-sider { - .yo-layout-sider(); - } - } - } - .yo-layout--top-nav { - position: absolute; - top: 0; - left: 0; - - display: flex; - flex-direction: column; - - width: 100%; - height: 100%; - - @layout-header-height: 54px; - .ant-layout-header { - line-height: @layout-header-height; - - z-index: 11; - - flex: 0 0 @layout-header-height; - - height: @layout-header-height; - padding: 0; - - background-color: @nav-background; - section { - display: flex; - justify-content: space-between; - - height: 100%; - } - .header-actions { - .header-action { - .anticon { - color: @header-action-color; - } - &:hover { - background-color: @header-action-hover-background; - .anticon { - color: @header-action-hover-color; - } - } - } - } - .user-container { - margin: (@layout-header-height - 40px) / 2 0; - } - .logo { - font-size: @font-size-lg * 1.5; - font-weight: 500; - line-height: @layout-header-height - 10px; - - display: flex; - overflow: hidden; - align-items: center; - - height: @layout-header-height 10px; - margin: 5px @padding-lg 5px 0; - - color: @logo-color; - img { - max-height: 100%; - } - span { - margin-left: @padding-sm; - } - } - .ant-menu-horizontal { - line-height: @layout-header-height; - - border-bottom: 0; - >.ant-menu-submenu { - top: 0; - - border-bottom: 0; - } - } - .header-actions { - .header-action { - line-height: @layout-header-height - 16px; - - margin: 10px 0; - } - } - } - &--container { - .ant-layout-header { - .ant-menu-horizontal { - width: 400px; - } - } - .ant-layout-content { - .yo-tab-external-mount { - >.ant-tabs { - >.ant-tabs-bar { - .ant-tabs-nav-container { - width: @container-width - @padding-md * 2; - margin: 0 auto; - } - } - } - } - } - } - &--container-fluid { - .ant-layout-header { - .ant-menu-horizontal { - width: 800px; - } - @media (max-width: 1400px) { - .ant-menu-horizontal { - width: 600px; - } - } - } - } - } -} -.yo-user-popover { - width: 280px; - padding-top: 0; - .ant-popover-arrow { - display: none; - } - .ant-popover-inner-content { - padding: 0; - } -} diff --git a/web-react/src/index.js b/web-react/src/index.js index 8c136cd..f63c526 100644 --- a/web-react/src/index.js +++ b/web-react/src/index.js @@ -5,10 +5,20 @@ import reportWebVitals from './reportWebVitals'; import { ConfigProvider } from 'antd' import { AntIcon } from 'components' +import { SETTING_KEY } from 'common/storage'; import zhCN from 'antd/lib/locale/zh_CN' import moment from 'moment' import 'moment/locale/zh-cn' -import './assets/style/app.less' + +const SETTING = JSON.parse(window.localStorage.getItem(SETTING_KEY)) || { + theme: 'default' +}; + +if (SETTING.theme === 'dark') { + require('./assets/style/dark/index.less') +} else { + require('./assets/style/default/index.less') +} moment.locale('zh-cn') @@ -34,7 +44,4 @@ ReactDOM.render( // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals -reportWebVitals(); - - -document.body.classList.add('yo-nav-theme--dark') \ No newline at end of file +reportWebVitals(); \ No newline at end of file diff --git a/web-react/src/pages/home/index.jsx b/web-react/src/pages/home/index.jsx index dc6292d..0d02873 100644 --- a/web-react/src/pages/home/index.jsx +++ b/web-react/src/pages/home/index.jsx @@ -4,7 +4,6 @@ import { isEqual } from 'lodash' import store from 'store' import { Container, Image, AntIcon } from 'components' import moment from 'moment' -import './index.less' import Statistics from './statistics' import Task from './task' @@ -17,9 +16,8 @@ const { getState, subscribe } = store const storePath = 'user' export default class index extends Component { - state = { - [storePath]: getState(storePath) + [storePath]: getState(storePath), } constructor(props) { @@ -47,22 +45,37 @@ export default class index extends Component {
- } type="avatar" /> + } + type="avatar" + />

- {moment().format('A')}好,{this.state.user.nickName || this.state.user.name},欢迎您登录系统! -

+ {moment().format('A')}好, + + {this.state.user.nickName || this.state.user.name} + + ,欢迎您登录系统! +
上次IP:{this.state.user.lastLoginIp} - 上次登录时间:{this.state.user.lastLoginTime} + + 上次登录时间:{this.state.user.lastLoginTime} +
- + 您有0封未读邮件,请尽快查收! diff --git a/web-react/src/pages/home/statistics.jsx b/web-react/src/pages/home/statistics.jsx index b8c6d5a..a28f01b 100644 --- a/web-react/src/pages/home/statistics.jsx +++ b/web-react/src/pages/home/statistics.jsx @@ -43,14 +43,14 @@ export default class statistics extends Component { > 当月活跃用户 - + } prefix={ - }> - + } + > diff --git a/web-react/src/pages/system/account/base.jsx b/web-react/src/pages/system/account/base.jsx index 7d7348b..298f2b4 100644 --- a/web-react/src/pages/system/account/base.jsx +++ b/web-react/src/pages/system/account/base.jsx @@ -5,7 +5,6 @@ import { Cropper } from 'react-cropper' import 'cropperjs/dist/cropper.css' import { BlobToFile } from 'util/file' -import './base.less' import { api } from 'common/api' export default class base extends Component { diff --git a/web-react/src/pages/system/dict/dictdata/form.jsx b/web-react/src/pages/system/dict/dictdata/form.jsx index 67ed191..50ce9d7 100644 --- a/web-react/src/pages/system/dict/dictdata/form.jsx +++ b/web-react/src/pages/system/dict/dictdata/form.jsx @@ -7,7 +7,6 @@ import MonacoEditor from 'react-monaco-editor' const initialValues = {} export default class form extends Component { - state = { // 加载状态 loading: true, @@ -32,7 +31,7 @@ export default class form extends Component { * 填充数据 * 可以在设置this.record之后对其作出数据结构调整 * [异步,必要] - * @param {*} params + * @param {*} params */ async fillData(params) { this.record = cloneDeep(params.record) @@ -45,7 +44,7 @@ export default class form extends Component { this.form.current.setFieldsValue(this.record) this.setState({ - loading: false + loading: false, }) } @@ -53,7 +52,7 @@ export default class form extends Component { * 获取数据 * 可以对postData进行数据结构调整 * [异步,必要] - * @returns + * @returns */ async getData() { const form = this.form.current @@ -66,11 +65,11 @@ export default class form extends Component { } //#region 从前段转换后端所需格式 try { - const code = JSON.parse(this.code.current.editor.getValue()); + const code = JSON.parse(this.code.current.editor.getValue()) if (code.constructor === Object) { - postData.extCode = JSON.stringify(code); + postData.extCode = JSON.stringify(code) } else { - throw new Error(0); + throw new Error(0) } } catch { Message.error('错误的JSON格式') @@ -85,18 +84,15 @@ export default class form extends Component { render() { return ( -
+ }>
diff --git a/web-react/src/store/reducer/layout.js b/web-react/src/store/reducer/layout.js index 1441e84..776fdc9 100644 --- a/web-react/src/store/reducer/layout.js +++ b/web-react/src/store/reducer/layout.js @@ -3,7 +3,8 @@ import { SIDER_BREAK_POINT } from "util/global" const defaultState = { siderCollapsed: false, - allowSiderCollapsed: true + allowSiderCollapsed: true, + theme: 'default' } const localStorageState = () => { @@ -36,6 +37,7 @@ const layout = (state = mergeState, action) => { window.localStorage.setItem(SETTING_KEY, JSON.stringify(_state)) return _state } + // 自动收起侧边 case 'AUTO_TOGGLE_COLLAPSED': { const _state = { @@ -45,6 +47,13 @@ const layout = (state = mergeState, action) => { } return _state } + // 切换主题 + case 'SET_THEME': + { + const _state = { ...state, theme: action.theme } + window.localStorage.setItem(SETTING_KEY, JSON.stringify(_state)) + return _state + } default: return state } diff --git a/web-react/src/views/login/index.jsx b/web-react/src/views/login/index.jsx index a431711..d7290aa 100644 --- a/web-react/src/views/login/index.jsx +++ b/web-react/src/views/login/index.jsx @@ -5,7 +5,6 @@ import { encryptByRSA } from 'util/rsa' import { RSA_PUBLIC_KEY } from 'util/global' import { api } from 'common/api' import { token } from 'common/token' -import './index.less' export default class index extends Component { state = { diff --git a/web-react/src/views/main/_layout/header/index.jsx b/web-react/src/views/main/_layout/header/index.jsx index ccf9f9d..796d6f1 100644 --- a/web-react/src/views/main/_layout/header/index.jsx +++ b/web-react/src/views/main/_layout/header/index.jsx @@ -33,7 +33,7 @@ export default class index extends Component { } render() { - const { allowSiderCollapsed } = this.state + const { allowSiderCollapsed, theme } = this.state return ( @@ -62,6 +62,21 @@ export default class index extends Component { + { + dispatch({ + type: 'SET_THEME', + theme: { dark: 'default', default: 'dark' }[theme], + }) + window.location.reload() + }} + > +
+
+
+
+