diff --git a/packages/theme-generator/.editorconfig b/packages/theme-generator/.editorconfig new file mode 100644 index 00000000..d6811195 --- /dev/null +++ b/packages/theme-generator/.editorconfig @@ -0,0 +1,22 @@ +# EditorConfig 有助于在不同编辑器和 IDE 中维护一致的编码风格 +# 更多详情请见 https://editorconfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{js,jsx,ts,tsx,vue}] +indent_style = space +indent_size = 2 +max_line_length = 120 + +[*.{json,jsonc}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/packages/theme-generator/.eslintrc.js b/packages/theme-generator/.eslintrc.js index 31733bfd..855b10a6 100644 --- a/packages/theme-generator/.eslintrc.js +++ b/packages/theme-generator/.eslintrc.js @@ -2,12 +2,18 @@ const path = require('path'); module.exports = { root: true, - extends: ['plugin:vue/essential', './../../.eslintrc.js'], + extends: ['plugin:vue/recommended', './../../.eslintrc.js'], parserOptions: { parser: '@babel/eslint-parser', babelOptions: { configFile: path.resolve(__dirname, './babel.config.js'), }, + ecmaVersion: 2020, + }, + rules: { + 'vue/multi-word-component-names': 'off', + 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], }, - rules: {}, }; diff --git a/packages/theme-generator/.prettierrc.json b/packages/theme-generator/.prettierrc.json new file mode 100644 index 00000000..ed9d899e --- /dev/null +++ b/packages/theme-generator/.prettierrc.json @@ -0,0 +1,12 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "es5", + "bracketSpacing": true, + "arrowParens": "always", + "printWidth": 120, + "tabWidth": 2, + "useTabs": false, + "vueIndentScriptAndStyle": false, + "htmlWhitespaceSensitivity": "css" +} diff --git a/packages/theme-generator/babel.config.js b/packages/theme-generator/babel.config.js index 162a3ea9..078c0056 100644 --- a/packages/theme-generator/babel.config.js +++ b/packages/theme-generator/babel.config.js @@ -1,3 +1,3 @@ module.exports = { - presets: ["@vue/cli-plugin-babel/preset"], + presets: ['@vue/cli-plugin-babel/preset'], }; diff --git a/packages/theme-generator/package.json b/packages/theme-generator/package.json index c6e89edd..a8f3144c 100644 --- a/packages/theme-generator/package.json +++ b/packages/theme-generator/package.json @@ -7,7 +7,8 @@ "dev": "vue-cli-service serve", "build": "vue-cli-service build --target wc --inline-vue --name td-theme-generator src/Generator.vue", "build:watch": "vue-cli-service build --target wc --inline-vue --name td-theme-generator src/Generator.vue --watch", - "lint": "vue-cli-service lint" + "lint": "vue-cli-service lint", + "lint:fix": "vue-cli-service lint --fix" }, "main": "dist/td-theme-generator.js", "files": [ diff --git a/packages/theme-generator/src/Generator.vue b/packages/theme-generator/src/Generator.vue index 76a2f27f..a2c37fef 100644 --- a/packages/theme-generator/src/Generator.vue +++ b/packages/theme-generator/src/Generator.vue @@ -1,12 +1,12 @@ @@ -18,6 +18,9 @@ import { syncThemeToIframe, themeStore, } from '@/common/themes'; +import { COMP_SIZE_DEFAULT_VALUES, SIZE_DEFAULT_VALUES } from '@/size-panel/built-in/size-map'; + +const STYLE_LOCK_ID = '__web-components-size-lock__'; import FloatDock from './float-dock'; import PanelDrawer from './panel-drawer'; @@ -31,6 +34,7 @@ export default { props: { showSetting: { type: [Boolean, String], + default: false, }, device: { type: String, @@ -48,8 +52,22 @@ export default { initGeneratorVars(); applyTokenFromLocal(); syncThemeToIframe(this.device); + + this.initWebComponentsSizeProtection(); }, methods: { + initWebComponentsSizeProtection() { + let styleEl = document.getElementById(STYLE_LOCK_ID); + + if (!styleEl) { + styleEl = document.createElement('style'); + styleEl.id = STYLE_LOCK_ID; + document.head.appendChild(styleEl); + } + + const sizeVars = { ...SIZE_DEFAULT_VALUES, ...COMP_SIZE_DEFAULT_VALUES }; + styleEl.textContent = buildSizeVarsCSS(sizeVars); + }, handleTriggerVisible() { this.visible = true; }, @@ -61,6 +79,13 @@ export default { }, }, }; + +function buildSizeVarsCSS(sizeVars) { + const body = Object.entries(sizeVars) + .map(([key, val]) => ` ${key}: ${val} !important;`) + .join('\n'); + return `:root {\n${body}\n}`; +} diff --git a/packages/theme-generator/src/color-panel/components/ColorColumn/index.vue b/packages/theme-generator/src/color-panel/components/ColorColumn/index.vue index c134379c..9d5c10d9 100644 --- a/packages/theme-generator/src/color-panel/components/ColorColumn/index.vue +++ b/packages/theme-generator/src/color-panel/components/ColorColumn/index.vue @@ -35,11 +35,11 @@
-
+
{{ color.name.replace('--td-', '') }}
@@ -74,7 +74,7 @@ {{ type }}{{ color.idx }} {{ getTokenValue(color.name) }}
- +
@@ -91,12 +91,6 @@ import { getTokenValue, handleAttach } from '@/common/utils'; export default { name: 'ColorColumn', - props: { - type: String, - gradientStep: Number, - tokenMap: Array, - }, - emit: ['recoverGradation', 'changeGradation'], components: { TPopup, ColorPicker, @@ -105,6 +99,21 @@ export default { ErrorCircleIcon, }, mixins: [langMixin], + props: { + type: { + type: String, + default: '', + }, + gradientStep: { + type: Number, + default: 0, + }, + tokenMap: { + type: Array, + default: () => [], + }, + }, + emit: ['recoverGradation', 'changeGradation'], data() { return { activeIdx: 0, diff --git a/packages/theme-generator/src/color-panel/index.vue b/packages/theme-generator/src/color-panel/index.vue index 5b9573cd..588559bd 100644 --- a/packages/theme-generator/src/color-panel/index.vue +++ b/packages/theme-generator/src/color-panel/index.vue @@ -22,8 +22,8 @@ :style="{ paddingBottom: '4px', color: 'var(--text-secondary)' }" >

@@ -239,8 +239,8 @@ @@ -249,18 +249,18 @@ @@ -269,13 +269,13 @@ @@ -284,13 +284,13 @@ @@ -299,13 +299,13 @@ @@ -352,10 +352,6 @@ import ColorColumn from './components/ColorColumn'; export default { name: 'ColorPanel', - props: { - top: Number, - }, - mixins: [langMixin], components: { TRow, TCol, @@ -370,6 +366,13 @@ export default { ColorPicker, ColorCollapse, }, + mixins: [langMixin], + props: { + top: { + type: Number, + default: 0, + }, + }, data() { return { DEFAULT_COLORS, @@ -394,7 +397,7 @@ export default { errorMainColor: getOptionFromLocal('error') || getTokenValue('--td-error-color'), warningMainColor: getOptionFromLocal('warning') || getTokenValue('--td-warning-color'), generationMode: getOptionFromLocal('recommend') === 'true' ? 'recommend' : 'remain', // remain: 保留输入, recommend: 智能推荐 - isGrayRelatedToTheme: getOptionFromLocal('neutral') == 'true', + isGrayRelatedToTheme: getOptionFromLocal('neutral') === 'true', isMoreVisible: false, }; }, @@ -493,7 +496,7 @@ export default { themeStore.updateBrandColor(newBrandColor); updateLocalOption( 'color', - newBrandColor.toLowerCase() !== this.$theme.value.toLowerCase() ? this.brandInputColor : null, + newBrandColor.toLowerCase() !== this.$theme.value.toLowerCase() ? this.brandInputColor : null ); updateLocalOption('recommend', !this.isRemainMode ? 'true' : null); diff --git a/packages/theme-generator/src/common/components/Collapse/index.vue b/packages/theme-generator/src/common/components/Collapse/index.vue index 49dd3842..84b9a29c 100644 --- a/packages/theme-generator/src/common/components/Collapse/index.vue +++ b/packages/theme-generator/src/common/components/Collapse/index.vue @@ -1,135 +1,29 @@ - - diff --git a/packages/theme-generator/src/common/components/CollapseBase/index.vue b/packages/theme-generator/src/common/components/CollapseBase/index.vue new file mode 100644 index 00000000..08e90f09 --- /dev/null +++ b/packages/theme-generator/src/common/components/CollapseBase/index.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/packages/theme-generator/src/common/components/ColorPicker/index.vue b/packages/theme-generator/src/common/components/ColorPicker/index.vue index 8c2b8c9a..db42152c 100644 --- a/packages/theme-generator/src/common/components/ColorPicker/index.vue +++ b/packages/theme-generator/src/common/components/ColorPicker/index.vue @@ -7,8 +7,8 @@ :swatch-colors="null" :show-primary-color-preview="false" :select-input-props="{ popupProps: { attach: handleAttach } }" - @change="handleChange" v-bind="$attrs" + @change="handleChange" /> @@ -17,13 +17,16 @@ import { ColorPickerPanel as TColorPickerPanel } from 'tdesign-vue'; import { handleAttach } from '../../utils'; export default { - inheritAttrs: false, name: 'ColorPicker', components: { TColorPickerPanel, }, + inheritAttrs: false, props: { - value: String, + value: { + type: String, + default: '', + }, format: { type: String, default: 'HEX', diff --git a/packages/theme-generator/src/common/components/SegmentSelection/index.vue b/packages/theme-generator/src/common/components/SegmentSelection/index.vue index 88d583d1..3c38e7bf 100644 --- a/packages/theme-generator/src/common/components/SegmentSelection/index.vue +++ b/packages/theme-generator/src/common/components/SegmentSelection/index.vue @@ -19,9 +19,9 @@ :disabled="disabled" :max="maxSliderValue" :value="sliderValue" - @change="handleSliderChange" :label="renderLabel" - :tooltipProps="{ attach: handleAttach }" + :tooltip-props="{ attach: handleAttach }" + @change="handleSliderChange" >
@@ -29,13 +29,13 @@
@@ -64,7 +64,10 @@ export default { required: false, default: () => {}, }, - value: [String, Number], + value: { + type: [String, Number], + default: '', + }, disabled: { type: Boolean, default: false, diff --git a/packages/theme-generator/src/common/components/SizeSlider/index.vue b/packages/theme-generator/src/common/components/SizeSlider/index.vue index e5b380d3..95292164 100644 --- a/packages/theme-generator/src/common/components/SizeSlider/index.vue +++ b/packages/theme-generator/src/common/components/SizeSlider/index.vue @@ -7,8 +7,8 @@ :value="size" :format="format" theme="column" - @change="handleInputChange" :style="{ marginBottom: '8px' }" + @change="handleInputChange" />
@@ -30,28 +30,49 @@ import { InputNumber as TInputNumber, Slider as TSlider } from 'tdesign-vue'; export default { name: 'SizeSlider', + components: { + TSlider, + TInputNumber, + }, props: { - sizeValue: [String, Number], - title: String, - step: Number, - min: Number, - max: Number, - disabled: Boolean, + sizeValue: { + type: [String, Number], + default: 0, + }, + title: { + type: String, + default: '', + }, + step: { + type: Number, + default: 1, + }, + min: { + type: Number, + default: 0, + }, + max: { + type: Number, + default: 100, + }, + disabled: { + type: Boolean, + default: false, + }, needInteger: { type: Boolean, default: true, }, }, - components: { - TSlider, - TInputNumber, - }, emit: ['changeSize'], data() { return { size: null, }; }, + mounted() { + this.size = this.needInteger ? parseInt(this.sizeValue, 10) : this.sizeValue; + }, methods: { format(val) { return `${val}px`; @@ -70,9 +91,6 @@ export default { this.$emit('changeSize', v); }, }, - mounted() { - this.size = this.needInteger ? parseInt(this.sizeValue, 10) : this.sizeValue; - }, };