Thanks to visit codestin.com
Credit goes to github.com

Skip to content

RFC: Attribute Prefixes #11

@lukeed

Description

@lukeed

Yo~!

I wonder if it'd be easier to parse & filter down to dynamic attributes via a common prefix match. In this case, "easier" is meant to cover the dev declarations and parser's workload. This is purely because of the consistent syntax & ability (on the parser) side to lazily infer if work will need to be done on X attribute later on.

// Values
// ---

// current
<button disabled={disabled}>...</button>
<button {disabled}>...</button>

// ideal?
<div :disabled={ disabled }>...</button>
<div :disabled>...</button>

// untouched
<Widget {...things}/>

// Events
// ---

// current
<button on:click=handleClick()>click me!</button>
<button on:click="handleClick({ foo: bar })">click me!</button>

// ideal?
<button :onclick=handleClick>click me!</button>
<button :onclick="handleClick">click me!</button>
<button :onclick={ handleClick }>click me!</button>
<button :onclick="handleClick({ foo: bar })">click me!</button>

Like stated in readme, any combination (or lack thereof) of " and {} is valid, as that doesn't really matter and essentially is like a semicolons-in-js debate. They're stylistic & will be required for compiler clarification in few cases.

Another aside, I think passing functions should work like JSX. It passes a reference when uninitialized, or you may pass along initial values that set up a new functional return value. I can be swayed on this 😇

// <button :onclick=onFoo>click me!</button>
button.onclick = onFoo;

// <button :onclick={ onBar(123) }>click me!</button>
const onBar = id => e => alert('hello', id, e.target.className);
button.onclick = onBar(123);

Custom Directives

Lastly, that leaves custom directives. This will borrow a lot from Vue & from Svelte's on:*, of course, but the difference here is that the syntax change illustrates a completely custom handler rather than attempting to write into a native attribute or event handler.

<form :onsubmit={ handler } @error={ onError } @success={ onLogin }>...</form>

function fire(el, name, data, opts) {
  opts = opts || {};
  if (data) opts.detail = detail;
  el.dispatchEvent(new CustomEvent(name, opts));
}

function handler(e) {
  e.preventDefault();

  let el = e.target;
  let foo = validate(el, my.rules);

  if (foo.errors.length > 0) {
    return fire(el, 'error', foo.errors); //~> onError called
  }
  
  return fire(el, 'success', foo.data); //~> onLogin called
}

// because ":onclick"
form.onclick = handler;

// because "@" is used
form.addEventListener('error', onError);
form.addEventListener('success', onLogin);

The parser then has a really easy time figure out if something is meant to be static or dynamic. Essentially it's just this:

function isDynamic(str) {
  let c = str.charCodeAt(0);
  return c === 58 || c === 64; // : or @
}

let dyna = SUSPECTS.filter(isDynamic);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions