DEV Community

Cover image for Proxies and Dynamic Methods
Zevan Rosser
Zevan Rosser

Posted on

Proxies and Dynamic Methods

Proxies can be used for all manner of strange “magic”. I can actually see some uses for this, might post in the next few days…

See more stuff like this over @ Snippet Zone

Top comments (3)

Collapse
 
shuckster profile image
Conan • Edited

Lots of fun. 😁

Here's a pattern I quite like:

const vnodes = new Proxy({}, {
  get: (_, tag) => (...rest) =>
      React.createElement(tag, ...rest)
})
Enter fullscreen mode Exit fullscreen mode

Usage:

const { h1, p, form, input } = vnodes

function App() {
  return form(null,
    h1(null, 'Hello, World!'),
    p(null, "Won't you click that lovely button?"),
    input({ type: 'button', value: 'Lovely button!' })
  )
}
Enter fullscreen mode Exit fullscreen mode

For when you absolutely, positively don't want JSX or a build-system.

Collapse
 
zevanrosser profile image
Zevan Rosser • Edited

that is very cool :D - really a sweet way around JSX :D

I have something similar in vanilla style - was planning on posting about it in a few days... this is just the basic idea:

const spec = {
  get(o, key) {
    return o[key] != null ? 
      o[key] : o[key] = (...args) => {
        const el = document.createElement(key);
        args.forEach(arg => { 
          if (typeof arg === 'string') {
            const span = document.createElement('span');
            span.innerHTML = arg;
            el.appendChild(span);
          } else if (typeof arg === 'object') {
            if (arg.tagName != null) {
              el.appendChild(arg);
            } else {
              for (let i in arg) {
                el.setAttribute(i, arg[i]);
              }
            }
          }
        });
        return el;
      }
  },
  set(o, key, v) {
    o[key] = v;
  }
}

const dom = new Proxy({}, spec);

document.body.appendChild(
  dom.div(
    dom.button('cool'), 
    dom.h2('some text', { style: 'font-style: italic' }), 
    dom.br(), 
    dom.input({ placeholder: 'testing 123' })
  )
);

const { div, input, label } = dom;
document.body.appendChild(
  div(
    label(
      'Slider:',
      { 
        for: 'slider', 
        style: 'padding:1em;display:block' 
      },
      input({ id: 'slider', type: 'range' })
    )
  )
);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
shuckster profile image
Conan

Cool! Really nice creative opportunities with Proxy, and stuff like this is a great application of its usage.