feat: theme
This commit is contained in:
parent
e523f7317b
commit
88b6bad25c
15
.stylelintrc.js
Normal file
15
.stylelintrc.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/** @type {import('stylelint').Config} */
|
||||||
|
export default {
|
||||||
|
plugins: ['stylelint-order'],
|
||||||
|
extends: [
|
||||||
|
'stylelint-config-standard',
|
||||||
|
'stylelint-config-standard-scss',
|
||||||
|
'stylelint-config-recommended-vue',
|
||||||
|
'stylelint-config-recess-order',
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
'font-family-name-quotes': 'always-where-required',
|
||||||
|
'font-family-no-missing-generic-family-keyword': [true, { ignoreFontFamilies: ['Roboto', 'SourceHanSansSC'] }],
|
||||||
|
'function-url-quotes': 'never',
|
||||||
|
},
|
||||||
|
};
|
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"plugins": ["stylelint-order"],
|
|
||||||
"extends": [
|
|
||||||
"stylelint-config-standard",
|
|
||||||
"stylelint-config-standard-scss",
|
|
||||||
"stylelint-config-recommended-vue",
|
|
||||||
"stylelint-config-recess-order"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"font-family-name-quotes": "always-where-required",
|
|
||||||
"function-url-quotes": "never"
|
|
||||||
}
|
|
||||||
}
|
|
1206
package-lock.json
generated
1206
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@ -32,12 +32,12 @@
|
|||||||
"globals": "^16.0.0",
|
"globals": "^16.0.0",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"sass-embedded": "^1.86.3",
|
"sass-embedded": "^1.86.3",
|
||||||
"stylelint": "^16.18.0",
|
"stylelint": "^16.19.1",
|
||||||
"stylelint-config-recess-order": "^6.0.0",
|
"stylelint-config-recess-order": "^5.1.1",
|
||||||
"stylelint-config-recommended-vue": "^1.6.0",
|
"stylelint-config-recommended-vue": "^1.6.0",
|
||||||
"stylelint-config-standard": "^38.0.0",
|
"stylelint-config-standard": "^36.0.1",
|
||||||
"stylelint-config-standard-scss": "^14.0.0",
|
"stylelint-config-standard-scss": "^13.1.0",
|
||||||
"stylelint-order": "^7.0.0",
|
"stylelint-order": "^6.0.4",
|
||||||
"typescript": "~5.7.2",
|
"typescript": "~5.7.2",
|
||||||
"typescript-eslint": "^8.30.1",
|
"typescript-eslint": "^8.30.1",
|
||||||
"unplugin-vue-components": "^28.5.0",
|
"unplugin-vue-components": "^28.5.0",
|
||||||
|
@ -4,7 +4,12 @@ import sTheme from '@core/theme.service';
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-config-provider :locale="sLocale.ant" :theme="sTheme.ant" :autoInsertSpaceInButton="false">
|
<a-config-provider
|
||||||
|
:locale="sLocale.ant"
|
||||||
|
:theme="sTheme.ant"
|
||||||
|
:autoInsertSpaceInButton="false"
|
||||||
|
:wave="{ disabled: true }"
|
||||||
|
>
|
||||||
<router-view />
|
<router-view />
|
||||||
</a-config-provider>
|
</a-config-provider>
|
||||||
</template>
|
</template>
|
||||||
|
94
src/ant.scss
94
src/ant.scss
@ -1,18 +1,84 @@
|
|||||||
// @use 'asset/themes/dark' as dark;
|
@use 'asset/themes/theme' as *;
|
||||||
// @use 'asset/themes/light' as light;
|
|
||||||
|
|
||||||
// $theme: dark;
|
@include themed {
|
||||||
|
.ant-btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
font: 400 14px/22px Roboto;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
// :root {
|
&.ant-btn-default {
|
||||||
// [theme='dark'] {
|
color: get-color(primary);
|
||||||
// $theme: dark !global;
|
background-color: get-color(141414);
|
||||||
// }
|
border-color: get-color(primary);
|
||||||
|
box-shadow: 0 2px 0 0 get-color(00000005);
|
||||||
|
}
|
||||||
|
|
||||||
// [theme='light'] {
|
&.ant-btn-primary {
|
||||||
// $theme: light !global;
|
font-weight: 500;
|
||||||
// }
|
color: get-color(141414);
|
||||||
// }
|
background-color: get-color(primary);
|
||||||
|
border-color: get-color(primary);
|
||||||
|
box-shadow: 0 2px 0 0 get-color(0000000a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// .ant-typography {
|
.ant-layout {
|
||||||
// color: #{$theme}.$text-1;
|
background-color: get-color(2a2c2c);
|
||||||
// }
|
|
||||||
|
& > .ant-layout-header {
|
||||||
|
line-height: unset;
|
||||||
|
background-color: get-color(242525);
|
||||||
|
box-shadow: 0 2px 8px 0 get-color(00000026);
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .ant-layout-sider {
|
||||||
|
background-color: get-color(36393a);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px 0 get-color(ffffff14);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-tabs {
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
& > .ant-tabs-nav {
|
||||||
|
margin: 0;
|
||||||
|
background-color: get-color(ffffff2e);
|
||||||
|
|
||||||
|
& > .ant-tabs-nav-wrap > .ant-tabs-nav-list {
|
||||||
|
& > .ant-tabs-tab {
|
||||||
|
padding: 14px 32px;
|
||||||
|
margin: 0;
|
||||||
|
font: 400 16px/20px Roboto;
|
||||||
|
color: get-color(ffffff73);
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
|
||||||
|
& > .ant-tabs-tab-btn {
|
||||||
|
color: inherit;
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ant-tabs-tab-active {
|
||||||
|
font-weight: 600;
|
||||||
|
color: get-color(primary);
|
||||||
|
background-color: get-color(36393a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .ant-tabs-ink-bar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-typography {
|
||||||
|
& > strong {
|
||||||
|
font: 500 16px/22px SourceHanSansSC;
|
||||||
|
color: get-color(ffffffd9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -54,6 +54,7 @@ export const EDITOR_CONFIG: Options = {
|
|||||||
maxScale: 4.01,
|
maxScale: 4.01,
|
||||||
scaleOff: 0.01,
|
scaleOff: 0.01,
|
||||||
defaultAnchors: [],
|
defaultAnchors: [],
|
||||||
|
globalAlpha: 0,
|
||||||
activeGlobalAlpha: 0,
|
activeGlobalAlpha: 0,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
lineHeight: 1.5,
|
lineHeight: 1.5,
|
||||||
|
BIN
src/assets/fonts/Roboto-Bold.ttf
Normal file
BIN
src/assets/fonts/Roboto-Bold.ttf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Roboto-Medium.ttf
Normal file
BIN
src/assets/fonts/Roboto-Medium.ttf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Roboto-Regular.ttf
Normal file
BIN
src/assets/fonts/Roboto-Regular.ttf
Normal file
Binary file not shown.
BIN
src/assets/fonts/SourceHanSansSC-Medium.otf
Normal file
BIN
src/assets/fonts/SourceHanSansSC-Medium.otf
Normal file
Binary file not shown.
25
src/assets/fonts/_font.scss
Normal file
25
src/assets/fonts/_font.scss
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// 谷歌Roboto字体
|
||||||
|
@font-face {
|
||||||
|
font-family: Roboto;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(./Roboto-Regular.otf) format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Roboto;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(./Roboto-Medium.otf) format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Roboto;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url(./Roboto-Bold.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 思源黑体
|
||||||
|
@font-face {
|
||||||
|
font-family: SourceHanSansSC;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(./SourceHanSansSC-Medium.otf) format('opentype');
|
||||||
|
}
|
16
src/assets/icons/_icon.scss
Normal file
16
src/assets/icons/_icon.scss
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
$icons: (edit upload);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
display: inline;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 1;
|
||||||
|
vertical-align: top;
|
||||||
|
|
||||||
|
@each $icon in $icons {
|
||||||
|
&.#{$icon} {
|
||||||
|
background: url(./#{$icon}.png) center / contain no-repeat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
src/assets/icons/edit.png
Normal file
BIN
src/assets/icons/edit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 749 B |
BIN
src/assets/icons/upload.png
Normal file
BIN
src/assets/icons/upload.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 543 B |
@ -1 +1,28 @@
|
|||||||
$text-1: #ffffffd9 !global;
|
$color: (
|
||||||
|
primary: #0dbb8a,
|
||||||
|
warning: #d89614,
|
||||||
|
111e1b: #111e1b,
|
||||||
|
|
||||||
|
141414: #141414,
|
||||||
|
595959: #595959,
|
||||||
|
00000005: #00000005,
|
||||||
|
0000000a: #0000000a,
|
||||||
|
00000026: #00000026,
|
||||||
|
|
||||||
|
000000: #000,
|
||||||
|
2a2c2c: #2a2c2c,
|
||||||
|
242525: #242525,
|
||||||
|
36393a: #36393a,
|
||||||
|
|
||||||
|
424242: #424242,
|
||||||
|
434343: #434343,
|
||||||
|
|
||||||
|
ffffff2e: #ffffff2e,
|
||||||
|
ffffff14: #ffffff14,
|
||||||
|
ffffff0a: #ffffff0a,
|
||||||
|
|
||||||
|
ffffffd9: #ffffffd9,
|
||||||
|
ffffffa6: #ffffffa6,
|
||||||
|
ffffff73: #ffffff73,
|
||||||
|
ffffff40: #ffffff40,
|
||||||
|
);
|
||||||
|
@ -1 +1,3 @@
|
|||||||
$text-1: #000000d9 !global;
|
$color: (
|
||||||
|
text-1: #000,
|
||||||
|
);
|
||||||
|
23
src/assets/themes/_theme.scss
Normal file
23
src/assets/themes/_theme.scss
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
@use 'sass:map';
|
||||||
|
@use './dark' as dark;
|
||||||
|
@use './light' as light;
|
||||||
|
|
||||||
|
$themes: (dark, light);
|
||||||
|
$theme-map: (
|
||||||
|
dark-color: dark.$color,
|
||||||
|
|
||||||
|
light-color: light.$color,
|
||||||
|
);
|
||||||
|
|
||||||
|
@mixin themed {
|
||||||
|
@each $theme in $themes {
|
||||||
|
$theme-color: map.get($theme-map, #{$theme}-color) !global;
|
||||||
|
:root[theme='#{$theme}'] {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@function get-color($key) {
|
||||||
|
@return map.get($theme-color, $key);
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"color": "#BFBFBF",
|
"color": "#BFBFBF",
|
||||||
"background": "#D9D9D9",
|
"background": "#2A2C2C",
|
||||||
"point-s": {
|
"point-s": {
|
||||||
"stroke": "#8C8C8C",
|
"stroke": "#8C8C8C",
|
||||||
"strokeActive": "#FCC947",
|
"strokeActive": "#FCC947",
|
||||||
@ -14,4 +14,4 @@
|
|||||||
"strokeActive": "#FCC947"
|
"strokeActive": "#FCC947"
|
||||||
},
|
},
|
||||||
"line": "#8C8C8C"
|
"line": "#8C8C8C"
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ const enum Mode {
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
editor: InjectionKey<ShallowRef<EditorService>>;
|
editor: InjectionKey<ShallowRef<EditorService>>;
|
||||||
|
editable?: boolean;
|
||||||
};
|
};
|
||||||
const props = defineProps<Props>();
|
const props = defineProps<Props>();
|
||||||
const editor = inject(props.editor)!;
|
const editor = inject(props.editor)!;
|
@ -2,7 +2,6 @@
|
|||||||
import type { RobotGroup } from '@api/robot';
|
import type { RobotGroup } from '@api/robot';
|
||||||
import { getSceneById } from '@api/scene';
|
import { getSceneById } from '@api/scene';
|
||||||
import { EditorService } from '@core/editor.service';
|
import { EditorService } from '@core/editor.service';
|
||||||
import { isEmpty } from 'lodash-es';
|
|
||||||
import { watch } from 'vue';
|
import { watch } from 'vue';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { onMounted, provide, shallowRef } from 'vue';
|
import { onMounted, provide, shallowRef } from 'vue';
|
||||||
@ -40,22 +39,40 @@ const editable = ref<boolean>(false);
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-layout class="full">
|
<a-layout class="full">
|
||||||
<a-layout-header class="ph-16" style="height: 64px">
|
<a-layout-header class="p-16" style="height: 64px">
|
||||||
<a-flex justify="space-between">
|
<a-flex justify="space-between" align="center">
|
||||||
<a-typography-text strong>{{ title }}</a-typography-text>
|
<a-typography-text strong>{{ title }}</a-typography-text>
|
||||||
|
<a-space align="center">
|
||||||
|
<a-button type="primary">
|
||||||
|
<i class="icon edit mr-2" />
|
||||||
|
<span>{{ $t('启用编辑器') }}</span>
|
||||||
|
</a-button>
|
||||||
|
<a-button>{{ $t('推送') }}</a-button>
|
||||||
|
<a-button>{{ $t('导入') }}</a-button>
|
||||||
|
<a-button>{{ $t('导出') }}</a-button>
|
||||||
|
</a-space>
|
||||||
</a-flex>
|
</a-flex>
|
||||||
</a-layout-header>
|
</a-layout-header>
|
||||||
|
|
||||||
<a-layout>
|
<a-layout class="p-16">
|
||||||
<a-layout-sider>
|
<a-layout-sider :width="320">
|
||||||
<RobotList v-if="editor" :editor="EDITOR_KEY" />
|
<a-tabs class="full" type="card">
|
||||||
|
<a-tab-pane key="1" :tab="$t('机器人')">
|
||||||
|
<RobotGroup v-if="editor" :editor="EDITOR_KEY" :editable="editable" />
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane key="2" :tab="$t('库区')">Content of Tab Pane 2</a-tab-pane>
|
||||||
|
<a-tab-pane key="3" :tab="$t('高级组')">Content of Tab Pane 3</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
</a-layout-sider>
|
</a-layout-sider>
|
||||||
<a-layout-content>
|
<a-layout-content>
|
||||||
<div ref="container" class="full"></div>
|
<div ref="container" class="editor-container full"></div>
|
||||||
</a-layout-content>
|
</a-layout-content>
|
||||||
<a-layout-sider>{{ $t('查询') }}</a-layout-sider>
|
|
||||||
</a-layout>
|
</a-layout>
|
||||||
</a-layout>
|
</a-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- <style scoped lang="scss"></style> -->
|
<style scoped lang="scss">
|
||||||
|
.editor-container {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
0
src/services/utils.ts
Normal file
0
src/services/utils.ts
Normal file
@ -1,4 +1,6 @@
|
|||||||
@use './ant';
|
@use './ant';
|
||||||
|
@use 'asset/icons/icon';
|
||||||
|
@use 'asset/fonts/font';
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user