Skip to content

Commit 5b6cb31

Browse files
iamkunziyoung
authored andcommitted
chore: generate theme (ElemeFE#14666)
* update es fr i18n * update no need edit pages * move var name to frontend * add i18n * update i18n * fix bug * update style * add callback * add shortcut * redo undo logic * update picker style * update shadow style * save config to local * button color * button color * add message * update save logic
1 parent 463ed66 commit 5b6cb31

23 files changed

+511
-174
lines changed

examples/components/theme-configurator/docStyle.vue

+10-4
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,34 @@ export default {
66
data() {
77
return {
88
docs: '', // content of docs css
9-
theme: ORIGINAL_THEME
9+
theme: ORIGINAL_THEME,
10+
asyncCb: true
1011
};
1112
},
1213
methods: {
13-
updateDocStyle(e) {
14+
updateDocStyle(e, cb) {
1415
const val = e.global['$--color-primary'] || ORIGINAL_THEME;
1516
const oldVal = this.theme;
1617
const getHandler = (variable, id) => {
1718
return () => {
1819
let newStyle = this.updateStyle(this[variable], ORIGINAL_THEME, val);
1920
updateDomHeadStyle(id, newStyle);
21+
this.asyncCb && cb();
2022
};
2123
};
2224
const docsHandler = getHandler('docs', 'docs-style');
2325
if (!this.docs) {
2426
const links = [].filter.call(document.querySelectorAll('link'), link => {
2527
return /docs\..+\.css/.test(link.href || '');
2628
});
27-
links[0] && this.getCSSString(links[0].href, docsHandler, 'docs');
29+
if (links[0]) {
30+
this.getCSSString(links[0].href, docsHandler, 'docs');
31+
} else {
32+
this.asyncCb = false;
33+
}
2834
} else {
2935
docsHandler();
3036
}
31-
3237
const styles = [].slice.call(document.querySelectorAll('style'))
3338
.filter(style => {
3439
const text = style.innerText;
@@ -40,6 +45,7 @@ export default {
4045
style.innerText = this.updateStyle(innerText, oldVal, val);
4146
});
4247
this.theme = val;
48+
!this.asyncCb && cb();
4349
},
4450
updateStyle(style, oldColor, newColor) {
4551
return style.replace(new RegExp(oldColor, 'ig'), newColor);

examples/components/theme-configurator/download.vue

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<el-button
99
type="primary"
1010
:loading=downloading
11+
style="background: #66b1ff;border-color: #66b1ff"
1112
@click.stop="onDownload">
1213
{{getActionDisplayName("download-theme")}}
1314
</el-button>

examples/components/theme-configurator/editor/boxShadow.vue

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
.plus-button {
7575
position: absolute;
7676
left: 90%;
77+
margin-top: 4px;
7778
}
7879
.colorPicker {
7980
margin-left: 0;

examples/components/theme-configurator/editor/color-picker/src/components/color-list.vue

+10-12
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
</span>
1111
<div class="color-list-item-label">
1212
{{item.info.label}}
13-
</div>
14-
<div class="color-list-item-value">
15-
{{item.info.value}}
13+
<div class="color-list-item-value">
14+
{{item.info.value}}
15+
</div>
1616
</div>
1717
</div>
1818
</div>
@@ -34,6 +34,7 @@
3434
width: 100%;
3535
cursor: pointer;
3636
margin: 2px 0;
37+
position: relative;
3738
}
3839
.color-list-item:hover {
3940
background: #efefef;
@@ -44,22 +45,19 @@
4445
margin-top: 2px;
4546
margin-left: 5px;
4647
border-radius: 100%;
47-
display: inline-block;
48+
display: block;
49+
position: absolute;
4850
}
4951
.color-list-item-label {
50-
margin-left: 15px;
52+
margin-left: 35px;
5153
font-size: 13px;
5254
line-height: 24px;
5355
display: inline-block;
54-
vertical-align: super;
55-
width: 30%;
56+
width: 85%;
57+
overflow: hidden;
5658
}
5759
.color-list-item-value {
58-
margin-left: 15px;
59-
font-size: 13px;
60-
line-height: 24px;
61-
display: inline-block;
62-
vertical-align: super;
60+
float: right;
6361
}
6462
</style>
6563

examples/components/theme-configurator/index.vue

+71-8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
round
55
type="primary"
66
size="mini"
7+
style="background: #66b1ff;border-color: #66b1ff"
78
@click.stop="showConfigurator"
89
>{{getActionDisplayName("theme-editor")}}</el-button>
910
<transition name="fade">
@@ -23,7 +24,8 @@
2324
</div>
2425
<div v-if="init && !currentConfig" class="no-config">
2526
<img src="../../assets/images/theme-no-config.png" alt>
26-
<span>{{getActionDisplayName("no-config")}}</span>
27+
<span v-if="pageCouldEdit">{{getActionDisplayName("no-config")}}</span>
28+
<span v-else>{{getActionDisplayName("no-need-config")}}</span>
2729
</div>
2830
<download-area></download-area>
2931
</div>
@@ -100,8 +102,16 @@ import {
100102
} from './utils/utils.js';
101103
import DocStyle from './docStyle';
102104
import Loading from './loading';
105+
import Shortcut from './shortcut';
103106
import DownloadArea from './download';
104107
108+
const ELEMENT_THEME_USER_CONFIG = 'ELEMENT_THEME_USER_CONFIG';
109+
110+
const DEFAULT_USER_CONFIG = {
111+
global: {},
112+
local: {}
113+
};
114+
105115
export default {
106116
components: {
107117
mainPanel,
@@ -117,21 +127,33 @@ export default {
117127
global: {},
118128
local: {}
119129
},
120-
lastApply: 0
130+
lastApply: 0,
131+
userConfigHistory: [],
132+
userConfigRedoHistory: [],
133+
hasLocalConfig: false
121134
};
122135
},
123-
mixins: [DocStyle, Loading],
136+
mixins: [DocStyle, Loading, Shortcut],
124137
computed: {
125138
globalValue() {
126139
return filterGlobalValue(this.defaultConfig, this.userConfig);
140+
},
141+
pageCouldEdit() {
142+
const noNeedEdit = ['installation', 'quickstart', 'i18n', 'custom-theme', 'transition'];
143+
const lastPath = this.$route.path.split('/').slice(-1).pop();
144+
return noNeedEdit.indexOf(lastPath) < 0;
127145
}
128146
},
147+
mounted() {
148+
this.checkLocalThemeConfig();
149+
},
129150
methods: {
130151
getActionDisplayName(key) {
131152
return getActionDisplayName(key);
132153
},
133154
showConfigurator() {
134155
this.visible = !this.visible;
156+
this.visible ? this.enableShortcut() : this.disableShortcut();
135157
bus.$emit('user-theme-config-visible', this.visible);
136158
window.userThemeConfigVisible = Boolean(this.visible);
137159
if (this.init) return;
@@ -154,25 +176,46 @@ export default {
154176
this.defaultConfig = defaultConfig;
155177
this.filterCurrentConfig();
156178
this.init = true;
179+
this.checkLocalThemeConfig();
157180
}
158181
loading.close();
159182
}, 300); // action after transition
160183
});
161184
});
162185
},
186+
checkLocalThemeConfig() {
187+
try {
188+
if (this.hasLocalConfig) {
189+
this.$message(getActionDisplayName('load-local-theme-config'));
190+
this.onAction();
191+
return;
192+
}
193+
const config = JSON.parse(localStorage.getItem(ELEMENT_THEME_USER_CONFIG));
194+
if (config && config.global) {
195+
this.userConfig = config;
196+
this.hasLocalConfig = true;
197+
this.showConfigurator();
198+
}
199+
} catch (e) {
200+
// bad local config
201+
}
202+
},
163203
filterCurrentConfig() {
164204
this.currentConfig = this.defaultConfig.find((config) => {
165-
return config.name === this.$route.path.split('/').pop().toLowerCase();
205+
return config.name === this.$route.path.split('/').pop().toLowerCase().replace('-', '');
166206
});
167207
},
168208
userConfigChange(e) {
209+
this.userConfigHistory.push(JSON.stringify(this.userConfig));
210+
this.userConfigRedoHistory = [];
169211
this.$set(this.userConfig[filterConfigType(this.currentConfig.name)], e.key, e.value);
170212
this.onAction();
171213
},
172214
applyStyle(res, time) {
173215
if (time < this.lastApply) return;
174-
this.updateDocs();
175-
updateDomHeadStyle('chalk-style', res);
216+
this.updateDocs(() => {
217+
updateDomHeadStyle('chalk-style', res);
218+
});
176219
this.lastApply = time;
177220
},
178221
onDownload() {
@@ -190,6 +233,12 @@ export default {
190233
onAction() {
191234
this.triggerComponentLoading(true);
192235
const time = +new Date();
236+
const currentConfigString = JSON.stringify(this.userConfig);
237+
if (JSON.stringify(DEFAULT_USER_CONFIG) === currentConfigString) {
238+
localStorage.removeItem(ELEMENT_THEME_USER_CONFIG);
239+
} else {
240+
localStorage.setItem(ELEMENT_THEME_USER_CONFIG, currentConfigString);
241+
}
193242
updateVars(this.userConfig)
194243
.then((res) => {
195244
this.applyStyle(res, time);
@@ -213,10 +262,24 @@ export default {
213262
triggerComponentLoading(val) {
214263
bus.$emit('user-theme-config-loading', val);
215264
},
216-
updateDocs() {
265+
updateDocs(cb) {
217266
window.userThemeConfig = JSON.parse(JSON.stringify(this.userConfig));
218267
bus.$emit('user-theme-config-update', this.userConfig);
219-
this.updateDocStyle(this.userConfig);
268+
this.updateDocStyle(this.userConfig, cb);
269+
},
270+
undo() {
271+
if (this.userConfigHistory.length > 0) {
272+
this.userConfigRedoHistory.push(JSON.stringify(this.userConfig));
273+
this.userConfig = JSON.parse(this.userConfigHistory.pop());
274+
this.onAction();
275+
}
276+
},
277+
redo() {
278+
if (this.userConfigRedoHistory.length > 0) {
279+
this.userConfigHistory.push(JSON.stringify(this.userConfig));
280+
this.userConfig = JSON.parse(this.userConfigRedoHistory.shift());
281+
this.onAction();
282+
}
220283
}
221284
},
222285
watch: {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
<script>
3+
export default {
4+
data() {
5+
return {
6+
downloading: false
7+
};
8+
},
9+
methods: {
10+
shortcut(e) {
11+
if (e.keyCode === 90 && (e.ctrlKey || e.metaKey)) {
12+
if (e.shiftKey) {
13+
this.redo();
14+
} else {
15+
this.undo();
16+
}
17+
}
18+
},
19+
enableShortcut() {
20+
document.addEventListener('keydown', this.shortcut);
21+
},
22+
disableShortcut() {
23+
document.removeEventListener('keydown', this.shortcut);
24+
}
25+
}
26+
};
27+
</script>

examples/components/theme-configurator/utils/utils.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,14 @@ const getNameFromI18N = (name) => {
4646
return constant.filter(config => config.lang === lang)[0][name];
4747
};
4848

49+
export const getVariableDisplayName = (key) => {
50+
return getNameFromI18N('variable-name')[key] || key;
51+
};
52+
4953
export const getStyleDisplayName = (config, componentName) => {
5054
const displayNameMap = getNameFromI18N('display-name');
51-
if (config.name !== '[]') {
52-
const langIndex = {'zh-CN': '0', 'es': 2, 'fr-FR': 3}[getLang()] || 1;
53-
const nameArr = config.name.replace(/\[?\]?/g, '').split(',');
54-
return nameArr[langIndex] || nameArr[1];
55+
if (config.name) {
56+
return getVariableDisplayName(config.key.replace('$--', ''));
5557
}
5658
let displayName = config.key.replace(`$--${componentName}-`, '').replace();
5759
Object.keys(displayNameMap).forEach((name) => {

0 commit comments

Comments
 (0)