@riovir/wc-fontawesome
Version:
Web components for Font Awesome
74 lines (66 loc) • 2.48 kB
JavaScript
export function definePropsOn({ prototype }, props) {
for (const [name, prop] of Object.entries(props)) {
defineOn(prototype, name, prop);
}
prototype.connectedCallback = function connectedCallback() {
for (const [prop, { connect = () => {} }] of Object.entries(props)) {
connect(this, prop);
}
};
}
function defineOn(object, propName, { get, set, observe = () => {}, defaultValue }) {
const _get = get || ((_, value) => value);
const _set = set || ((_, value) => value);
const _cache = Symbol(`cached-${propName}`);
object[_cache] = defaultValue;
Object.defineProperty(object, propName, {
get() {
const lastValue = this[_cache];
this[_cache] = _get(this, this[_cache]);
if (this[_cache] !== lastValue) {
observe(this, this[_cache], lastValue);
}
return this[_cache];
},
set(value) {
const lastValue = this[_cache];
const result = _set(this, value, this[_cache]);
if (result === undefined) { return; }
this[_cache] = _get(this, result);
if (lastValue === this[_cache]) { return; }
observe(this, this[_cache], lastValue);
},
enumerable: true,
configurable: false,
});
}
export function Prop({ attribute, defaultValue, ...rest }) {
return { connect: initPropFrom(attribute, defaultValue), defaultValue, ...rest };
}
export function BooleanProp({ defaultValue = false, set = (_, value) => value, ...rest }) {
const setBoolean = (host, value) => set(host, Boolean(value));
return Prop({ defaultValue, set: setBoolean, ...rest });
}
export function StringProp({ defaultValue = '', set = (_, value) => value, ...rest }) {
const setString = (host, value) => set(host, asString(value));
return Prop({ defaultValue, set: setString, ...rest });
}
export function ObjectOrStringProp({ defaultValue = '', set = (_, value) => value, ...rest }) {
const setObjectOrString = (host, value) => {
const coercedValue = typeof value === 'object' ? value : asString(value);
return set(host, coercedValue);
};
return Prop({ defaultValue, set: setObjectOrString, ...rest });
}
function asString(value) {
return value === null || value === undefined ? '' : String(value);
}
function initPropFrom(attribute, defaultValue) {
const valueOf = typeof defaultValue === 'boolean' ?
() => true :
host => host.getAttribute(attribute);
return (host, key) => {
if (!host.hasAttribute(attribute)) { return; }
host[key] = valueOf(host);
};
}