import { toKebabCase } from '../../esl-utils/misc/format' ; import type { ESLBaseElement } from '../core/esl-base-element' ; /** HTML attribute mapping configuration */ type AttrDescriptor = { /** HTML attribute name. Uses kebab-cased variable name by default */ name ? : string ; /** Create getter only */ readonly ? : boolean ; /** Use data-* attribute */ dataAttr ? : boolean ; /** Default property value. Used if no attribute is present on the element. Empty string by default. */ defaultValue ? : string | boolean | null ; } ; function buildSimpleDescriptor ( attrName , readOnly , defaultValue ) { function get ( ) { const value = this . getAttribute ( attrName ) ; return typeof value === 'string' ? value : defaultValue ; } function set ( value ) { if ( value === undefined || value === null || value === false ) { this . removeAttribute ( attrName ) ; } else { this . setAttribute ( attrName , value === true ? '' : value ) ; } } return readOnly ? { get } : { get , set } ; } const buildAttrName = ( propName , dataAttr ) : string => dataAttr ? `data-${ toKebabCase ( propName ) }` : toKebabCase ( propName ) ; param config - mapping configuration. See  AttrDescriptor export const attr = ( config = { } ) : PropertyDecorator => { config = Object . assign ( { defaultValue : '' } , config ) ; return ( target , propName ) : void => { const attrName = buildAttrName ( config . name || propName , ! ! config . dataAttr ) ; Object . defineProperty ( target , propName , buildSimpleDescriptor ( attrName , ! ! config . readonly , config . defaultValue ) ) ; } ; } ;