@jsonAttr Decorator
Maps a property to an HTML attribute using JSON stringification / evaluation rules ("JSON‑lite").
Quick Start
import {jsonAttr} from '@exadel/esl/modules/esl-utils/decorators';
class SettingsPanel extends HTMLElement {
// Will read the attribute value, evaluate (JSON‑like) or fall back to {}
@jsonAttr({defaultValue: {theme: 'light', compact: false}})
config!: {theme: string; compact: boolean};
}
// <settings-panel config='{"theme":"dark","compact":true}'></settings-panel>
// panel.config => {theme: 'dark', compact: true}
// Without attribute: panel.config => {theme: 'light', compact: false}
// Writing assigns JSON (object) => attribute updated (or removed if falsy/object empty as per internal rules)
panel.config = {theme: 'dark', compact: false};
What It Does Today (Summary)
Aspect | Current Behavior (v5.x) |
---|---|
Mapping | Attribute string ⇄ object (or null ) via internal evaluation (evaluate ) + JSON.stringify on set |
Default | defaultValue used only when attribute missing (not written to DOM) |
Readonly | readonly: true -> prevents setting; still parses attribute |
data-* | dataAttr: true -> uses data- prefixed name |
Errors | Malformed JSON/eval logs a warning, returns defaultValue |
When to Use @jsonAttr vs @attr
Use @jsonAttr
for conventional object mapping with default object semantics and no need for fine‑grained custom parsing yet. Use @attr
with a custom parser/serializer (see attr.md
) when you need:
- Specialized serialization rules
- Non‑object values combined inside a single attribute
- Transitional strategy before enhanced object parsing arrives
Inheritance / Override Patterns
You can redeclare the property with @prop
to freeze or replace default behavior:
class BaseCfg extends HTMLElement {
@jsonAttr({defaultValue: {enabled: true}}) options!: {enabled: boolean};
}
class LockedCfg extends BaseCfg {
@prop(Object.freeze({enabled: false}), {readonly: true}) override options!: {enabled: boolean};
}
(Overrides the dynamic attribute mapping with a fixed prototype value.)
Future Expansion (ESL v6.0.0+)
Planned improvements (subject to change):
- Unified
parseObject
helper for safer / more permissive parsing - Clearer error fallback strategy
- Potential structured cloning semantics for complex values (TBD)
Until then: keep payloads simple, valid JSON objects.
Caveats (Current Version)
- Only plain objects / arrays that
JSON.stringify
can handle are fully safe. - Functions, Dates, custom classes won’t round‑trip meaningfully.
- Large objects may bloat attributes—prefer IDs or references when possible.
- Attribute size limits still apply (browser dependent).
Minimal API Reference
jsonAttr<T>(config?: {
name?: string;
readonly?: boolean;
dataAttr?: boolean;
defaultValue?: T; // used only if attribute is absent
}): PropertyDecorator;