CONVERT setProperty with CSS variables to object and functions version 2

PHOTO EMBED

Fri Feb 21 2025 03:25:09 GMT+0000 (Coordinated Universal Time)

Saved by @davidmchale #setproperty #cssvariables

// html
 <div id="app">
      <div class="grid-container">
        <div class="box"><a href="#">remove</a></div>
        <div class="box"><a href="#">remove</a></div>
        <div class="box"><a href="#">remove</a></div>
        <div class="box"><a href="#">remove</a></div>
      </div>
    </div>


//css


.grid-container {
  background-color: aliceblue;
  width: 100%;
  min-height: 200px;
  display: grid;
  column-gap: 1rem;
  grid-template-columns: repeat(
    var(--col-grid-count, 4),
    var(--col-make-width, 1fr)
  );
}

.box {
  width: 100%;
  height: 100%;
  background-color: firebrick;
  padding-top: 1rem;
}

.box a {
  text-align: center;
  margin-top: 1rem;
  color: white;
  display: flex;
  justify-content: center;
  cursor: pointer;
  text-decoration: none;
}


//js

(function () {
  "use strict";

  const gridContainer = document.querySelector(".grid-container");

  if (!gridContainer) return;

  function changeItemWith(value) {
    gridContainer.style.setProperty("--col-make-width", value);
  }

  function updateGrid(number) {
    const updatedBoxes = document.querySelectorAll(".box").length;
    gridContainer.style.setProperty("--col-grid-count", updatedBoxes);

    const widthOptions = {
      1: () => changeItemWith("minmax(230px, 250px)"),
      2: () => changeItemWith("minmax(295px, 320px)"),
      3: () => changeItemWith("minmax(245px, 420px)"),
      4: () => changeItemWith("minmax(243px, 500px)"),
    };

    console.log(`Number of boxes: ${number}`);
    console.log(`Function in widthOptions:`, widthOptions[number]);

    // Fix: Call the function if it exists, otherwise apply default width
    // see note on how widthOptions[number](); works
    if (widthOptions[number]) {
      widthOptions[number]();
    } else {
      changeItemWith("205px"); // Default case
    }
  }

  function onHandleLink(event) {
    event.preventDefault();

    const link = event.currentTarget;
    const box = link.parentElement;

    if (box) {
      box.remove();
      // Fix: Pass the correct length
      updateGrid(document.querySelectorAll(".box").length); 
    }

    console.log(box);
  }

  function listeners() {
    document.querySelectorAll(".box").forEach((box) => {
      const link = box.querySelector("a");
      if (link) {
        link.addEventListener("click", onHandleLink);
      }
    });
  }

  function init() {
    // Fix: Pass the correct length
    updateGrid(document.querySelectorAll(".box").length); 
    listeners();
  }

  init();
})();



/*
NOTE; Understanding widthOptions 

widthOptions is an object where each key (like 1, 2, etc.) maps to a function:

const widthOptions = {
  1: () => changeItemWith("minmax(230px, 250px)"),
  2: () => changeItemWith("minmax(295px, 249px)"),
  3: () => changeItemWith("minmax(245px, 1fr)"),
  4: () => changeItemWith("minmax(243px, 1fr)"),
};

Each value is an anonymous function (() => {}) that calls changeItemWith(...).


Accessing a Function in an Object
If number is 1, then: widthOptions[1]

is the same as: () => changeItemWith("minmax(230px, 250px)");
which in the widthOptions object is:  1: () => changeItemWith("minmax(230px, 250px)")


So if we call it with (), it executes:
widthOptions[1]();
*/ 

// See codesandbox for my implementation
// https://codesandbox.io/p/sandbox/q3926h?file=%2Fsrc%2Findex.mjs%3A28%2C6-28%2C30
content_copyCOPY