@gongt/ts-stl-client
Version:
65 lines (56 loc) • 2 kB
text/typescript
import {createLogger} from "@gongt/ts-stl-library/debug/create-logger";
import {LOG_LEVEL} from "@gongt/ts-stl-library/debug/levels";
import * as React from "react";
import {StatefulBaseComponent} from "../stateless-component";
export const prefixAll: PrefixAll = require('inline-style-prefixer/static');
export interface PrefixAll {
(style: React.CSSProperties): React.CSSProperties;
(style: CSSStyleDeclaration): CSSStyleDeclaration;
}
export interface CSSPropsMap {
default: React.CSSProperties;
[status: string]: React.CSSProperties;
}
const warn = createLogger(LOG_LEVEL.WARN, 'auto-style');
export function AutoStyle<X extends CSSPropsMap>(styleMap: X): PropertyDecorator {
Object.keys(styleMap).forEach((key) => {
styleMap[key] = prefixAll(styleMap[key]);
if (key === 'default') {
return;
}
styleMap[key] = Object.assign({}, styleMap.default, styleMap[key]);
});
return <T extends StatefulBaseComponent<any, any>>(target: T, propertyKey: string|symbol) => {
const stateKey = 's_' + propertyKey.toString();
if (!target.state) {
target.state = {};
}
Object.defineProperty(target, propertyKey, {
get(this: T): React.CSSProperties {
return styleMap[this.state[stateKey] || 'default'];
},
set(this: T, type: keyof X) {
if (!styleMap[type]) {
warn('styleMap "%s.%s" do not have key "%s"', target.constructor.name, propertyKey, type);
}
this.setState({[stateKey]: type});
},
})
};
}
export function AutoStyleProp<X extends CSSPropsMap>(styleMap: X): PropertyDecorator {
Object.keys(styleMap).forEach((key) => {
if (key === 'default') {
return;
}
styleMap[key] = Object.assign({}, styleMap.default, styleMap[key]);
});
return <P, T extends StatefulBaseComponent<P, any>>(target: T, propertyKey: keyof P) => {
const stateKey = 's_' + propertyKey.toString();
Object.defineProperty(target, propertyKey, {
get(this: T): React.CSSProperties {
return styleMap[this.props[stateKey] || 'default'];
},
})
};
}