Various JavaScript hacks

Auto-resize box when contents gets near boundaries

This code automatically resizes boxes when you create or drag cards near the box boundaries. A big use case for me is if I want to add cards to a box, this way I can click into the box, and start typing and hit return, and the box will grow. It’s also nice if I’m organizing cards in a box and I want to make more room. I can now drag cards to push the boundaries.

let store =
  document.querySelector("#app").__vue_app__.config.globalProperties.$store;

let currentCardId = "";
let previousCardId = "";
let isDraggingCardId = "";

let intervalId = setInterval(() => {
  let isCardDetailsOpen = document.querySelector(".card-details");

  if (
    isCardDetailsOpen &&
    isCardDetailsOpen.getAttribute("data-card-id") != currentCardId
  ) {
    previousCardId = currentCardId;
    currentCardId = isCardDetailsOpen.getAttribute("data-card-id");
    document.dispatchEvent(
      new CustomEvent("cardEditEnded", { detail: { cardId: previousCardId } })
    );
    document.dispatchEvent(
      new CustomEvent("cardEditStarted", { detail: { cardId: currentCardId } })
    );
  }

  if (!isCardDetailsOpen && currentCardId) {
    previousCardId = currentCardId;
    currentCardId = "";
    document.dispatchEvent(
      new CustomEvent("cardEditEnded", { detail: { cardId: previousCardId } })
    );
  }

  if (!isDraggingCardId && store.state.currentDraggingCardId) {
    isDraggingCardId = store.state.currentDraggingCardId;
  } else if (isDraggingCardId && !store.state.currentDraggingCardId) {
    document.dispatchEvent(
      new CustomEvent("cardDragEnded", { detail: { cardId: isDraggingCardId } })
    );
    isDraggingCardId = "";
  }
}, 50);

let resizeBoxes = (card) => {
  if (!card) return;

  Object.values(store.state.currentBoxes.boxes).forEach((box) => {
    if (
      card.x + (card.resizeWidth ?? card.width) >= box.x &&
      card.x < box.x + box.resizeWidth &&
      card.y + (card.resizeHeight ?? card.height) >= box.y &&
      card.y < box.y + box.resizeHeight
    ) {
      console.log(
        "📦",
        { card },
        "is inside",
        { box },
        card.x,
        card.resizeWidth,
        box.x,
        box.resizeWidth
      );
      if (
        card.x + (card.resizeWidth ? card.resizeWidth : card.width) >
        box.x + box.resizeWidth - 24
      ) {
        // Handle east
        store.dispatch("currentBoxes/update", {
          ...box,
          resizeWidth: card.x + (card.resizeWidth ?? card.width) + 48 - box.x,
        });
      }
      if (
        card.y + (card.resizeHeight ? card.resizeHeight : card.height) >
        box.y + box.resizeHeight - 24
      ) {
        // Handle south
        store.dispatch("currentBoxes/update", {
          ...box,
          resizeHeight:
            card.y + (card.resizeHeight ?? card.height) + 48 - box.y,
        });
      }
      if (card.x < box.x) {
        store.dispatch("currentBoxes/update", {
          ...box,
          x: card.x - 20,
          resizeWidth: box.resizeWidth + box.x - card.x + 20,
        });
      }
      if (card.y < box.y) {
        store.dispatch("currentBoxes/update", {
          ...box,
          y: card.y - 20,
          resizeHeight: box.resizeHeight + box.y - card.y + 20,
        });
      }
    }
  });
};

document.addEventListener("cardEditStarted", (e) => {
  console.log("🎴", e.type, e.detail.cardId);
  resizeBoxes(store.state.currentCards.cards[e.detail.cardId]);
});

document.addEventListener("cardEditEnded", (e) => {
  console.log("🎴", e.type, e.detail.cardId);
  resizeBoxes(store.state.currentCards.cards[e.detail.cardId]);
});

document.addEventListener("cardDragEnded", (e) => {
  console.log("🎴", e.type, e.detail.cardId);
  resizeBoxes(store.state.currentCards.cards[e.detail.cardId]);
});
3 Likes