diff --git a/src/modules/esl-utils/decorators/attr.ts b/src/modules/esl-utils/decorators/attr.ts index 5e1ff998f..7c5d31ebf 100644 --- a/src/modules/esl-utils/decorators/attr.ts +++ b/src/modules/esl-utils/decorators/attr.ts @@ -1,7 +1,8 @@ -import {identity} from '../misc/functions'; +import {identity, resolveProperty} from '../misc/functions'; import {parseString, toKebabCase} from '../misc/format'; import {getAttr, setAttr} from '../dom/attr'; +import type {PropertyProvider} from '../misc/functions'; import type {ESLAttributeDecorator} from '../dom/attr'; import type {ESLDomElementTarget} from '../abstract/dom-target'; @@ -17,7 +18,7 @@ type AttrDescriptor = { /** Use data-* attribute */ dataAttr?: boolean; /** Default property value. Used if no attribute is present on the element. Empty string by default. */ - defaultValue?: T; + defaultValue?: T | PropertyProvider; /** Parser from attribute value */ parser?: AttrParser; /** Serializer to transform passed value to attribute value */ @@ -38,7 +39,9 @@ export const attr = (config: AttrDescriptor = {}): ESLAttributeDe function get(): T | null { const val = getAttr(this, attrName); - if (val === null && 'defaultValue' in config) return config.defaultValue as T; + if (val === null && 'defaultValue' in config) { + return resolveProperty(config.defaultValue, this) as T; + } return (config.parser || parseString as AttrParser)(val); } function set(value: T): void { diff --git a/src/modules/esl-utils/decorators/test/attr.test.ts b/src/modules/esl-utils/decorators/test/attr.test.ts index f44f2f865..da959c6bf 100644 --- a/src/modules/esl-utils/decorators/test/attr.test.ts +++ b/src/modules/esl-utils/decorators/test/attr.test.ts @@ -18,6 +18,8 @@ describe('Decorator: attr', () => { public readonlyField: string | null; @attr({defaultValue: 'def'}) public defField: string | boolean; + @attr({defaultValue: () => 'test-provider'}) + public defProvider: string; } customElements.define('test-el-attr', TestElement); const el = new TestElement(); @@ -99,6 +101,9 @@ describe('Decorator: attr', () => { el.defField = false; expect(el.defField).toBe('def'); expect(el.hasAttribute('def-field')).toBe(false); + expect(el.defProvider).toBe('test-provider'); + el.defProvider = ''; + expect(el.defProvider).toBe(''); }); afterAll(() => {