My scroll to top button not showing when scrolling

I am trying to implement a “Scroll to top” function on my website. Simply what I have is a button with some JS to make it apear when scrolling and when clicked scroll the user to the top automatically and then disapear. My problem is that the button is not showing when I am scrolling. I also made a parallax hero image thing and I think it was after that the button stopped working.

I would need some help on why the button isn’t showing on scroll and how I can fix it. Here is the HTML, css and JS which I think is causing the trouble. I’ll include an entire snippet below.

<div class="wrapper">
  <header class="parallax">
    <img src="https://cdn.imgpaste.net/2022/10/10/Kem93m.png" class="background" />
    <img src="https://cdn.imgpaste.net/2022/10/10/KemO9N.png" class="foreground" />
    <div class="hero-text">
      <h1>Lagar och säkerhet</h1>
      <p>
        Hemsidan om lagar och säkerhet på internet här står det massa saker wow omg coolt :I
      </p>
    </div>
  </header>
  <main>
    <div class="content">
      <section>
        <h2>Hejehje</h2>
        <p>
          Lorem ipsum dolor sit, amet consectetur adipisicing elit. Magni in aut quisquam ipsa,
          reiciendis quidem rem facilis quaerat nam est! Lorem ipsum dolor sit amet consectetur,
          adipisicing elit. Libero, nulla perferendis? Officia illo vitae alias obcaecati nulla
          porro quisquam, praesentium id vel ex culpa deleniti neque reiciendis officiis nisi
          quaerat.
        </p>
      </section>
      <picture class="img">
        <source media="(min-width: 900px)" srcset="imgs/template1000.jpg" />
        <img src="imgs/template500.jpg" alt="template500" />
      </picture>
    </div>
    <button id="scroll-button" title="Gå till toppen">
      <i class="fas fa-arrow-up"></i>
    </button>
  </main>

Css

#scroll-button {
  display: none;

  position: fixed;
  bottom: 1rem;
  right: 1.2rem;

  z-index: 998;

  border: none;
  outline: none;

  background-color: transparent;
  color: var(--white-color);
  font-size: 1.5rem;

  cursor: pointer;

  border-radius: 50%;
}

.parallax {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  transform-style: preserve-3d;
  z-index: -1;
}

.background {
  transform: translateZ(-10px) scale(2);
  -webkit-user-drag: none;
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
}

.foreground {
  transform: translateZ(-5px) scale(1.5);
  -webkit-user-drag: none;
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
}

.background,
.foreground {
  position: absolute;
  height: 100%;
  width: 100%;
  object-fit: cover;
  z-index: -1;
}

.hero-text {
  text-align: center;
  color: var(--white-color);

  position: absolute;
  top: 50%;
  left: 50%;

  min-width: 14rem;

  transform: translate(-50%, -50%);
}

.hero-text > h1 {
  font-size: 3rem;
}

.hero-text > p {
  font-size: 1rem;
}

JS

button = document.getElementById("scroll-button");

button.addEventListener("click", topFunction);

window.onscroll = function () {
  scrollFunction();
};

function scrollFunction() {
  if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
    button.style.display = "block";
  } else {
    button.style.display = "none";
  }
}

function topFunction() {
  window.scrollTo({
    top: 0,
    left: 0,
    behavior: "smooth",
  });
}

$(document).ready(function () {
  // Hamburger
  $(".burger-container").click(function () {
    $(".nav-menu").toggleClass("menu-opened");
    $("body").toggleClass("unscrollable");
  });

  // Dark-Light switcher
  $("body").toggleClass("light", localStorage.toggled == "light");

  document.getElementById("checkBox").addEventListener("click", darkLight);

  function darkLight() {
    if (localStorage.toggled != "light") {
      $("body").toggleClass("light", true);
      localStorage.toggled = "light";
    } else {
      $("body").toggleClass("light", false);
      localStorage.toggled = "";
    }
  }

  if ($("body").hasClass("light")) {
    $("#checkBox").prop("checked", true);
  } else {
    $("#checkBox").prop("checked", false);
  }
});

// Scroll to top
button = document.getElementById("scroll-button");

button.addEventListener("click", topFunction);

window.onscroll = function () {
  scrollFunction();
};

function scrollFunction() {
  if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
    button.style.display = "block";
  } else {
    button.style.display = "none";
  }
}

function topFunction() {
  window.scrollTo({
    top: 0,
    left: 0,
    behavior: "smooth",
  });
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* Dark colors */
:root {
  --white-color: #d9d9d9;
  --black-color: #0d0d0d;

  --grey-color-1: #595959;

  --body-bg-color: #262626;

  --text-hover-color: #a6a6a6;
}

/* Light colors */
:root .light {
  --body-bg-color: #dfdfdf;

  --black-color: blue;
  --white-color: black;
}

/* ======== MAIN CSS ======== */

html {
  width: 100%;
  height: 100%;
}

body {
  width: 100%;
  height: 100%;

  background-color: var(--body-bg-color) !important;

  position: relative;

  overflow: hidden;

  font-family: "Nunito", sans-serif;
  color: var(--white-color);
}

main {
  background-color: var(--body-bg-color);
}

.wrapper {
  height: 100vh;
  overflow-y: auto;
  overflow-x: hidden;
  perspective: 10px;
}

.top {
  z-index: 999;

  position: sticky;
  top: 0;
  left: 0;

  width: 100%;

  transition: 0.5s ease;
}

nav {
  position: sticky;
  top: 0;
  z-index: 999;
  width: 100vw;
  height: 3.5rem;
  background-color: var(--black-color);
}

.unscrollable {
  overflow: hidden;
}

.active {
  text-decoration: underline;
}

/* ======= PARALLAX ======= */

.parallax {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  transform-style: preserve-3d;
  z-index: -1;
}

.background {
  transform: translateZ(-10px) scale(2);
  -webkit-user-drag: none;
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
}

.foreground {
  transform: translateZ(-5px) scale(1.5);
  -webkit-user-drag: none;
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
}

.background,
.foreground {
  position: absolute;
  height: 100%;
  width: 100%;
  object-fit: cover;
  z-index: -1;
}

.hero-text {
  text-align: center;
  color: var(--white-color);

  position: absolute;
  top: 50%;
  left: 50%;

  min-width: 14rem;

  transform: translate(-50%, -50%);
}

.hero-text > h1 {
  font-size: 3rem;
}

.hero-text > p {
  font-size: 1rem;
}

/* ======== HAMBURGER ======== */

.burger-container {
  position: absolute;
  right: 1rem;
  top: 0.1rem;

  display: inline-block;

  height: 50px;
  width: 50px;

  transform: rotate(0deg);
  transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99);
  user-select: none;

  z-index: 999;

  -webkit-tap-highlight-color: transparent;
}

#burger {
  position: relative;
  top: 50%;

  width: 18px;
  height: 8px;

  display: block;

  margin: -4px auto 0;
}

.bar {
  position: relative;

  width: 100%;
  height: 1px;

  display: block;

  background: var(--white-color);

  transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99);
  transition-delay: 0s;
}

.topBar {
  transform: translateY(0px) rotate(0deg);
}

.btmBar {
  transform: translateY(6px) rotate(0deg);
}

.menu {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;

  padding: 0;
  background: var(--black-color);
  height: 100%;

  list-style: none;
}

.menu-item {
  transform: translateY(-200px);
  transition: transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 1);
}

.menu-item a {
  display: block;
  position: relative;

  color: var(--white-color);
  font-family: "Roboto", sans-serif;
  font-weight: 300;
  text-decoration: none;
  font-size: 1.3rem;
  line-height: 2.35;

  border-bottom: 1px solid var(--body-bg-color);

  width: 100%;
}

.menu-item a:hover {
  color: var(--text-hover-color);
  text-decoration: none;
}

.nav-menu {
  height: 3.5rem;
  transition: height 0.4s;
}

.nav-menu.menu-opened {
  transition: height 0.4s;

  position: absolute;
  top: 0;

  height: 100vh;
  width: 100vw;
}

.nav-menu.menu-opened .burger-container {
  transform: rotate(90deg);
}

.nav-menu.menu-opened .burger-container #burger .bar {
  transition: all 0.4s cubic-bezier(0.4, 0.01, 0.165, 0.99);
  transition-delay: 0.2s;
}

.nav-menu.menu-opened .burger-container #burger .bar.topBar {
  transform: translateY(4px) rotate(45deg);
}

.nav-menu.menu-opened .burger-container #burger .bar.btmBar {
  transform: translateY(3px) rotate(-45deg);
}

.nav-menu.menu-opened ul.menu li.menu-item {
  transform: scale(1) translateY(0px);
}

/* ======== Dark Light switcher ====== */

.switcher > span {
  color: var(--white-color);
  padding: 0 0.5rem;
  font-size: 1.3rem;
}

.switcher {
  display: flex;
  align-items: center;
}

.toggler-container {
  display: block;
  margin-top: 1rem;
  transform: translateY(-200px);
  transition: transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 1);
}

.nav-menu.menu-opened ul.menu li.toggler-container {
  transform: scale(1) translateY(0px);
}

.switch {
  position: relative;
  align-self: center;

  display: inline-block;

  width: 3.2rem;
  height: 1.5rem;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;

  cursor: pointer;

  background-color: #808080;

  -webkit-transition: 0.4s;
  transition: 0.4s;

  border-radius: 1rem;
}

.slider:before {
  position: absolute;
  left: 4px;
  bottom: 4px;

  content: "";

  height: 1rem;
  width: 1rem;

  background-color: var(--white-color);

  -webkit-transition: 0.4s;
  transition: 0.4s;

  border-radius: 50%;
}

input:checked + .slider {
  background-color: #808080;
}

input:checked + .slider:before {
  -webkit-transform: translateX(1.7rem);
  -ms-transform: translateX(1.7rem);
  transform: translateX(1.7rem);
}

/* ======== CONTENT ======= */

.content {
  text-align: center;
  margin: 0 5% 0 5%;
  padding-top: 1.5rem;
  color: var(--white-color);
}

.content h2 {
  font-size: 1.4rem;
  font-family: "Roboto", sans-serif;
}

.content p {
  font-size: 1.1rem;
  font-family: "Nunito", sans-serif;
}

.img {
  display: block;
}

/* ======== UP ARROW ========*/

#scroll-button {
  display: none;

  position: fixed;
  bottom: 1rem;
  right: 1.2rem;

  z-index: 998;

  border: none;
  outline: none;

  background-color: transparent;
  color: var(--white-color);
  font-size: 1.5rem;

  cursor: pointer;

  border-radius: 50%;
}

/* ======== FOOTER ======== */

footer {
  padding: 3rem 0 6rem 0;
  background-color: var(--grey-color-1);
  position: sticky;
  bottom: 0;
  z-index: -2;
}

footer ul {
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: center;
  font-size: 1.3rem;
}

footer ul a {
  color: var(--white-color);
  text-decoration: none;
}

footer ul li {
  display: block;
  padding: 0.25rem 0;
}

footer ul a:hover {
  color: var(--text-hover-color);
}

footer hr {
  color: var(--text-hover-color);
  max-width: 13rem;
  margin: 1.5rem auto;
}

footer .copyright {
  margin-top: 1rem;
  text-align: center;
  font-size: 0.75rem;
  color: var(--text-hover-color);
}

/* ======== MEDIA QUERIES ======== */

/* TABLET */
@media only screen and (min-width: 600px) {
  /* ======= FOOTER ======= */
  footer ul {
    font-size: 1.1rem;
  }

  footer ul li {
    display: inline-block;
    padding: 0 0.2rem;
  }

  footer hr {
    max-width: 35rem;
  }
}

/* DESKTOP */
@media only screen and (min-width: 769px) {
  /* ======== MAIN CSS ======== */

  .top {
    overflow: hidden;
  }

  .hero-text {
    position: absolute;
    top: 40%;
    left: 30%;
    max-width: 20rem;
  }

  .hero-text > h1 {
    font-size: 3.5rem;
  }

  .hero-text > p {
    font-size: 1.2rem;
  }

  /* ======= Scrollbar ======== */
  ::-webkit-scrollbar {
    width: 7px;

    background: transparent;
  }

  ::-webkit-scrollbar-thumb {
    border-radius: 100px;

    background: rgb(109, 109, 109);
  }

  ::-webkit-scrollbar-thumb:hover {
    background-color: rgb(148, 148, 148);
  }

  /* ======== HAMBURGER ======== */
  nav {
    width: 100%;

    background-color: var(--black-color);
    backdrop-filter: none;
  }

  .nav-menu {
    transition: all 0.3s ease-in, 0.5s ease-in;
    transition-delay: 0.25s;

    width: 100%;
    height: 3.5rem;

    display: flex;
    align-items: center;
  }

  .nav-menu.menu-opened {
    height: 100%;
  }

  .burger-container {
    display: none;
  }

  .menu-item {
    transform: scale(1) translateY(0px);

    display: inline;

    margin-right: 0.8rem;
    border-bottom: 0;
    margin-top: 0;
  }

  .menu {
    flex-direction: row;

    position: absolute;
    top: 0;

    margin: 0 0 0 1.5rem;

    height: 3.5rem;
    width: 100%;
  }

  .menu-item a {
    display: inline;

    border: none;

    font-size: 1rem;

    transition: all 0.15s cubic-bezier(0.54, 0.12, 0.54, 0.94);
  }

  .flex-filler {
    flex: 1 1 auto;
  }

  /* ======== Dark-light switcher ======== */

  .toggler-container {
    display: block;
    margin: 0 2.5rem 0 0;
    transform: scale(1) translateY(0px);
  }

  .switcher > span {
    font-size: 1.2rem;

    padding: 0 0.4rem;
  }

  .switch {
    width: 2.5rem;
    height: 1.3rem;
  }

  .slider:before {
    height: 0.8rem;
    width: 0.8rem;

    left: 4px;
    bottom: 4px;
  }

  input:checked + .slider:before {
    -webkit-transform: translateX(1.2rem);
    -ms-transform: translateX(1.2rem);
    transform: translateX(1.2rem);
  }

  /* ======== CONTENT ========*/

  .content {
    margin: 0 20% 0 20%;
    padding-top: 2rem;
  }

  .content h2 {
    font-size: 1.5rem;
  }

  .content p {
    font-size: 1.15rem;
  }

  /* ======== UP ARROW ========*/

  #scroll-button {
    position: fixed;

    height: 3rem;
    width: 3rem;

    bottom: 1.1rem;
    right: 1.1rem;
  }

  #scroll-button:hover {
    background-color: rgba(160, 160, 160, 0.568);
    backdrop-filter: blur(15px);
  }

  /* ======= FOOTER ======= */
}

/* XL-DESKTOP */
@media only screen and (min-width: 1200px) {
  /* ======= HAMBURGER ======= */

  .menu-item {
    margin-right: 1.3rem;
  }

  .menu-item a {
    font-size: 1.1rem;
  }

  /* ======= FOOTER ======= */
  footer ul {
    font-size: 1.2rem;
  }

  footer ul li {
    padding: 0 0.4rem;
  }

  footer hr {
    max-width: 40rem;
  }
}
<!DOCTYPE html>
<html lang="sv">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Lagar och säkerhet | Hem</title>
    <link rel="stylesheet" href="css/style.css" />
    <link
      href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"
      rel="stylesheet"
    />
    <link
      href="https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;0,1000;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900;1,1000&display=swap"
      rel="stylesheet"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
      rel="stylesheet"
    />
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"
    />
    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@48,400,0,0"
    />
    <script defer src="js/script.js"></script>
  </head>
  <!--
    Att göra: 
    
    Fixa bilder till Hero parallax
    Skriva content
    Fixa bilder till content (Picture element, bootstrap)
    Lägga in all content på index och subpages (Bootstrap)
    Fixa up arrow så den funkar
    Tablet responsive media query
    Hamburger close animation (Inte prio)
  -->
  <body>
    <div class="top">
      <nav>
        <div class="nav-menu">
          <div class="burger-container">
            <div id="burger">
              <div class="bar topBar"></div>
              <div class="bar btmBar"></div>
            </div>
          </div>
          <ul class="menu">
            <li class="menu-item"><a href="#">Hem</a></li>
            <li class="menu-item"><a href="html/losenord.html">Lösenord</a></li>
            <li class="menu-item">
              <a href="html/sakerhetshot.html">Säkerhetshot</a>
            </li>
            <li class="menu-item">
              <a href="html/statlig-kontroll.html">Statlig kontroll</a>
            </li>
            <li class="menu-item">
              <a href="html/tredjepartskod.html">Tredjepartskod</a>
            </li>
            <li class="menu-item">
              <a href="html/webbhotell.html">Webbhotell</a>
            </li>
            <div class="flex-filler"></div>
            <li class="toggler-container">
              <div class="switcher">
                <span class="material-symbols-outlined"> dark_mode </span>
                <label class="switch">
                  <input type="checkbox" id="checkBox" />
                  <span class="slider"></span>
                </label>
                <span class="material-symbols-outlined"> light_mode </span>
              </div>
            </li>
          </ul>
        </div>
      </nav>
    </div>
    <div class="wrapper">
      <header class="parallax">
        <img src="https://cdn.imgpaste.net/2022/10/10/Kem93m.png" class="background" />
        <img src="https://cdn.imgpaste.net/2022/10/10/KemO9N.png" class="foreground" />
        <div class="hero-text">
          <h1>Lagar och säkerhet</h1>
          <p>
            Hemsidan om lagar och säkerhet på internet här står det massa saker wow omg coolt :I
          </p>
        </div>
      </header>
      <main>
        <div class="content">
          <section>
            <h2>Hejehje</h2>
            <p>
              Lorem ipsum dolor sit, amet consectetur adipisicing elit. Magni in aut quisquam ipsa,
              reiciendis quidem rem facilis quaerat nam est! Lorem ipsum dolor sit amet consectetur,
              adipisicing elit. Libero, nulla perferendis? Officia illo vitae alias obcaecati nulla
              porro quisquam, praesentium id vel ex culpa deleniti neque reiciendis officiis nisi
              quaerat.
            </p>
          </section>
          <picture class="img">
            <source media="(min-width: 900px)" srcset="imgs/template1000.jpg" />
            <img src="imgs/template500.jpg" alt="template500" />
          </picture>
        </div>
        <button id="scroll-button" title="Gå till toppen">
          <i class="fas fa-arrow-up"></i>
        </button>
      </main>
      <footer>
        <ul class="list">
          <li>
            <a href="#" class="active">Hem</a>
          </li>
          <li>
            <a href="html/losenord.html">Lösenord</a>
          </li>
          <li>
            <a href="html/sakerhetshot.html">Säkerhetshot</a>
          </li>
          <li>
            <a href="html/statlig-kontroll.html">Statlig kontroll</a>
          </li>
          <li>
            <a href="html/tredjepartskod.html">Tredjepartskod</a>
          </li>
          <li>
            <a href="html/webbhotell.html">Webbhotell</a>
          </li>
        </ul>
        <hr />
        <p class="copyright">Copyright &copy; All rights reserved by Vincent Cornelius</p>
      </footer>
    </div>
  </body>
</html>

Getting null after updating the state in Reactjs

I’m building a drag-and-drop web app using reactjs. The issue I’m facing is when I start the drag, it fires the handleDragStart function to update the selectedCard state variable, but when I try to access this variable(selectedCard) inside the handleDrop function, it logs null in the console.

My question is how I can get access to the selectedCard variable inside the handleDrop function?

My Code:

import { useState } from "react";

const Panel = ({ data }) => {
  const { title, label, items } = data;
  const [selectedCard, setSelectedCard] = useState(null);

  const handleDragStart = (item) => {
    setSelectedCard(item);
  };
  const handleDrop = (colName, id) => {
    console.log(selectedCard);
  };

  const handleDragOver = (e) => {
    e.preventDefault();
  };

  return (
    <div className="w-56">
      <h2 className="mb-4">{title}</h2>
      <ul className="flex flex-col space-y-4">
        {items.map((item) => (
          <li key={item.id}>
            <button
              id={item.id}
              className="px-4 py-2 border w-full text-left cursor-grab"
              onDragStart={() => handleDragStart(item)}
              onDrop={() => handleDrop(label, item.id)}
              onDragOver={handleDragOver}
              draggable
            >
              {item.name}
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default Panel;

Converting date from string to input type date format

I have an HTML input type of “datetime-local” which I then store in a Datetime field in a MS SQL Server database. When I load the edit page I want to populate this HTML date field with the value from the database. When I console out the value of the date it is:
“Tue May 16 2023 15:40:00 GMT+0200 (South Africa Standard Time)”.
Has anyone successfully converted a string like this to the accepted HTML date input format with Javascript?

ag-grid Pie Chart make some items invisible initially

I am using ag-grid to create Pie Charts in Angular. I am following this URL for API documentation : https://www.ag-grid.com/angular-charts/pie-series/

I want to hide some items initially. (I know I can hide the entire series using “visible: false”). I only want some items to be hidden initially. The user can then click on the legend of the hiden item and toggle the item ON if needed.

For e.g. in the following data, I want Android and iOS to be invisible initially

export function getData() {
    return [
        { label: 'Android', value: 56.9 },
        { label: 'iOS', value: 22.5 },
        { label: 'BlackBerry', value: 6.8 },
        { label: 'Symbian', value: 8.5 },
        { label: 'Bada', value: 2.6 },
        { label: 'Windows', value: 1.9 },
    ];
}

My use case is as follows. We have 8 items/sectors in the chart. We have millions of count in the 3 success states, and there are only few counts in the other 5 error/warning state. The chart looks mostly green with just thin lines for error states. Most users are only interested in errors and they have to manually turn off success states by clicking on the legend to only focus on error states. So, I want to turn off the success states initially, and if any one wants to see the success states they can click on the legend and turn them on.

I tried using multiple series, listeners, etc. But the API documentation does not clearly state how to set the initial state of the item in the legend.

Uncaught SyntaxError: Javascript Module

Uncaught SyntaxError: import declarations may only appear at top level of a module

I have created a new .js file where I imported previous functions from main .js file.
I imported it all from one direction so I thought the problem is not found. I have tried to add a attribute type with value module, it appeared me this problem: —
Uncaught TypeError: The specifier “.” was a bare specifier, but was not remapped to anything. Relative module specifiers must start with “./”, “../” or “/”.

This is the index.js file sourcing in index.html which contains all functions

<script src="index.js"></script>

This is the products.js file calling into products.html which is importing into it functions

<script src="products.js"></script>
import { checkRegex, addAnimation, increaseByHeight, timeout } from "./index";

window.onload = () => {
    const watch = document.querySelector('.watch')
    const items = document.querySelectorAll('.item')

    timeout(3000, setInterval(() => {
        items.forEach((item, idx) => {
            addAnimation(item, 'animated', 1)
        })
    }, 500))
}

So i need to prevent the problem which is happening while importing the functions.

WebGPU Rust and Javascript communication

I incorporate WebGPU+Rust in the following way

(index.html)

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>GreenMatterAI graphics preview</title>
    <style>
        canvas {
            background-color: black;
        }
    </style>
</head>

<body id="wasm-example">
<script type="module">
      import init from "./pkg/gmai_cad.js";
      init().then(() => {
          console.log("WASM Loaded");
      });
  </script>
</body>

</html>

(lib.rs)

#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))]
pub async fn run() {
    cfg_if::cfg_if! {
        if #[cfg(target_arch = "wasm32")] {
            std::panic::set_hook(Box::new(console_error_panic_hook::hook));
            console_log::init_with_level(log::Level::Warn).expect("Couldn't initialize logger");
        } else {
            env_logger::init();
        }
    }

    let event_loop = EventLoop::new();
    let window = WindowBuilder::new().build(&event_loop).unwrap();
    #[cfg(target_arch = "wasm32")]
    {
        use winit::dpi::PhysicalSize;
        window.set_inner_size(PhysicalSize::new(450, 400));

        use winit::platform::web::WindowExtWebSys;
        web_sys::window()
            .and_then(|win| win.document())
            .and_then(|doc| {
                let dst = doc.get_element_by_id("wasm-example")?;
                let canvas = web_sys::Element::from(window.canvas());
                dst.append_child(&canvas).ok()?;
                Some(())
            })
            .expect("Couldn't append canvas to document body.");
    }
    let mut state = State::new(window).await;
    event_loop.run(move |event, _, control_flow| match event {
        Event::RedrawRequested(window_id) if window_id == state.window().id() => {
            state.update();
            state.render()
        }
        Event::MainEventsCleared => {
            state.window().request_redraw();
        }
        Event::WindowEvent {
            ref event,
            window_id,
        } => { state.event(event) },
        _ => {}
    });
}

The way this code is structured there is no way I could pass any data from Javascript to the render loop. I want to have some HTML inputs that user can modify and affect the rendering interactively. The only thing that comes to my mind is to have a global mutable variable and expose a few Rust functions that Javascript could use to modify those variables. Of course that’s a clear Rust anti-pattern. What’s the canonical way of going about this?

Realm data type for dynamic key name pair and values

I am working with realm flexible sync in react native and i want to define schema for below json where key names are dynamic objectId and has set of properties so i tried dictionary and mixed but didn’t worked.
Also this group_taxes would have n of key values.

{
    "group_taxes": {
        // This one is dynamic object id as key which holds properties
        "63bbb1372aea3a5f887b4d0e": {
            "tax_id": {
                "$oid": "63bbb1372aea3a5f887b4d0e"
            },
            "tax_name": "CGST",
            "tax_rate": 10,
            "calculated_tax": 44,
            "tax_calculation": "PERCENTAGE"
        },
        "63bbb1372aea3a5f887b4d10": {
            "tax_id": {
                "$oid": "63bbb1372aea3a5f887b4d10"
            },
            "tax_name": "SGST",
            "tax_rate": 20,
            "calculated_tax": 20,
            "tax_calculation": "FLAT_VALUE"
        }
    }
}

What i tried to define in schema as below but didn’t worked

{
  "group_taxes" : {
    "bsonType": "mixed"
  }
}

Need help finding tools for micro-frontends architecture

(Please apologize in advance for my poor english, they are typos and mistakes in this topic)

I’m currently working in a company where we want to change the dev ecosystem. The main product of the company is a PWA app wich provide a lot of services. The problem is that this app has 10 years of technical debt and has become unmaintainable. The old devs are gonne and we are a new team handling the project.

The lead dev want to rebuild (piece by piece) the app with a micro-frontend architecture inside a monorepo. The goal is to have an “app shell” cache-served (we still need to be in a PWA) that loads and displays the micro-frontends.

We can’t do this in a single one monolothic app like before because the services we provide are very dense and are going to have each their own database.

So I reached this article wich was pretty interesting. The architecture is exactly what we are looking for. And then, after few other research I found TurboRepo. As I told, our lead dev want to use a monorepo for this project (and I kind of agree with him). So my question is :

Is it possible only with TurboRepo ?

I mean, I feel like Module Federation (in Webpack, from the article) are equivalent to Workspaces (in TurboRepo). They both call internal packages like they will do with external ones (like those available on npm).

BUT, I have two main questions that triggers me :

1 – Is the architecture described in the previous article doable with TurboRepo (one app shell displaying child dependencies) ? Is it just a matter of project architecture and TurboRepo settings tweeking ?

2 – In the article, they setup something that allow to display each individual micro-frontend in dev mode but not in production. Are those things also a matter of configuration ?

I am kind of new to all of those concepts, I only worked on ‘simple’ projects before, so I don’t get everything.
I based all my topic around the article I linked because it kind of describes the things I want, but webpack is hard to work with (and a bit slow compared to other bundlers like vite or turbopack ?). So I wanted to give TurboRepo a try.
But am I mixing everything ? Monorepos, micro-frontend architecture, bundling, etc. ?

Thank you if you reached the bottom of this topic ! I’ll wait impatiently for your answers.

How to pass props to styled component without converting them to transient props?

I have created a Text component which receives couple of props. These props are passed to the styled component, where styles are applied. I dont want to pass props to the DOM, I only want to access them inside styled component.

Converting props to transient props works, but it creates repeating code which I think makes the whole component unnecessarily bigger.

I would like to know, how to pass some props to my styled component without passing them to the DOM and without having to redefine every prop. I tried using shouldForwardProps but I cant get it to work with Typescript.

type Props = {
  children: React.ReactNode;
  size: number;
  height: number;
  color: string;
};

const StyledText = styled.p<{ $color: string; $size: number; $height: number }>`
  color: ${({ $color }) => $color};
  font-size: ${({ $size }) => `${$size}px;`};
  line-height: ${({ $height }) => `${$height}px;`};
  ...
`;

const Text: React.FC<Props & React.HTMLAttributes<HTMLParagraphElement>> = ({ children, size, height, color, ...rest }) => {
  return (
    <StyledText $size={size} $height={height} $color={color} {...rest}>
      {children}
    </StyledText>
  );
};

Best practice for using an external library on the window object

In my code I rely on an external library which I expect to be loaded on the window object on the pages where my snippet is going to be running. My code looks like the following:

if (window.ats) {
        window.ats.retrieveEnvelope(function (envelope: string) {
          console.log('Located ATS.js');
          this.cachedEnvelope = JSON.parse(envelope).envelope;
        });
}

ats is the name of the library which I depend on. Locally this failed since ats is not one of the usual window properties. In order to make it compile and also be able to mock it in my tests, I created the following override:

declare global {
  interface Window {
    ats?: any;
  }
}

I am wondering if this is the standard way to go about a situation like this. This (1) does make the code compile (2) should be able to allow the code identify the ats on a production environment and (3) allow mocking in the specs.

I am not a Javascript expert and I’d like to know if there’s a better/standard way to address the aforementioned situation.

Refining understanding of typescript module resolution and configuration in a monorepo

I have a monorepo (npm workspaces) with typescript 4.7 installed in all my packages.
The repo:

root
  apps
    nestjs
      tsconfig.json
    cloud_functions
      tsconfig.json
    frontend (vue3)
      tsconfig.json
  packages
    types
      tsconfig.json
      package.json
    config
      tsconfig.json
      package.json

The use case is simple, I want to import constants from the config package and types from the types one.

The imports of types work fine but the imports of constants are causing me a lot of grief.

All my 3 consumers tsconfig.json files already have this:

{
  "extends": "@app/tsconfig/tsconfig.base.json",
  "compilerOptions": {
    "rootDir": ".",
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@app/types": ["../../packages/types"],
      "@app/config": ["../../packages/config"]
    }
    //... other options

  },
  
  "references": [
    { "path": "../../packages/types/tsconfig.json" },
    {
      "path": "../../packages/config/tsconfig.json"
    }
   //... other options
  ]
}

NestJS and Cloud Functions are by default CommonJS friendly, i.e:

 "compilerOptions": {
    "module": "CommonJS",
    "moduleResolution": "Node",
   // ... stuff
}

When Vue 3 is EsNext friendly:

 "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "Node",
   // ... stuff
}

Vue 3 default tsconfig comes out of the box with the "esModuleInterop": true flag set.

Changing the module value to ESNext for NestJS breaks things, so I need to stick to CommonJS.

At this stage, my understanding of the situation is that the “references” set in the consumers help the compiler resolve the dependencies without having to import them as dependencies or devDependencies, and do a fine job at doing that for types.

However, the constants (config), i.e, are javascript code, and therefore need extra love to be consumed seamlessly by consumers who have different expectations, namely the CommonJS vs ES6 module dilemma.

My config/tsconfig.json is currently defined like so:

{
  "extends": "@app/tsconfig/tsconfig.base",
  "compilerOptions": {
    "esModuleInterop": true,
    "module": "CommonJS",
    "target": "es6",
    "skipLibCheck": true,
    "allowSyntheticDefaultImports": true,
    "types": ["node"]
  },
  "include": ["./index.ts", "./src/**/*.ts"],
  "display": "Config"
}

And its package.json like so:

{
  "name": "@app/config",
  "version": "0.0.1",
  "license": "MIT",
  "scripts": {
    "build": "tsc -b"
  },
  "exports": "./index.js",
  "types": "index.d.ts",
  "private": true
}

My expectation was that by exporting to a commonjs module format, Vue, with the esModuleInterop": true would be able to happily import the config constants. But instead it is giving me this error: /packages/config/index.js' does not provide an export named 'CASL_SUBJECT_ACCOUNT'

And clearly, it is not because what I have instead is this:
Object.defineProperty(exports, "CASL_SUBJECT_ACCOUNT", { enumerable: true, get: function () { return casl_1.CASL_SUBJECT_ACCOUNT; } });

I have tried also to not export .js files at all (i.e emitDeclarationOnly: true) and rely on each consumer to compile the files to its needs but that only created different issues.

So my questions at this stage are:

  • can I actually rely on “references” to not have to import packages as dependencies
  • do I actually have to generate javascript files in my config package?
  • do I need to export my constants as .cjs, .mjs files to please the consumers OR can I rely on some baked in config options from typescript (e.g esModuleInterop)
  • What changes can I bring to the config above to fix the existing issues?

Thanks,

How to run a website locally if it immediately opens a link to the original page after opening the HTML file? [closed]

I do not know if anyone is able to help me but I downloaded the website files to run it locally and test a few things but there is one problem because when I run the website without js, everything starts normally from the html file but once I connect the script so that everything on the website works , then immediately after opening the html file, it launches the original page, even though I didn’t even find a link to this page in the code. Does anyone know why this is happening?

I checked the code and I really can’t find anything that could be responsible for this, and I need to check something on the site locally

Finding the average within a table

I’m expected to create an html page for a car dealership using JQuery and Bootstrap 5. I’m supposed to use Bootstrap 5 to perform the following:

Create a table with appropriate form input elements that allow the user to enter four (4)
quarterly sales for three (3) sales representatives of a local automobile business. The
figures should be stored in a two-dimensional array. Once the figures are entered, the
program should have a BS5 button to display the following – in the table or below the
table:
− The total sales for each quarter
− The average sales for each sales representative
− The sales representative with the highest sales for each quarter

Here is what I have so far:

<!DOCTYPE html>
<html>
<head>

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
        <script> 
        $(document).ready(function(){
          $("#flip").click(function(){
            $("#panel").slideDown("slow");
          });
        });
        </script>
        
                    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
            
            
            

        <style>
        
        
        
            #panel, #flip {
              padding: 5px;
              text-align: center;
              background-color: red;
              border: solid 1px white;
             
            }

            #panel {
              padding: 50px;
              display: none;
            }

            #logo {
                text-align: left;
                padding: 50px;
                
            .center {
                  margin: auto;
                  width: 60%;
                  border:none;
                  padding: 10px;
                  
            }
                
            
            
            
            

        </style>
</head>
<body style="background-color: black;">

    <script>
        function calculate(){
            quarters=['Quarter 1','Quarter 2','Quarter 3','Quarter 4'];
            
            var sales = new Array(3); //Array with 3 rows
            sales[0]=[];  
            sales[1]=[];
            sales[2]=[];
            
            var totalSales=[]; 
            
            var s1 = document.getElementsByName('s1[]'); 
            for (var i = 0; i < s1.length; i++) {
                alert("Pushing"+s1[i].value);
                sales[0].push(s1[i].value);
            }
            
            var s2 = document.getElementsByName('s2[]'); 
            for (var i = 0; i < s2.length; i++) {
                //alert("Pushing"+s2[i].value);
                sales[1].push(s2[i].value);
                
                
            }
            
            var s3 = document.getElementsByName('s3[]'); 
            for (var i = 0; i < s3.length; i++) {
                //alert("Pushing"+s3[i].value);
                sales[2].push(s3[i].value);
            }
            
            
            //Total sales for each quarter
                          
            var overall=0;
            for(var col=0; col<sales[0].length;++col)
            {
              var totalQ = 0;
              for (var row=0; row<sales.length; ++row) 
              {
                totalQ += parseInt(sales[row][col]); 
                //alert("sales[row][col]"+sales[row][col]);
                overall += parseInt(sales[row][col]);  
                
              }
              totalSales.push(totalQ);
              //alert("Candidate's Total="+totalVote[col]);
              
              document.getElementsByName('total[]')[col].value=totalQ; 
              
            }

            alert("Overall="+overall);


            //Winner in each precinct  

            for (var row=0; row<sales.length; ++row)
            {
                highest=parseInt(sales[row][0]);///reset the maximum each time
                //alert(highest);
                for(var col=0; col<sales[0].length;++col)
                {
                  if (parseInt(sales[row][col])>highest)
                    highest = parseInt(sales[row][col]);
                }
                //alert("Highest votes in row "+(row+1)+"="+highest);
                var repRow = "high"+(row+1);
                //alert("Precinct="+precinctID);
                document.getElementById(repRow).value=highest;
            }


            //Show winner, votes, and percentage
            //alert("Highest total votes="+ Math.max(...totalVote));
            var currMax= parseInt(totalSales[0]);
            //alert("Initial max="+currMax);
            var maxPos=0;
            //alert(maxPos);

            for (var i=0; i< totalSales.length; ++i)
            {
               if (totalSales[i] > currMax)
                 {
                   currMax = parseInt(totalSales[i]);
                   //alert("CurrentMax="+currMax);
                   maxPos=i;
                 }
            }
            
            //Finding the average sale of each representative
            
            
            for (var row=0; row<sales.length; ++row)
            {
                var totalperRep = 0; //reset
                
                for (var col=0; col<sales.length[0]; ++col)
                {
                    totalperRep += parseInt(sales[row][col]);
                    var saleRow = "avg"+(row+1);
                    
                    

                }
                document.getElementById(saleRow).value = totalperRep;
                    
                    var average = totalperRep/sales.length[0];
                    
                    document.getElementById(average).value = totalperRep;
            }   
                
                
            
            
            
            
        }//end function

    </script>

<div id="logo"><img src="logo/33574391656_af96565fed.jpg" alt= "Autolist logo" width="350" height="133"></div>
<div id="flip"><span style="font-weight:bold;"> Click here to see description </span></div>
<div id="panel"><p>As an automotive dealership, we match our buyers to thousands of used car sites so that you won't even have to search.<br>
From your first car to your fifteenth, we want to make buying and selling a car something you can look forward to. We’re taking a data 
driven and user centric approach to create new and better ways to buy and sell cars.<p></div>


    <div class="container">
      <h2 style="color:white"><strong>Quarterly Sales</strong></h2>
                
      <table class="table table-bordered" style="color:white";>
        <thead>
          <tr>
            <th>Dealership</th>
            <th>Representative</th>
            <th>Quarter 1</th>
            <th>Quarter 2</th>
            <th>Quarter 3</th>
            <th>Quarter 4</th>
            <th>Highest sale per rep</th>
            <th>Average sales per rep </th>
            
            
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Carmax in Laurel, MD</td>
            <td>John Malcavech</td>
            <td><input style="color:red;" type="number" name="s1[]"></td>
            <td><input style="color:red;" type="number" name="s1[]"></td>
            <td><input style="color:red;" type="number" name="s1[]"></td>
            <td><input style="color:red;" type="number" name="s1[]"></td>
            <td><input style="color:red;" type="text" name="high1" id="high1" readonly></td> 
            <td><input style="color:red;" type="text" name="avg1" id="avg1" readonly></td> 
          </tr>
          <tr>
            <td>MERCEDES-BENZ OF SILVER SPRING</td>
            <td>Moses Aran</td>
            <td><input style="color:red;" type="number" name="s2[]"></td>
            <td><input style="color:red;" type="number" name="s2[]"></td>
            <td><input style="color:red;" type="number" name="s2[]"></td>
            <td><input style="color:red;" type="number" name="s2[]"></td>
            <td><input style="color:red;" type="text" name="high2" id="high2" readonly></td> 
            <td><input style="color:red;" type="text" name="avg2" id="avg2" readonly></td> 
          </tr>
          <tr>
            <td>Hertz Car Sales Baltimore</td>
            <td>Rachet C. Clinton</td>
            <td><input style="color:red;" type="number" name="s3[]"></td>
            <td><input style="color:red;" type="number" name="s3[]"></td>
            <td><input style="color:red;" type="number" name="s3[]"></td>
            <td><input style="color:red;" type="number" name="s3[]"></td>
            <td><input style="color:red;" type="text" name="high3" id="high3" readonly></td> 
            <td><input style="color:red;" type="text" name="avg3" id="avg3" readonly></td> 
          </tr>
          
          <tr>
            <td>Total Sales</td>
            <td>-----</td>
            <td><input style="color:red;" type="text" name="total[]" readonly></td>
            <td><input style="color:red;" type="text" name="total[]" readonly></td>
            <td><input style="color:red;" type="text" name="total[]" readonly></td>
            <td><input style="color:red;" type="text" name="total[]" readonly></td>
            <td>-----</td>
            <td>-----</td>
          </tr>
          
          
          
        </tbody>
      </table>
      
        <div class="center">
            <button type="button" onclick="calculate()">Calculate</button>
        </div>
    </div> 
    
    


        
</body>

If you run the above code on a browser, you should see that I was successful in displaying the total sales for each quarter and the sales representative with the highest sales for each quarter.

The part I’m stuck on, however, is finding the average sales of each representative. Whenever, I run the program, no values are displayed in the readonly textbox in the “Average sales per rep” column.

Here’s the part of my calculate function that is supposed to find the average sales of each rep:

//Finding the average sale of each representative

        1 for (var row=0; row<sales.length; ++row)
        2 {
        3   var totalperRep = 0; //reset
        4   
        5   for (var col=0; col<sales.length[0]; ++col)
        6   {
        7       totalperRep += parseInt(sales[row][col]);
        8       var saleRow = "avg"+(row+1);
        9   
        10      
                    11
                    12
        13  }
        14  document.getElementById(saleRow).value = totalperRep;
        15      
        16      var average = totalperRep/sales.length[0];
        17      
        18      document.getElementById(average).value = totalperRep;
        19     }    

Lines 1 and 5 represent a row major. It’s supposed to allow the program to scan through the sales, one column at a time, and reset totalperRep variable with the current value selected. It should keep adding to the values stored in totalperRep until the row.length and col.length has reached their limit. As shown in line 8, the variable saleRow should call on the Id with the following characters: “avg” and move to the next value in a row. As shown on line 16 the total amount saved in totalperRep should be divided by the sales.length, which should be 4. Because saleRow is calling on the id “avg”, and because of document.getElementById(average).value shown on line 18, every element in the table with that id should be displayed in input (readonly) textbox.
For example: <input style=”color:red;” type=”text” name=”avg2″ id=”avg2″

But again, when I run the program, the textboxes under the very last column show up completely blank. I don’t understand why that’s the case. It should be at least displaying values, if not give me the correct calculations. Can someone please help figure this out, or offer any suggestions?

video is not being shown in mobile in safari,firefox and chrome but works well on desktop

I have a website that has video on header, it works fine on desktop except mobile,
I am using next.js 13.4 and this is my code:

<video
        id="background-video"
        autoPlay
        playsInline
        loop
        muted
        className="absolute left-0 top-0 w-[100%] h-[100%] object-cover -z-2"
      >
        <source
          src={"./header-webm.webm"}
          type="video/webm"
        />
      </video>

also I tried this but again is not working:

 <div
        className="absolute left-0 top-0 w-[100%] h-[100%] -z-2 "
        dangerouslySetInnerHTML={{
          __html: `<video
           id="background-video"
           autoPlay
           playsInline
           loop
           style="width: 100%; height: 100%; object-fit: cover;"
         >
           <source
             src="./header-webm.webm"
           />
         </video>`,
        }}
      ></div>

also I tried this approach

https://medium.com/@BoltAssaults/autoplay-muted-html5-video-safari-ios-10-in-react-673ae50ba1f5

but with this the video is not being shown even in chrome desktop.
I got confused ,what is the problem?