generated from wbkd/webpack-starter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
55 lines (54 loc) · 2.14 KB
/
index.js
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
import {isFunction, propNameToCssVarName} from "./helper";
import {createObserver, OBSERVER_OPTIONS} from "./observer";
/**
* Define the Decorator
* @param options
* @returns {function(*): {kind: string, finisher(*): void, placement: string, descriptor: {}, key: symbol, initializer(): void}}
*/
export const cssVar = (options = {}) => element => {
return {
kind: 'field',
// eslint-disable-next-line no-undef
key: Symbol(),
placement: 'own',
descriptor: {},
initializer() {
if (isFunction(element.initializer)) {
this[element.key] = element.initializer.call(this);
}
// Using see option will turn on two-way binding from setting css var from code
// and synced it to the element property.
// it might cause performance issues.
if (options.observeCss) {
const propName = element.key;
// Keep a ref to css vars on _cssVarsProperties array
this._cssVarsProperties = this._cssVarsProperties || [];
this._cssVarsProperties.push(propName);
// For better performance: don't define an observer
// on the element if one was already defined
if (!this._cssVarsObserver) {
this._cssVarsObserver = createObserver();
this._cssVarsObserver.observe(this, OBSERVER_OPTIONS);
}
}
},
finisher(clazz) {
clazz.createProperty(element.key, options);
const key = `__${element.key}`;
const propName = element.key;
Object.defineProperty(clazz.prototype, propName, {
get() {
return this[key];
},
set(value) {
// Sync property with css var and render.
this[key] = value;
this.style.setProperty(propNameToCssVarName(propName), value);
this.requestUpdate();
},
configurable: true,
enumerable: true
});
},
};
};