1
\$\begingroup\$

First time creating my own Proxy handler, instead of copy pasting code.

Goal is to chain CSS definitions: style(element).color("red").background("green")

and allow whole CSS objects:

style(element).CSS({color:"red",font:"12 px Arial"}).background("green")

Any optimizations?

let handler = {
  get: (target, prop) => val => // getter returns a function
    val ?
    (
      handler.set(target, prop, val), //process val parameter as setter
      new Proxy(target, handler) // and return new proxy for chaining
    ) 
    //else:
    : target[prop], // no parameter value, return property value

  set: (target, prop, val) => prop === "CSS" ? Object.assign(target, val) : target[prop] = val
}

let style = element => new Proxy(element.style, handler);

let el = document.body.appendChild(document.createElement("div"));

el.style.backgroundColor = "red"; // standard non-Proxy way of setting styles

style(el).fontSize = "30px"; // style property name as SETTER

// Proxy allows for chaining because each function returns a Proxy again:

style(el)
  .backgroundColor("green") // style property Name processed as function
  .CSS({ // custom function applies CSS
    width: "100px",
  })
  .CSS = { // custom SETTER applies CSS (last action in the chain)
    color: "gold",
    fontWeight: "bold",
    textAlign: "center"
  };

el.textContent = style(el).fontSize(); // GETTER as function notation!!

Update #1

I reduced the style()function definition to a one-liner:

let style = element => new Proxy(element.style, handler = {
  get: (target, prop, proxy) => val =>
    val ? (handler.set(target, prop, val), proxy) : target[prop],
  set: (target, prop, val) =>
    prop === "CSS" ? Object.assign(target, val) : target[prop] = val
});

any issues here?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.