Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider support for custom “updaters” in default template engine. #132

Open
theengineear opened this issue Mar 4, 2023 · 0 comments

Comments

@theengineear
Copy link
Collaborator

theengineear commented Mar 4, 2023

Just adding this for completeness. We likely have no need to expose custom updaters in our default templating engine, but if we ever wanted to, it could look something like this:

class MyBaseElement extends XElement {
  static get templateEngine() {
    return {
      ...XElement.defaultTemplateEngine,
      match: {
        type: 'attribute', // or "property", "content", etc…
        interface: (value, words) => {
          // Perform validation, etc.
          const context = [words];
          return [words]; // Optionally return custom context. 
        },
        // If it’s for an attribute, boolean, defined, or property, you get
        //  the following, but it’d be slightly different for content-types.
        //  Note that the “words” below shows up because it was returned
        //  by the above “interface” function.
        updater: (node, name, value, lastValue, words) => {
          if (value !== lastValue) {
            node.setAttribute(name, value);
            if (words.includes(name)) {
              const data = { bubbles: true, composed: true };
              node.dispatchEvent(new CustomEvent('match', data));
            }
          }
        }
      }
    };
  }
}

class MyElement extends MyBaseElement {
  static get properties() {
    return {
      word: { type: String },
      words: { type: Array, default: () => ['fish', 'cat', 'bear'] },
    };
  }
  static template(html, { match }) {
    return ({ word, words }) => {
      html`<div word="${match(word, words)}"></div>`;
    };
  }
}

While it's not much of a code burden — it does pose an interface burden that might be hard to change in the future. IFF we really needed this, we could always add (harder to remove later than it is to add later).

Also note that other templating engines expose custom functionality like this — so it's possible to simply plug something else in if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant