-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathThemer.ts
148 lines (124 loc) · 4.13 KB
/
Themer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
* This file is part of the Klipper package.
*
* (c) François Pluchino <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import {DarkModeModuleState} from '@klipper/bow/stores/darkMode/DarkModeModuleState';
import {ThemerClasses} from '@klipper/bow/themer/ThemerClasses';
import {Store} from 'vuex';
import colors, {Colors} from 'vuetify/lib/util/colors';
/**
* @author François Pluchino <[email protected]>
*/
export class Themer {
/**
* Convert string classes into themer classes map.
*
* @param {ThemerClasses|string} classes
*
* @return {ThemerClasses}
*/
public static toClasses(classes: ThemerClasses|string): ThemerClasses {
if (typeof classes === 'string') {
const strings = classes.split(' ');
classes = {} as ThemerClasses;
strings.forEach((value) => {
(classes as ThemerClasses)[value.trim()] = true;
});
}
return classes;
}
/**
* Update the html meta theme color with the background color of the selected element.
*/
public static updateThemeColor(classNames: string): void {
const themeColor = document.querySelector<HTMLMetaElement>('meta[name="theme-color"]');
const app = document.getElementsByClassName(classNames);
if (themeColor && app.length > 0) {
window.setTimeout(() => {
let bgColor = '';
if (app[0] instanceof Element) {
bgColor = window.getComputedStyle(app[0], null)
.getPropertyValue('background-color');
}
bgColor = Themer.rgbToHex(bgColor);
if (bgColor) {
themeColor.content = bgColor;
}
}, 1);
}
}
/**
* Convert the string RGB value into the hexadecimal.
*/
public static rgbToHex(rgb: string): string {
const sep = rgb.indexOf(',') > -1 ? ',' : ' ';
const rgbs = rgb.substr(4).split(')')[0].split(sep);
let r = (+rgbs[0]).toString(16);
let g = (+rgbs[1]).toString(16);
let b = (+rgbs[2]).toString(16);
if (1 === r.length) {
r = '0' + r;
}
if (1 === g.length) {
g = '0' + g;
}
if (1 === b.length) {
b = '0' + b;
}
return '#' + r + g + b;
}
private store: Store<DarkModeModuleState>;
/**
* Constructor.
*
* @param {Store<DarkModeModuleState>} store
*/
public constructor(store: Store<DarkModeModuleState>) {
this.store = store;
}
/**
* Get the full colors.
*/
public get colors(): Colors {
return colors;
}
/**
* Create a computed object for the classes and select automatically the good theme.
*
* @param {ThemerClasses|string} classes
* @param {ThemerClasses|string} [darkClasses]
*/
public classes(classes: ThemerClasses|string, darkClasses?: ThemerClasses|string): ThemerClasses {
classes = Themer.toClasses(classes);
darkClasses = darkClasses ? Themer.toClasses(darkClasses) : {};
Object.keys(darkClasses).forEach((key) => {
const prevValue = undefined !== (classes as ThemerClasses)[key]
? (classes as ThemerClasses)[key]
: true;
if ((darkClasses as ThemerClasses)[key] as boolean) {
(classes as ThemerClasses)[key] = prevValue && this.store.state.darkMode.enabled;
} else {
(classes as ThemerClasses)[key] = prevValue && !this.store.state.darkMode.enabled;
}
});
return classes;
}
/**
* Select automatically the good theme.
*
* @param {string} color
* @param {string} [darkColor]
*
* @return {string}
*/
public color(color: string, darkColor?: string): string {
if (undefined !== darkColor && this.store.state.darkMode.enabled) {
return darkColor;
}
return color;
}
}