Infinite Marquee with gradient text

I need to make an endless running line with gradient text that changes as it moves, as in the example, it works, but there are problems in Safari, everything twitches there and the letters seem to run into each other, maybe something can be done so that it also works in Safari without freezes. Maybe there are other solutions for such an implementation.

Example marquee

document.querySelectorAll('.running-lines__wrapper').forEach(
  (line) => {
    const content = line.innerHTML;
    const duplicateCount = line.getAttribute('data-duplicate-count') || 1;
    const duration =
      parseInt(line.getAttribute('data-duration'), 10) || 10000;
    const direction = line.getAttribute('data-direction') || 'normal';
    let duplicatedContent = '';

    for (let i = 0; i < duplicateCount; i++) {
      duplicatedContent += content;
    }

    line.innerHTML = duplicatedContent;

    const lineText = line.querySelectorAll('.running-lines__items');

    lineText.forEach((text) => {
      const fromFrame = {
        textIndent: 0
      };
      const toFrame = {
        textIndent: '-100%'
      };
      const options = {
        duration,
        iterations: Infinity,
        direction
      };
      text.animate([fromFrame, toFrame], options);
    });
  });
.running-lines {
  font-family: "Poppins";
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
  row-gap: 0.5rem;
  overflow: hidden;
  background-image: linear-gradient(92.55deg,
      #852fff 0%,
      #dd26ed 48.5%,
      #ed2662 100%);
  -webkit-background-clip: text;
  background-clip: text;
  padding-top: 4rem;
  padding-bottom: 4rem;
  mix-blend-mode: lighten;
}

@media (min-width: 956px) {
  .running-lines {
    row-gap: 1rem;
    padding-top: 3.5rem;
    padding-bottom: 3.5rem;
  }
}

@media (min-width: 1184px) {
  .running-lines {
    row-gap: 1.25rem;
  }
}

.running-lines__wrapper {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  padding-top: 0.625rem;
  padding-bottom: 0.625rem;
}

.running-lines__items {
  margin-bottom: 0;
  text-wrap: nowrap;
  will-change: text-indent;
  /*   animation: marquee 15s linear infinite; */
}

.running-lines__item {
  margin-right: 2rem;
  font-size: 1.25rem;
  line-height: 1.5rem;
  font-style: italic;
  color: transparent;
}

@media (min-width: 956px) {
  .running-lines__item {
    margin-right: 3rem;
    font-size: 1.5rem;
    line-height: 2rem;
  }
}

@media (min-width: 1184px) {
  .running-lines__item {
    margin-right: 4rem;
  }
}

@keyframes marquee {
  from {
    text-indent: 0;
  }

  to {
    text-indent: -100%;
  }
}
<div class="running-lines">
  <div class="running-lines__wrapper" data-duration="28000" data-duplicate-count="7">
    <p class="running-lines__items">
      <span class="running-lines__item">Security Kit</span>
      <span class="running-lines__item">Honeypot</span>
      <span class="running-lines__item">Antibot</span>
      <span class="running-lines__item">Flood Control</span>
      <span class="running-lines__item">Move 403 to 404</span>
      <span class="running-lines__item">Rabbit Hole</span>
      <span class="running-lines__item">Username Enumeration Prevention</span>
    </p>
  </div>
  <div class="running-lines__wrapper" data-duration="50000" data-direction="reverse" data-duplicate-count="7">
    <p class="running-lines__items">
      <span class="running-lines__item">Content Moderation</span>
      <span class="running-lines__item">Workflows</span>
      <span class="running-lines__item">Simple Menu Permissions</span>
      <span class="running-lines__item">Group Node</span>
      <span class="running-lines__item">Scheduler</span>
      <span class="running-lines__item">Media</span>
    </p>
  </div>
  <div class="running-lines__wrapper" data-duration="40000" data-duplicate-count="7">
    <p class="running-lines__items">
      <span class="running-lines__item">Paragraphs & Paragraphs Browser</span>
      <span class="running-lines__item">Group</span>
      <span class="running-lines__item">Gin & Gin Toolbar</span>
      <span class="running-lines__item">Crop & Image Widget Crop</span>
      <span class="running-lines__item">Migrate & Migrate Plus</span>
    </p>
  </div>
</div>

Can I get fillable PDF form value using Angular?

I got a particular scenario ๐Ÿ™

I need to show a fillable PDF file to the user in an angular app, once that the user fills all the fields, I need to get the base64 string or byte array of that file (with all fields filled by the user), to upload it in a server using node api.

Did I explain correctly my problem?
Anyone could give me a hand?
๐Ÿ™

I tried to use different libraries like pdf-js, but I couldn’t get what I need.

I also tried to get the data of the filled fields as json object to then fill a blank file and after that upload it, yes I know, a very strange scenario but I’m desperate XD

How to css links grouped in on file to a single html file?

I am developing a project and it requieres lots of css link tags. after using so many link my html files looks to clustered and hard to read.

Is there any way to store all the link tags in a single seperate file and import that file in index html file using only single line?

i tried using imports it was not working

React Native PDF – Single Page Styling Issues (alignment)

Problem

I’m using react-native-pdf in my React Native application to display PDF documents. I’ve encountered two issues that only happen when displaying a PDF with a single page:

  1. The single page appears centered instead of starting at the top of the container
  2. The borderRadius styles I’ve applied to the PDF component aren’t working for single-page PDFs

When the PDF has 2 or more pages, everything works as expected – the first page starts at the top of the container and the borderRadius is properly applied.

Code
Here’s my implementation:

import React, { useEffect, useState } from 'react';
import { SafeAreaView, ScrollView, View } from 'react-native';
import Pdf from 'react-native-pdf';

export function DocumentViewerScreen() {
  const [pdfUrl, setPdfUrl] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    // Simulated data loading
    const loadDocument = async () => {
      try {
        // In real app, we'd fetch the PDF from an API
        // This is just for demo purposes
        setPdfUrl('https://example.com/sample.pdf'); // Or your base64 data URI
        setIsLoading(false);
      } catch (error) {
        setIsLoading(false);
      }
    };
    loadDocument();
  }, []);

  if (isLoading) {
    return <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }} />;
  }

  return (
    <SafeAreaView style={{ flex: 1 }}>
      <ScrollView
        style={{ flex: 1 }}
        showsVerticalScrollIndicator={false}
        contentContainerStyle={styles.scrollViewContent}>
        <View style={{ height: 60 }}>
          {/* Header placeholder */}
        </View>
        <View style={styles.pdfContainer}>
          {pdfUrl && (
            <Pdf
              trustAllCerts={false}
              source={{
                uri: pdfUrl,
              }}
              style={styles.pdf}
            />
          )}
        </View>
      </ScrollView>
      <View style={styles.buttonContainer}>
        {/* Share button placeholder */}
      </View>
    </SafeAreaView>
  );
}

And here are my styles:

import { BorderRadius } from '@foundation/config';
import { ColorPalette } from '@foundation/config/colorPalette';
import { getScreenHeight, getScreenWidth } from '@foundation/helpers';
import { StyleSheet } from 'react-native';

export const styles = StyleSheet.create({
  scrollViewContent: {
    gap: getScreenHeight(2.5),
    paddingBottom: getScreenHeight(6.4),
    alignItems: 'center',
    flexGrow: 1,
  },
  pdfContainer: {
    flex: 1,
    height: '100%',
    flexDirection: 'column',
    display: 'flex',
    borderWidth: 1,
  },
  pdf: {
    flex: 1,
    width: getScreenWidth(94),
    height: '100%',
    maxHeight: getScreenHeight(100),
    flexDirection: 'column',
    display: 'flex',
    overflow: 'scroll',
    backgroundColor: ColorPalette.BackgroundPrimary,
    borderRadius: BorderRadius.Large,
    borderWidth: 1,
  },
  buttonContainer: {
    position: 'absolute',
    bottom: getScreenHeight(4.1),
  },
});

Expected Behavior:

  1. For single page pdf, the document should start from the top of the container, not centered vertically
  2. The borderRadius style should be applied to single page PDF.

Current Behavior

  • Multi-page PDFs: Everything works as expected – pages start from the top and borderRadius is applied
  • Single-page PDFs: The page appears centered vertically in the container and the borderRadius style is not applied

What I’ve Tried

I’ve experimented with:

  1. Different fitPolicy values (0, 1, 2)
  2. Setting singlePage to true/false
  3. Adjusting scale, minScale and various other properties
  4. Various container styling combinations

Question
How can I make single-page PDFs behave the same as multi-page PDFs where they start from the top of the container and properly apply the borderRadius styling?

Image:
enter image description here

Rejection System for Consultancy System

I have an accept/reject system for a consultation request. When a consultation request is sent from a user, on the consultant’s interface, they have the ability to either accept or reject. The accept system is working, however, when rejecting, a popup to enter the rejection reason will open and the database column status will change from pending to rejected, after the reason is typed and entered.

Here is the structure of my table:
enter image description here

However, it’s supposed to get the rejection reason from the popup and insert it into the rejection_reason column, and change the status to rejected. Also, I have a notifictions sytem for the consultant which is supposed to update accordingly (when accepted/rejected, it will change: self-explanatory with code). It’s not working how it’s intended to.

consultant_consult.php:

HTML & Javascript:

  function toggleNotifications() {
        const dropdown = document.getElementById('notificationsDropdown');
        const overlay = document.getElementById('overlay');

        // Toggle Dropdown Visibility
        const isVisible = dropdown.style.display === 'block';
        dropdown.style.display = isVisible ? 'none' : 'block';
        overlay.style.display = isVisible ? 'none' : 'block';

        // If opening, fetch notifications & reset unread count
        if (!isVisible) {
            fetch('consultant_consult.php?fetchConsultations=true')
            .then(response => response.json())
            .then(data => {
                const notificationList = document.getElementById("notification-list");
                notificationList.innerHTML = "";

                if (data.error) {
                    notificationList.innerHTML = `<p style="color: red;">${data.error}</p>`;
                    return;
                }

                if (data.length === 0) {
                    notificationList.innerHTML = `<p style="margin-left: 15px;">Nothing Here!</p>`;
                    return;
                }

                // Display consultations in the dropdown
                data.forEach(consultation => {
                    const consultationHTML = `
                        <div class="notification-item">
                            <p><strong>From:</strong> ${consultation.user_name}</p>
                            <p><strong>Symptoms:</strong> ${consultation.symptoms}</p>
                            <p><strong>Date:</strong> ${consultation.date} | <strong>Time:</strong> ${consultation.time}</p>
                            ${consultation.medical_docs ? `<p><a href="${consultation.medical_docs}" target="_blank">View Medical Documents</a></p>` : ""}
                            <div class="button-group">
                                <button class="accept-btn" onclick="processConsultation(${consultation.id}, 'accept')">Accept</button>
                                <button type='button' class="reject-btn" onclick="openRejectionPopup(${consultation.id})">Reject</button>
                            </div>
                        </div>
                    `;
                    notificationList.innerHTML += consultationHTML;
                });

                // Reset unread count to zero (since the user has now read them)
                unreadNotificationCount = 0;
                document.getElementById("notification-count").innerText = unreadNotificationCount;
            })
            .catch(error => console.error("Error fetching consultations:", error));
        }
    }

    // Fetch notification count on page load
    document.addEventListener("DOMContentLoaded", fetchNotificationCount);

    // Allow clicking on overlay to close the dropdown
    document.getElementById('overlay').addEventListener('click', function() {
        document.getElementById('notificationsDropdown').style.display = 'none';
        this.style.display = 'none';
    });

    function processConsultation(consultationId, action) {
        fetch('process_consult.php', {
            method: "POST",
            headers: { "Content-Type": "application/x-www-form-urlencoded" },
            body: `consultation_id=${consultationId}&action=${action}`
        })
        .then(response => response.text())
        .then(data => {
            alert(data);
            toggleNotifications(); // Refresh Notifications List
        })
        .catch(error => console.error("Error:", error));
    }

  // Rejection Reason and Reject System

  let rejectConsultationId = null;

  function openRejectionPopup(consultationId) {
      rejectConsultationId = consultationId; // Store the consultation ID
      document.getElementById("rejectionPopup").style.display = "flex";
  }

  function closeRejectionPopup() {
      document.getElementById("rejectionPopup").style.display = "none";
  }

  function submitRejection() {
      let reason = document.getElementById("rejectionReason").value.trim();

      if (reason === "") {
          alert("Please provide a reason for rejection.");
          return;
      }

      fetch("process_consult.php", {
          method: "POST",
          headers: { "Content-Type": "application/x-www-form-urlencoded" },
          body: `reject=true&consultation_id=${rejectConsultationId}&rejection_reason=${encodeURIComponent(reason)}`
      })
      .then(response => response.text())
      .then(data => {
          alert(data);
          closeRejectionPopup();
          location.reload(); // Refresh page to update consultations
      })
      .catch(error => console.error("Error:", error));
  }
<!-- Rejection Popup -->
<div id="rejectionPopup" class="popup-overlay">
    <div class="popup-box">
        <h2>Why are you rejecting this patient?</h2>
        <textarea id="rejectionReason" placeholder="Enter reason here..." rows="4"></textarea>
        <button class="reject-confirm-btn" onclick="submitRejection()">Reject</button>
        <button class="close-btn" onclick="closeRejectionPopup()">Cancel</button>
    </div>
</div>

process_consult.php

<?php
session_start();
$dbHost = "localhost";
$dbUser = "root";
$dbPass = "root";
$database = "medconnect";
$connection = mysqli_connect($dbHost, $dbUser, $dbPass, $database) or die ("Connection Failed");

if (!isset($_SESSION['signUpBtn'])) {
    echo "Unauthorized action!";
    exit;
}

if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['consultation_id'], $_POST['action'])) {
    $consultation_id = intval($_POST['consultation_id']);
    $action = $_POST['action'];

    if ($action === "accept") {
        $query = "UPDATE consultations SET status='accepted' WHERE id=$consultation_id";
    } elseif ($action === "reject" && isset($_POST['rejection_reason'])) {
        $rejection_reason = mysqli_real_escape_string($connection, $_POST['rejection_reason']);
        $query = "UPDATE consultations SET status='rejected', rejection_reason='$rejection_reason' WHERE id=$consultation_id";
    } else {
        echo "Invalid action!";
        exit;
    }

    if (mysqli_query($connection, $query)) {
        echo "Consultation $action successfully!";
    } else {
        echo "Error: " . mysqli_error($connection);
    }
}

mysqli_close($connection);
?>

P.S. I’m using alert(data) as debugging to see if any data is recieved, and localhost always alerts blank (nothing), which indicates no data is being recieved itself, which is probably why there is no database update or notifications change taking place like how it’s supposed to.

How do I redirect to an edit page with the ID as a query parameter after form submission in Next.js?

I’m building a book management application using Next.js. I have a form that collects book details and submits them using an asynchronous function (onSubmit). The form data is sent to an action.ts file where it is validated and inserted into a Supabase database. After a successful submission, I want to redirect the user to an edit page while passing the ISBN of the newly submitted book in the URL.

  //submitting the forms
  async function onSubmit(data: BookInferSchema) {
    try {
      const formData = new FormData();
      Object.entries(data).forEach(([key, value]) => {
        formData.append(
          key,
          value instanceof Date ? value.toISOString() : value.toString()
        );
      });

      //sending the formData to the action.ts for submitting the forms
      const response = action(formData) as {
        error?: string;
        message?: string;
      } | void;

      //Error or success messages for any submissions and any errors/success from the server
      if (response?.error) {
        toast({
          title: "Error",
          description: `An error occurred: ${response.error}`,
        });
      } else {
        //after submitting the form, reset the form
        // form.reset();
      }
    } catch {
      toast({
        title: "Error",
        description: "An unexpected error occured.",
      });
    }
  }

And hereโ€™s a snippet of my action.ts where I validate and insert the book into the database:

const validatedFields = BookSchema.safeParse({
  ISBN: formData.get("ISBN"),
  //...other fields
});

if (!validatedFields.success) {
  console.error("Validation Errors:", validatedFields.error.format());
  return {
    errors: validatedFields.error.flatten().fieldErrors,
  };
}

const { ISBN } = validatedFields.data;

const supabase = createClient();
const { data, error } = await (await supabase)
  .from('books')
  .insert({
    isbn: ISBN,
    // ... other fields
  });

if (error) {
  return {
    error: true,
    message: error.message,
  };
}

return {
  error: false,
  message: 'Book updated successfully',
};

What I tried:

I tried returning the ISBN:

const successMessage = {
    error: false,
    message: "Book updated successfully",
    ISBN,
  };

return successMessage;

and use it here inside a !response?.error and it would just show as undefined when checking for the value of the response.

2nd try:
I put this code in the action.ts after submissions:

// Perform the redirect after returning the success message
  redirect(`/admin/books/${ISBN}/edit`);

But it would show this an application error, and this is what the console would redirect me with: https://nextjs.org/docs/messages/sync-dynamic-apis

This is the edit book page link: /admin/books/${id}/edit:

I am sure that I can access this page as I am also handling a redirect page for viewing each book.

const BookEdit = async (props: { params: Promise<{ id: string }> }) => {
  const supabase = await createClient();

  const {
    data: { user },
  } = await supabase.auth.getUser();

  if (!user) {
    return redirect("/login");
  }

  const params = await props.params;
  const id = params.id;

  const books = await fetchAllBooks(id);
  const bookData = books ? books[0] : null;

  return <h1>Edit Book {JSON.stringify(bookData, null, 2)}</h1>;
};

export default BookEdit;

Problem importing GLTF model in Three.js: Lights not working properly

I have been trying to import a GLTF model into Three.js, but I’m encountering several issues. When I import my scene with all the elements, the lights do not work as expected. The directional lights I configured in Blender (using the Eevee engine) do not appear correctly in Three.js.

Context:

  • I exported my model from Blender in GLTF/GLB format with all materials and textures.
  • I am using Three.js to render the scene.
  • The lights are imported as Object3D instead of DirectionalLight.

Code:

Here is the code I am using to load the model and set up the lights:

import * as THREE from "three";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { ModelViewerProps } from "./types";

export class ModelViewer {
  private _container: HTMLDivElement | null;
  private _scene: THREE.Scene = new THREE.Scene();
  private _camera: THREE.PerspectiveCamera;
  private _renderer: THREE.WebGLRenderer;
  private _controls?: OrbitControls;

  constructor(props: ModelViewerProps) {
    this._container = props.container;

    this._renderer = new THREE.WebGLRenderer({ antialias: true });
    this._renderer.setPixelRatio(window.devicePixelRatio);
    this._renderer.setSize(window.innerWidth, window.innerHeight);
    this._renderer.shadowMap.enabled = true;
    this._renderer.toneMapping = THREE.ACESFilmicToneMapping;
    this._renderer.toneMappingExposure = 1.25;
    this._renderer.setClearColor(0x000000, 1);

    this._camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      0.1,
      1000
    );
    this._camera.position.set(0, 2, 5);

    if (props.useOrbitControls) {
      this._controls = new OrbitControls(
        this._camera,
        this._renderer.domElement
      );
    }

    this.loadModel(props.modelPath);

    if (this._container) {
      this._container.appendChild(this._renderer.domElement);
    }

    window.addEventListener("resize", this.onWindowResize.bind(this));
    this.animate();
  }

  private loadModel(url: string) {
    const loader = new GLTFLoader();
    loader.load(
      url,
      (gltf) => {
        this._scene.add(gltf.scene);
        if (gltf.cameras.length > 0) {
          if (gltf.cameras[0] instanceof THREE.PerspectiveCamera) {
            this._camera = gltf.cameras[0];
          }
        }
      },
      (xhr) => {
        console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
      },
      (error) => {
        console.error(error);
      }
    );
  }

  private onWindowResize() {
    const width = window.innerWidth;
    const height = window.innerHeight;

    this._camera.aspect = width / height;
    this._camera.updateProjectionMatrix();

    this._renderer.setSize(width, height);
  }

  private animate() {
    requestAnimationFrame(() => this.animate());
    if (this._controls) {
      this._controls.update();
    }
    this._renderer.render(this._scene, this._camera);
  }
}

This is how the scene looks in Blender:
enter image description here

JSON.parse fails with quotation in template literal

I’m using Editor.js (which saves the HTML blocks as JSON) to create content on my website and it works great unless there is a " in the JSON value.

Data insertion works correctly, but when editing entries containing escaped double quotes (") within JSON values, JavaScript’s JSON.parse fails. For example:

j = JSON.parse(`{"data": "<a href="https://www.google.com/">Google</a>"}`);

The above would not parse and will say:

SyntaxError: JSON Parse error: Expected '}'

I’ve tried with just single quotes and that doesn’t work either. I’ve checked if the JSON is valid and jsonlint.com says both the JSON I generated with Editor.js is valid and the JSON above is valid.

What am I doing wrong? Again, everything works if as long as I don’t have an escaped quote (") in the JSON.

JavaScript json.parse fails on “

I’m using Editor.js (which saves the HTML blocks as JSON) to create content on my website and it works great unless there is a ” in the JSON value. So if I enter a quote or add a link, which puts the URL in quotes, it inserts the resulting JSON into PostgreSQL just fine, but when I go to “edit” the entry the data will not load if there is a ” in the JSON values. If I don’t enter a link or any quotes, then it works fine. Again, this data inserts into PostgreSQL just fine in a JSON column, so the JSON is valid, but JavaScript isn’t parsing the data correctly when I do JSON.parse to edit the data. Something isn’t right. I have tried with Safari and Chrome. Chrome actually says which character the error occurs on and I’ve confirmed that the first ” is where the error occurs. Here is an example of the JavaScript:

j = JSON.parse(`{"data": "<a href="https://www.google.com/">Google</a>"}`);

The above would not parse and will say: SyntaxError: JSON Parse error: Expected ‘}’

I’ve tried with just single quotes and that doesn’t work either. I’ve checked if the JSON is valid and jsonlint.com says both the JSON I generated with Editor.js is valid and the JSON above is valid.

What am I doing wrong? Again, everything works if as long as I don’t have an escaped quote (“) in the JSON.

“Why doesn’t `scrollIntoView()` work when clicking a search result to scroll to the corresponding product in the main list?”

React SearchBar: Scroll to Clicked Product Not Working

I’m trying to create a search bar that filters products and scrolls to the selected product when clicked. However, the scrolling does not work. The element does not scroll into view when I click a search result.

What I Tried

  • Used useRef(new Map()) to store product references dynamically.
  • Called scrollIntoView({ behavior: "smooth", block: "center" }) inside handleProductClick.
  • Added useEffect to reset the refs when products change.

Expected Behavior

  • When I click a search result, the corresponding product should smoothly scroll into view.

Actual Behavior

  • Clicking a search result does not scroll to the product.

My Code

import { useState, useRef, useEffect } from "react";
import searchIcon from "../assets/icons/search-icon.png";

const SearchBar = ({ products }) => {
    const [query, setQuery] = useState("");
    const filteredProducts = products.filter((product) =>
        product.name.toLowerCase().includes(query.toLowerCase())
    );

    const productRefs = useRef(new Map()); // Store refs using Map()

    useEffect(() => {
        productRefs.current = new Map(); // Reset refs when list updates
    }, [products]);

    const handleProductClick = (id) => {
        const element = productRefs.current.get(id); // Get element from Map
        if (element) {
            element.scrollIntoView({
                behavior: "smooth",
                block: "center",
            });
        }
        setQuery(""); // Clear search
    };

    return (
        <div className="flex w-full pl-3 max-w-xs sm:max-w-md md:max-w-lg relative">
            <input
                type="text"
                className="bg-amber-50 w-3/4 h-9 md:h-10 pl-3 rounded-bl-md rounded-tl-md text-sm focus:outline-0 md:font-semibold"
                placeholder="Search"
                value={query}
                onChange={(event) => setQuery(event.target.value)}
            />
            <button className="bg-[#FEBD69] flex items-center rounded-br-md rounded-tr-md cursor-pointer focus:outline-0 h-9 md:h-10 p-2">
                <img className="w-4 md:w-8" src={searchIcon} alt="Search" />
            </button>
            {query && filteredProducts.length > 0 && (
                <ul className="flex flex-col gap-5 absolute bg-amber-50 top-10 md:top-13 rounded-md shadow-lg p-2 max-h-60 overflow-y-auto border-1 border-gray-300">
                    {filteredProducts.map((product) => (
                        <li
                            key={product.id}
                            ref={(el) => productRefs.current.set(product.id, el)} // Store ref in Map
                            className="p-2 w-70 md:w-full flex items-center gap-2 md:gap-5 max-h-8 md:max-h-10 text-sm md:font-semibold cursor-pointer mt-4 duration-200 hover:opacity-80"
                            onClick={() => handleProductClick(product.id)}
                        >
                            {product.name} - <img className="max-w-7" src={product.image} alt="" />
                        </li>
                    ))}
                </ul>
            )}
        </div>
    );
};

export default SearchBar;

How to toggle :root –color-scheme light/dark from pinia with vuetify?

I recently added custom light/dark color schemes to a Vuetify app and the user can toggle between them and that works well, except for one thing: the scroll bar color doesn’t change. In browser dev tools I traced it down to this bit of CSS:

:root {
    color-scheme: dark;
}

If I switch to the light theme, that CSS is still there, still set to dark, and the scroll bar remains dark. If I uncheck it in dev tools, it turns light.

I couldn’t find anything in Vuetify that addressed this, so I figured I’d do it myself. I change the theme with a pinia store, and I figured on the switch to light I’d grab the root and adjust it. But from my pinia store function, document.documentElement is null:

  function toggleDark() {
    dark.value = !dark.value
    console.log(document.documentElement) // prints null
    if (!dark.value) {
      document.documentElement.style.setProperty('--color-scheme', 'light')
    }
  }

Why is :root’s color-scheme still set to dark after I change the theme to a light theme in Vuetify? And how can I fix it?

Versions:

    "@vueuse/core": "^12.8.2",
    "pinia": "^3.0.1",
    "vue": "^3.5.13",
    "vue-router": "^4.5.0",
    "vuetify": "^3.7.15"

Why react-native tiptop navigation doesn’t work correctly on IOS platform?

I’m currently learning to work with React Native, and I’m a little stuck on the topic of navigation between pages. Specifically, I’m currently figuring out the “Top Tab Navigator”. As you can see in the image, I created 3 navigation items “Statistics”, “Achivements” and “Challenges”, and each of them has corresponding components. According to my idea, when a user enters, for example, the “Statistics” page, the application should display the inscription “Statistics Screen”. And by the same logic, all other pages should work. But for some reason, the ‘Statistics’ page displays the contents of the ‘Challanges’ page, and the other two pages are not displayed at all. And the strangest thing is that this is only on IOS, which is where I’m currently working. Just for the sake of an experiment, I ran the same code, without the slightest changes, on Android and everything works correctly there, as I wanted. Tell me, what could this be connected with?

[enter image description here](https://i.sstatic.net/DUyRWi4E.png)
[enter image description here](https://i.sstatic.net/EDVHzRXZ.png)
[enter image description here](https://i.sstatic.net/BKQu9Hzu.png)

I’ve tried a lot of things already. Tried using “SafeAreaView”, tried deleting and reinstalling expo, tried reinstalling dependencies, updated all packages and technologies that I used in the project, changed the phone versions in the simulator (starting from iPhone 15 and ending with iPhone 15 Pro Max), even asked ChatGPT to help, but still nothing helps.

Just in case, here is my ‘TopTap’ file code:

    import React from "react";
    import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs";
    import Statistics from "../screens/Statistics"
    import Achievements from "../screens/Achievements";
    import Challenges from "../screens/Challenges";
    import { StyleSheet } from "react-native";
    import { SafeAreaView } from "react-native-safe-area-context";
       
    const Tab = createMaterialTopTabNavigator();
    
    const TopTap = () => {
      return (
        <SafeAreaView style={styles.container}>
          <Tab.Navigator
            initialRouteName="Statistics"
            screenOptions={{
              swipeEnabled: true,
              animationEnabled: false,
              lazy: true,
              tabBarIndicatorStyle: { backgroundColor: "blue" },
              tabBarStyle: {
                elevation: 0,
                shadowOpacity: 0,
              },
            }}
          >
            <Tab.Screen name="Statistics" component={Statistics} />
            <Tab.Screen name="Achievements" component={Achievements} />
            <Tab.Screen name="Challenges" component={Challenges} />
          </Tab.Navigator>
        </SafeAreaView>
      );
    };
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        margin: 10,
      },
    });
    export default TopTap;

How to make a calendar with editable events (users can’t access)

I am working on a project where I want to include a calendar with upcoming events and activities. I was able to find some code for a basic calendar, but I can’t figure out how to add events to specific days.

Here is my code currently. It’s working as expected, and I can move from month to month, but I’m not sure how I can add events to specific days (it should be the same days each month). I was considering using a forEach loop, but I’m not sure how to implement

HTML:

 `<!--Events Calendar-->
    <div id="eventsBody">
      <div class="calendar-container">
        <header class="calendar-header">
          <p class="calendar-current-date"></p>
          <div class="calendar-navigation">
            <span id="calendar-prev" class="material-symbols-rounded">
              chevron_left
            </span>
            <span id="calendar-next" class="material-symbols-rounded">
              chevron_right
            </span>
          </div>
        </header>

        <div class="calendar-body">
          <ul class="calendar-weekdays">
            <li>Sun</li>
            <li>Mon</li>
            <li>Tue</li>
            <li>Wed</li>
            <li>Thu</li>
            <li>Fri</li>
            <li>Sat</li>
          </ul>
          <ul class="calendar-dates"></ul>
        </div>
      </div>
      <script src="eventsCalendar.js"></script>
    </div>

Javascript:
    let date = new Date();
    let year = date.getFullYear();
    let month = date.getMonth();

    const day = document.querySelector(".calendar-dates");

    const currdate = document.querySelector(".calendar-current-date");

    const prenexIcons = document.querySelectorAll(".calendar-navigation span");

    // Array of month names
    const months = [
      "January",
      "February",
      "March",
      "April",
      "May",
      "June",
      "July",
      "August",
      "September",
      "October",
      "November",
      "December",
    ];

    // Function to generate the calendar
    const manipulate = () => {
      // Get the first day of the month
      let dayone = new Date(year, month, 1).getDay();

      // Get the last date of the month
      let lastdate = new Date(year, month + 1, 0).getDate();

      // Get the day of the last date of the month
      let dayend = new Date(year, month, lastdate).getDay();

      // Get the last date of the previous month
      let monthlastdate = new Date(year, month, 0).getDate();

      // Variable to store the generated calendar HTML
      let lit = "";

      // Loop to add the last dates of the previous month
      for (let i = dayone; i > 0; i--) {
         lit += `<li class="inactive">${monthlastdate - i + 1}</li>`;
      }

      // Loop to add the dates of the current month
      for (let i = 1; i <= lastdate; i++) {
        // Check if the current date is today
        let isToday =
          i === date.getDate() &&
          month === new Date().getMonth() &&
          year === new Date().getFullYear()
            ? "active"
            : "";
        lit += `<li class="${isToday}">${i}</li>`;
      }

      // Loop to add the first dates of the next month
      for (let i = dayend; i < 6; i++) {
        lit += `<li class="inactive">${i - dayend + 1}</li>`;
      }

      // Update the text of the current date element
      // with the formatted current month and year
      currdate.innerText = `${months[month]} ${year}`;

      // update the HTML of the dates element
      // with the generated calendar
      day.innerHTML = lit;
    };

    manipulate();

    // Attach a click event listener to each icon
    prenexIcons.forEach((icon) => {
      // When an icon is clicked
      icon.addEventListener("click", () => {
        // Check if the icon is "calendar-prev"
        // or "calendar-next"
        month = icon.id === "calendar-prev" ? month - 1 : month + 1;

    // Check if the month is out of range
    if (month < 0 || month > 11) {
      // Set the date to the first day of the
      // month with the new year
      date = new Date(year, month, new Date().getDate());

      // Set the year to the new year
      year = date.getFullYear();

      // Set the month to the new month
      month = date.getMonth();
    } else {
      // Set the date to the current date
      date = new Date();
    }

    // Call the manipulate function to
    // update the calendar display
    manipulate();
  });
});

How can I change this code so that when the user clicks cancel on the pop up the link does not open?

I am extremely new to JavaScript but I am tackling a project to make a google chrome extension that detects when a user clicks a link and asks them whether or not they want to continue. The issue is that currently when the pop-up appears, the link will open regardless of which option the user picks. This is the code I am currently working with.

// detects when the user clicks. 
document.addEventListener("click", function(event) {

    //checks if a user clicks on a hyperlink specifically. 
    const target = event.target.closest("a")

    //This section makes it so the link is not immediately opened. 
    if (target) {event.preventDefault();
        
        // Makes the pop up and shows the full link to the user, they decide if they want to proceed.
if (confirm("You clicked on a link!"+"nAre you confident you want to proceed?nnn" + target.href)) {
            window.location.href = target.href;
        }
    }
}, true);

I’ve looked through a few different forums and FAQs for a good answer but I haven’t seen anyone with the same problem. I have messed with the
window.location.href = target.href;}}}, true); phrase a bit but I cant seem to figure out how to fix this in order to make it actually cancel the click on the link when I hit cancel.