diff --git a/src/generators/Generator.ts b/src/generators/Generator.ts index f6010a6781..fa7a47060f 100644 --- a/src/generators/Generator.ts +++ b/src/generators/Generator.ts @@ -577,8 +577,8 @@ export default class Generator { } if (templateProperties.props) { - // TODO - this.props = templateProperties.props.value; + this.props = templateProperties.props.value.elements.map((element: Node) => element.value); + removeObjectKey(this.code, defaultExport.declaration, 'props'); } // now that we've analysed the default export, we can determine whether or not we need to keep it diff --git a/src/generators/dom/index.ts b/src/generators/dom/index.ts index d3adee900a..cdb5bc39e9 100644 --- a/src/generators/dom/index.ts +++ b/src/generators/dom/index.ts @@ -232,12 +232,32 @@ export default function dom( `; if (generator.customElement) { + const props = generator.props || Array.from(generator.expectedProperties); + builder.addBlock(deindent` class ${name} extends HTMLElement { constructor(options = {}) { super(); ${constructorBody} } + + static get observedAttributes() { + return ${JSON.stringify(props)}; + } + + ${props.map(prop => deindent` + get ${prop}() { + return this.get('${prop}'); + } + + set ${prop}(value) { + this.set({ ${prop}: value }); + } + `).join('\n\n')} + + attributeChangedCallback ( attr, oldValue, newValue ) { + this.set({ [attr]: newValue }); + } } customElements.define('${generator.tag}', ${name}); diff --git a/src/validate/js/propValidators/index.ts b/src/validate/js/propValidators/index.ts index 1be9f9ffbb..89ccd36f14 100644 --- a/src/validate/js/propValidators/index.ts +++ b/src/validate/js/propValidators/index.ts @@ -9,6 +9,7 @@ import methods from './methods'; import components from './components'; import events from './events'; import namespace from './namespace'; +import props from './props'; import tag from './tag'; import transitions from './transitions'; import setup from './setup'; @@ -25,6 +26,7 @@ export default { components, events, namespace, + props, tag, transitions, setup, diff --git a/src/validate/js/propValidators/props.ts b/src/validate/js/propValidators/props.ts new file mode 100644 index 0000000000..408e72a7f5 --- /dev/null +++ b/src/validate/js/propValidators/props.ts @@ -0,0 +1,20 @@ +import { Validator } from '../../'; +import { Node } from '../../../interfaces'; + +export default function props(validator: Validator, prop: Node) { + if (prop.value.type !== 'ArrayExpression') { + validator.error( + `'props' must be an array expression, if specified`, + prop.value.start + ); + } + + prop.value.elements.forEach((element: Node) => { + if (element.type !== 'Literal' || typeof element.value !== 'string') { + validator.error( + `'props' must be an array of string literals`, + element.start + ); + } + }); +} diff --git a/src/validate/js/propValidators/tag.ts b/src/validate/js/propValidators/tag.ts index 2bd55b894a..c64381fc54 100644 --- a/src/validate/js/propValidators/tag.ts +++ b/src/validate/js/propValidators/tag.ts @@ -1,4 +1,3 @@ -import usesThisOrArguments from '../utils/usesThisOrArguments'; import { Validator } from '../../'; import { Node } from '../../../interfaces';