@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
40 lines (39 loc) • 1.62 kB
JavaScript
import { getAttr, setAttr } from '../dom/attr';
import { toKebabCase, parseObjectSafe } from '../misc/format';
function buildJsonAttrDescriptor(attrName, readOnly, defaultValue) {
function fallback(value) {
console.warn('[ESL]: cannot parse attribute %s value "%s"', attrName, value);
return defaultValue;
}
function get() {
const attrContent = getAttr(this, attrName, '').trim();
if (!attrContent)
return defaultValue;
return parseObjectSafe(attrContent, fallback);
}
function set(value) {
try {
if (typeof value !== 'object')
throw Error('value should be object');
setAttr(this, attrName, value ? JSON.stringify(value) : false);
}
catch (e) {
console.error('[ESL] jsonAttr: Can not set json value ', e);
}
}
return readOnly ? { get } : { get, set };
}
const buildAttrName = (propName, dataAttr) => dataAttr ? `data-${toKebabCase(propName)}` : toKebabCase(propName);
/**
* Decorator to map current property to element attribute value using JSON (de-)serialization rules.
* Maps object type property.
* @param config - mapping configuration. See {@link JsonAttrDescriptor}
*/
export const jsonAttr = (config = {}) => {
config = Object.assign({ defaultValue: {} }, config);
return (target, propName) => {
const attrName = buildAttrName(config.name || propName, !!config.dataAttr);
Object.defineProperty(target, propName, buildJsonAttrDescriptor(attrName, !!config.readonly, config.defaultValue));
return {};
};
};