Skip to content

v0.16.0 - stay classy

Latest
Compare
Choose a tag to compare
@trusktr trusktr released this 26 May 08:16

What's Changed

  • @element options via static class fields, @jsonAttribute, and improvements by @trusktr in #46

    Add a new @jsonAttribute decorator for element attributes that accept JSON strings, add an object-based format for @element decorator options, accept both static elementName and static autoDefine options from static class fields as an alternative to options passed to the @element decorator, fall back to using the class constructor name to derive an element name when the name has not been specified, and improve the underlying attribute definition implementation to use half the number of objects which in turn no longer requires the non-decorator attribute types used in static observedAttributeHandlers to be called as functions.

    • BREAKING: To make the new object-based @element(options) format work well, along with static class field options, passing no arguments to @element (or passing an empty string) no longer causes the customElements definition to be skipped. @element class MyClass ... will now automatically define the element with the name my-el derived from the dash-cased constructor name instead of skipping definition.
      • Migration: to prevent automatic element definition, explicitly set autoDefine to false rather than relying on zero arguments or an empty string argument, f.e. @element('', false) class MyEl ..., @element({autoDefine: false}) class MyEl ..., or @element class MyEl extends Element { static autoDefine = false; ...}. For example, before:
        @element
        class MyEl extends Element {}
        MyEl.defineElement('with-any-name')
        after (recommended method):
        @element
        class MyEl extends Element {
          static autoDefine = false
        }
        MyEl.defineElement('with-any-name')
    • BREAKING: The attribute.* types for use with the non-decorator static observedAttributeHandlers API are no longer functions.
      • Migration: Convert attribute.type() to attribute.type. For example, before:
        class MyEl extends Element {
          static observedAttributeHandlers = {
            count: attribute.number(),
            hasGold: attribute.boolean(),
          }
        }
        after:
        class MyEl extends Element {
          static observedAttributeHandlers = {
            count: attribute.number,
            hasGold: attribute.boolean,
          }
        }

    Examples:

    New, options for @element via static class fields:

    @element
    class MyElement extends Element {
      static elementName = 'my-el'
    }
    @element
    class MyElement extends Element {
      static elementName = 'my-el'
      static autoDefine = false
    }
    
    MyElement.defineElement()

    New @jsonAttribute decorator for json-handling attributes:

    Given this element definition,

    @element
    class MyEl extends Element {
      @jsonAttribute data: SomeType = {someValue: 123}
    }

    we can pass JSON strings for deserialization via HTML/DOM attributes:

    <my-el id="myEl" data='{"someValue": 456}'></my-el>
    
    <script>
      console.log(myEl.data.someValue) // 456
    </script>

    New object-based options for @element:

    @element({elementName: 'my-el'})
    class MyElement extends Element {}
    @element({elementName: 'my-el', autoDefine: false})
    class MyElement extends Element {}
    MyElement.defineElement()

    Automatically derive the dash-cased element name from the class constructor:

    @element
    class MyEl extends Element {}
    
    console.log(MyEl.elementName) // 'my-el'
    console.log(document.createElement('my-el') instanceof MyEl) // true
    @element class MyEl extends Element {
      static autoDefine = false
    }
    
    const el = document.createElement('my-el')
    console.log(el instanceof MyEl) // false
    MyEl.defineElement() // defines <my-el>
    console.log(el instanceof MyEl) // true

    Simplified non-decorator static observedAttributeHandlers:

    element(class MyEl extends Element {
      static elementName = 'my-el' // This field is not necessary, unless your minifier renames classes or you want to re-use the string type in TypeScript.
    
      static observedAttributeHandlers = {
        someValue: attribute.number,
      }
    
      someValue = 123;
    })

Full Changelog: v0.15.0...v0.16.0