iOS Keyboard Blocking Dynamic Bottom Canvas in Vue 3 with Bootstrap 5

IPhone Keyboard block Bootstrap 5 Bottom Canvas

Describe the issue

I’m building a Vue 3 project with Bootstrap 5, and I’ve implemented a dynamic bottom canvas (offcanvas) where users can add and interact with content. However, on iPhones, when the keyboard pops up (e.g., during form input), it blocks the bottom canvas, preventing the content from being displayed or accessed properly.

I’ve tried using CSS solutions like position: fixed;, bottom: 0;, and overflow: auto;, but they didn’t resolve the issue. The problem seems specific to iOS handling of fixed-position elements when the keyboard is active.

Has anyone faced a similar issue with iOS keyboards and dynamic bottom canvases? Any suggestions or workarounds would be greatly appreciated!

my code

<template>
  <TransitionGroup
    enter-active-class="animate__animated animate__slideInUp animate__faster"
    leave-active-class="animate__animated animate__slideOutDown"
    :duration="45"
  >
    <div
      v-for="(modal, index) in modalStore.modals"
      :key="index"
      :class="['offcanvas', 'offcanvas-bottom', { show: modal.isOpen }]"
      data-bs-backdrop="false"
      tabindex="-1"
      aria-labelledby="offcanvasBottomLabel"
      :style="{ height: modal.height }"
    >
      <!-- Modal Header -->
      <!-- <div class="offcanvas-header" v-if="modal.props.title">
        <h5 class="offcanvas-title">{{ modal.props.title }}</h5>
      </div> -->
      <!-- Modal Body -->
      <component :is="modal.component" v-bind="modal.props"></component>

      <!-- Modal Footer (conditionally rendered) -->
      <div class="offcanvas-footer" v-if="modal.showFooter == true">
        <div class="d-grid">
          <button
            type="button"
            class="modal-close-btn"
            @click="closeModal(modal.name)"
            aria-label="Close"
          >
            <i class="fa-solid fa-chevron-down"></i>
          </button>
        </div>
      </div>
    </div>
  </TransitionGroup>
  <!-- Conditionally Render Backdrop -->
  <div
    v-if="modalStore.modals.length > 0"
    class="offcanvas-backdrop fade show"
    @click="handleBackdropClick"
  ></div>
</template>

<script>
import { useModalStore } from "../../../libs/store/modalStore";

export default {
  setup() {
    const modalStore = useModalStore();

    const closeModal = (name) => {
      modalStore.closeModal(name);
    };

    // Backdrop click handler
    const handleBackdropClick = () => {
      // Get the most recent modal (top-most on the stack)
      const currentModal = modalStore.modals[modalStore.modals.length - 1];

      // Close the modal if `closeOverlay` is not explicitly false
      if (currentModal.props.closeOverlay !== false) {
        closeModal(currentModal.name);
      }
    };

    return {
      modalStore,
      closeModal,
      handleBackdropClick,
    };
  },
};
</script>

i try adding this to script but still didnt work

    const adjustModalForIOSKeyboard = () => {
      const modalElement = document.querySelector(".offcanvas-bottom");

      if (!modalElement) return;

      const onKeyboardShow = (event) => {
        // Get the keyboard height from the event (iOS provides it)
        const keyboardHeight = event?.keyboardHeight || 300; // Fallback height

        // Adjust modal height to avoid being blocked by the keyboard
        modalElement.style.height = `calc(100vh - ${keyboardHeight}px)`;
      };

      const onKeyboardHide = () => {
        // Reset modal height when the keyboard is hidden
        modalElement.style.height = "100%";
      };

      // Listen to iOS-specific keyboard events
      window.addEventListener("keyboardDidShow", onKeyboardShow);
      window.addEventListener("keyboardDidHide", onKeyboardHide);

      // Fallback for other platforms: focus events
      document.body.addEventListener("focusin", onKeyboardShow); // Simulates `keyboardDidShow`
      document.body.addEventListener("focusout", onKeyboardHide); // Simulates `keyboardDidHide`
    };

    onMounted(() => {
      adjustModalForIOSKeyboard();
    });

    onUnmounted(() => {
      // Cleanup event listeners
      window.removeEventListener("keyboardDidShow", adjustModalForIOSKeyboard);
      window.removeEventListener("keyboardDidHide", adjustModalForIOSKeyboard);
    });

Can I get a json response in google safe browsing v5?

Can I get a json response in google safe browsing v5? As I understand it, protobuf is returned here, is it possible to decrypt it or get json instead? There was a similar question, but that wasn’t answered: question

import crypto from 'node:crypto'
import { getSuffPref } from './getSuffPref.js';
import { canonize } from './canonize.js';


function getHash64(pref) {
    let hash = crypto
        .createHash('sha256')
        .update(pref, 'utf-8')
        .digest();

    return hash.subarray(0, 4).toString('base64');
}

let urls = getSuffPref(canonize('https://dgomeq.loveiswe.com/?utm_source=da57dc555e50572d&s1=196580&s2=2016932&j6=1&s3=64016&click_id=467a4fdaceb2561f8993991750c25be7&ban=other&j1=1&j8=1'))
let finalArr = urls.map(getHash64)

async function checkSiteSafe(hashList) {
    let url = new URL('https://safebrowsing.googleapis.com/v5/hashes:search');
    
    url.searchParams.set('key', 'key');
    for (let pref of hashList) {
        url.searchParams.append('hashPrefixes', pref);
    }

    let response = await fetch(url.toString(), 
    { 
        'method': 'GET',
    });

    return [response.status, await response.text()]
}

checkSiteSafe(finalArr).then(result => console.log(result))

This code returns: [ 200, ‘x12x03b�x02’ ], as I understand it, js is trying to convert protobuf to utf-8 characters, which is why such a strange answer. I also tried using url.searchParams.set(‘alt’, ‘json’) and headers: {‘Accept’: ‘application/json’}, but the first causes an error, and the second does not affect the response in any way. Are there any ways to fix this?

React 19’s use() Hook not functioning as intended with the latest version of Vite

I have recently started a new react project using Vite, and I updated it from React 18.3 (which Vite came with) to React 19 (on react, react-dom and their type modules), as I wish to use the new use() hook as it seems very helpful for reducing code for http requests.

However, when I try run my code, it gets stuck in the Suspense component and starts repeatedly making http requests.

import { Suspense, use } from 'react';
import axios from 'axios';

function App() {
  return (
  <>
    <h1>Hello World!</h1>

    <Suspense fallback={<p>loading</p>}>
      <SteamApiGameCountRequest />
    </Suspense>
  </>);
}

function SteamApiGameCountRequest() {

  const response = use(getGames());

  return (<p>I have {response.response.game_count} games</p>);
}

async function getGames() {
  const res = await axios.get('http://localhost:5173/GetOwnedGames', 
    { 
      params: {
        format: 'json',
        steamid: '76561198194449583'
  }});
  
  return res.data;
}

export default App;

html page stuck in the Suspense fallback component while repeatedly making http requests

I know the issue is unrelated to any of my async code as I have gotten it to work successfully using the useEffect() hook.

import { useEffect, useState } from 'react';
import axios from 'axios';

function App() {
  return (
  <>
    <h1>Hello World!</h1>

    <SteamApiGameCountRequest />
  </>);
}

function SteamApiGameCountRequest() {

  const [response, setResponse] = useState<any>({});
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const getGames = async () => {
      const res = await axios.get('http://localhost:5173/GetOwnedGames', 
        { 
          params: {
            format: 'json',
            steamid: '76561198194449583'
      }});
      
      setResponse(res.data);
      setLoading(false);
    }

    getGames();
  }, []);

  if (loading) {
    return (<p>Loading...</p>);
  } else {
    return (<p>I have {response.response.game_count} games</p>);
  }
}

export default App;

However, there is a lot more boiler-plate code involved and I am planning on using a lot more api calls in my app so it would be nicer if I could use the new hook.

I feel like the answer to this question will most likely be just to use React 18 until Vite updates, as Vite doesn’t currently support React 19, but if I am doing something wrong an answer would be greatly appreciated.

valueChanges is still triggered even when using { emitEvent: false, onlySelf: true }

I would like to change value of FormControl in Angular 12. So I refered to this ticket and none of it helped: ValueChanges on FormControl triggers when Form.enable, even with emitEvent: false

Here is a code:

private subscribeToChanges(): void {
 const controlsToFollow = [
  'useDefaultBrightnessMode',
  'controlLedBrightnessDay',
  'controlLedBrightnessNight',
  'controlDisplayBrightnessDay',
  'controlDisplayBrightnessNight',
  'displayOffToExtendLifetime'
 ];

 controlsToFollow.forEach((controlName) => {
   const control = this.brightnessConfigurationForm.get(controlName) as FormControl;

   if (control) {
     this.asyncSaving.handleFormControlChanges(
       control,
       this.destroy$,
       () => this.saveBrightness()
     );
   }
 });
}
// I would like to set value to formControl without triggering valueChanges.
private resetBrightness(): void {
 this.brightnessConfigurationForm.get('controlLedBrightnessDay')
   .setValue(this.defaultBrightnessDay, { emitEvent: false, onlySelf: true });
 this.brightnessConfigurationForm.get('controlLedBrightnessNight')
   .setValue(this.defaultBrightnessNight, { emitEvent: false, onlySelf: true });
 this.brightnessConfigurationForm.get('controlDisplayBrightnessDay')
   .setValue(this.defaultBrightnessDay, { emitEvent: false, onlySelf: true });
 this.brightnessConfigurationForm.get('controlDisplayBrightnessNight')
   .setValue(this.defaultBrightnessNight, { emitEvent: false, onlySelf: true });
}

There is my method from asyncSaving service:

handleFormControlChanges<T>(
formControl: FormControl,
destroy$: Subject<void>,
onValueChange: (value: T) => void,
customOperators: Array<OperatorFunction<any, any>> = [tap(() => this.setLoading$(true))]): void {
  let composedChanges = formControl.valueChanges;
  for (const op of customOperators) {
    composedChanges = composedChanges.pipe(op);
  }

  composedChanges
    .pipe(
      takeUntil(destroy$),
      tap(() => this.setLoading$(true))
    )
    .subscribe(onValueChange);
}

Maybe there is someone that could help me out with this.

react-google-maps getting bigger when clicked

I have a project when I need to use react-google-maps to display multiples public adresses but I’m to do it so when user click on the wanted location the marker would get bigger

Here is my actual code for the Map/Marker part if someone can help please

      <div className="w-full lg:w-800 h-[800px] mt-20">
        <LoadScript
          googleMapsApiKey="////"
          libraries={["places"]}
        >
          <GoogleMap
            mapContainerStyle={{ width: "100%", height: "100%" }}
            center={selectedLocation}
            zoom={16}
            onLoad={(map) => { mapRef.current = map; }}
            options={{streetViewControl: false}}
          >
            {filteredLocations.map((location, index) => (
              <Marker 
              key={index} 
              position={{ lat: location.lat, lng: location.lng }} 
        icon={{
          path: "M-1.547 12l6.563-6.609-1.406-1.406-5.156 5.203-2.063-2.109-1.406 1.406zM0 0q2.906 0 4.945 2.039t2.039 4.945q0 1.453-0.727 3.328t-1.758 3.516-2.039 3.070-1.711 2.273l-0.75 0.797q-0.281-0.328-0.75-0.867t-1.688-2.156-2.133-3.141-1.664-3.445-0.75-3.375q0-2.906 2.039-4.945t4.945-2.039z",
          fillColor: "#000000",
          fillOpacity: 1,
          scale: 1.5,
        }}
        />
            ))}

What is Traceparent and Request-id Http Request Headers? And why/how does a raw fetch automatically add these while Angular’s HttpClient doesn’t?

I have encountered a peculiar scenario where a the same exact api request using fetch vs Angular’s HttpClient has a difference. Particularly, the Traceparent and Request-id are automatically added by fetch but Angular doesn’t.

Given the fact, I also have used the HttpClient now with the following provider added to the ApplicationConfig:

import { provideHttpClient, withFetch } from '@angular/common/http';
...
provideHttpClient(withFetch())

I was assuming that since HttpClient will use fetch under the hood because of this declaration of provider that is using withFetch, it will carry over the two headers just like a raw fetch would do. But apparently it does not.

So this seems to be a three part question:

  1. What are these headers?
  2. How are these attached by fetch?
  3. Should I file an issue on Angular’s GitHub regarding HttpCLient‘s withFetch not exactly doing what fetch would do?

Niagara launcher animation in react-native animation

I want to implement alphabet selection like the “One-hand friendly” mode in the image below and do it with drag animation in React Native + the reanimated library. I would like to know the math to implement smooth animation while indicating the current alphabet according to touch.

enter image description here

Show pop-up form when visitor comes from utm

I have a problem with a wordpress site with elementor pro that I can’t solve.

Objective:

When the person comes from a Google Ads UTM a specific popup appears with the Google Ads Form, if they come from organic another popup opens with another form.

Specifications / Elements:

WordPress site with the Pro element, and popups from the element itself.

2 different popups, each with a specific form.

What was done:

  1. Installed the “Header Footer Code Manager” plugin

  2. Added the java code, in the footer and header, to appear in “site wide”:


// Verifique o valor do parâmetro UTM 

const utmSource = getURLParameter('utm_source'); 

// IDs dos popups no Elementor 

const popupGoogleId = "19330"; // ID do popup para Google Ads 

const popupOrganicoId = "16228"; // ID do popup para tráfego orgânico 

// IDs dos formulários do Gravity Forms 

const formGoogleId = "38"; // ID do formulário para Google Ads 

const formOrganicoId = "19"; // ID do formulário para tráfego orgânico 

// Exibir o popup correspondente com base no parâmetro UTM 

if (typeof elementorPro !== "undefined" && elementorPro.modules.popup) {   

if (utmSource === 'google_ads') {      // Abre o popup para Google Ads      elementorPro.modules.popup.showPopup({ id: popupGoogleId });    } else {     

// Abre o popup para tráfego orgânico      elementorPro.modules.popup.showPopup({ id: popupOrganicoId });    }  }});</script>```


3) Tests were carried out, and several versions of the code, but only the organic popup appeared, both with the google Ads UTM and the organic one.

Any idea what else could be done?

Thanks

Unicast ipv4 without specify port regex rule

It is not a question to be solved, I will simply leave my solution for javascript in case someone needs it. Of course, if there are better solutions or corrections, don’t hesitate to write them here.

My solution: (?=^(?:(22[0-3]|(?:(2[0-1]d|1[0-9]d|[1-9]d|[0-9])))).((?:(25[0-5]|(?:(2[0-4]|1[0-9]|[1-9]|))[0-9])).){2}(?:(25[0-5]|(?:(2[0-4]|1[0-9]|[1-9]|))[0-9]))$)(?!0.0.0.0)

range between 0.0.0.1 to 223.255.255.255

Bookmarklet or other way to select options that contain a particular word?

I am looking for a solution that will always select a particular entry in any drop down menu that matches a word pattern e.g. “not accept“.

The problem is that website developers use a ton of different ways to hide elements or prevent bookmarklet execution.

Is there any robust and reliable solution for this? Would be open to even a non-JS technology or even a third party software or browser.

events inside addEventListener on a dynamically created element doesn’t work

A div is dynamically created (divFicheProduit), with a button (buttonLeave) inside it which is also dynamically created and added to this div. This button must close the div it is inside. So i bind a click event listener to it, but it doesn’t work. As you can see in the log screen, i’m able to get parent div so the div i want to remove on click, but style properties doesn’t work on it, there is no result even in the console (see console screen). What am i doing wrong ?

$(document).click('.buttonVoirProduit',async()=>{
    console.log('buttonVoirProduit Clicked');
    /*console.log('buttonVoirProduitId Ooutside : ', buttonVoirProduitId);*/
    console.log('buttonId : ', buttonVoirProduitId);
    const divFicheProduit = document.createElement('div');
        divFicheProduit.style.width = '100%';
        divFicheProduit.style.height = '100%';
        divFicheProduit.style.opacity = '80%';
        divFicheProduit.style.background = 'black';
        divFicheProduit.style.display = 'flex';
        divFicheProduit.style.position = 'absolute';
        divFicheProduit.style.left = '50%';
        divFicheProduit.style.transform = `translateX(-50%)`;
        divFicheProduit.style.top = '200px';
        divFicheProduit.id = `ficheProduit${buttonVoirProduitId}`;
        divFicheProduitId = divFicheProduit.id;
        console.log(`divFicheProduitId after buttonVoirProduit clicked : `,divFicheProduitId);

        const buttonLeave = document.createElement('img');
        buttonLeave.src = 'icones/cancel.png';
        buttonLeave.classList.add('buttonLeave');
        buttonLeave.id = `buttonLeave${buttonVoirProduitId}`;
        buttonLeave.style.right = '0px';
        buttonLeave.style.top = '0px';
        buttonLeave.style.cursor = 'pointer';
        buttonLeave.style.zIndex = '1000';
        buttonLeave.style.position = 'absolute';
        buttonLeave.style.width = '25px';
        buttonLeave.style.height = 'auto';
        buttonLeave.style.aspectRatio = 'preserve';
        buttonLeave.style.filter = 'brightness(0) saturate(100%) invert(92%) sepia(3%) saturate(2225%) hue-rotate(339deg) brightness(101%) contrast(91%)';
            
        

        const imgFicheProduit = document.createElement('img');
        imgFicheProduit.style.width = '50%';
        /*divFicheProduit.style.zIndex = '1000';*/
        divFicheProduit.append(buttonLeave);
        
        document.body.appendChild(divFicheProduit);
        
        buttonLeave.addEventListener('click', async() =>{
            console.log('buttonLeave Clicked');
            console.log(buttonLeave);
            const buttonLeaveParent = buttonLeave.parentElement;
            console.log(buttonLeaveParent);
            buttonLeaveParent.style.display = 'none';
        });
        
        
});

console screen :

enter image description here

GSAP rotation animation stops after reversing direction on hover

I am trying to create a continuous rotating text animation using GSAP. The animation should rotate the text 360 degrees continuously. When the mouse hovers over the element, I want to reverse the direction of the animation. However, when the mouse leaves, the animation resumes in the correct direction but it stops instead of continuing the loop.

Here is the CodePen I created to demonstrate the issue:
(https://codepen.io/developpeur-the-animator/pen/pvzLvJX)

What I want to achieve:

The text should rotate continuously in one direction.
When hovering over the element, the rotation direction should reverse.
When the mouse leaves, the rotation should continue in the normal direction without stopping.

The problem:

The animation correctly reverses direction on hover, but it stops and does not continue looping in the reverse direction.

My code:

// GSAP timeline
let tlRotatingText;

function rotatingTextAnimation() {
    // Add class 'display'
    $('.circle').addClass('display');
    
    // Check if the timeline already exists
    if (tlRotatingText) {
        return; // Do nothing if it already exists
    }

    // Create a GSAP animation with `repeat: -1` for infinite loop
    tlRotatingText = gsap.to(".circle .text", {
        rotation: 360, // Full rotation
        duration: 5,  // Duration for 360°
        ease: "none",  // No easing for smooth movement
        repeat: -1,    // Repeat infinitely
        modifiers: {
            rotation: (value) => value % 360 // Keep the rotation between 0 and 360 degrees
        }
    });

    // Remove previous events to avoid duplicates
    $(".circle").off("mouseenter mouseleave");

    // Add events to reverse the direction on hover
    $(".circle").on("mouseenter", function () {
        if (tlRotatingText) {
            console.log('Reversing direction');
            tlRotatingText.timeScale(-1); // Reverse the direction
        }
    });

    $(".circle").on("mouseleave", function () {
        if (tlRotatingText) {
            console.log('Resuming normal direction');
            tlRotatingText.timeScale(1); // Resume normal direction
        }
    });
}

What I have tried:

I’ve used timeScale(-1) to reverse the animation direction when the mouse enters the element.
I attempted to use timeScale(1) to return to the normal direction when the mouse leaves.
I’ve used the reverse(0) function

Component not triggering re-render after setState

I have two components. 1 is a hook and the second is functional component that map an array of elements and renders them.

Here is the code in useRooms hook:

import { useCallback, useEffect, useState } from "react";
import { IRoom } from "@types";
import methods from "@api:methods";
import { useStoreState } from "../store.tsx";

const useRooms = (id: number) => {
    const setState = useStoreState()[1];

    const [loading, setLoading] = useState(true);
    const [rooms, setList] = useState<IRoom[]>([]);

    const addRoom = (room: IRoom) => {
        setList((prevState) => [room, ...prevState]);
    };

    useEffect(() => {
        setState((prevState) => ({ ...prevState, addRoom }));
    }, []);

    const handleRefresh = useCallback(
        async (startLoading?: boolean) => {
            if (startLoading) setLoading(true);
            const data = await methods.service.rooms.list(id);
            setLoading(false);

            if (!data) {
                return false;
            }

            setList(data);
        },
        [setList, id]
    );

    useEffect(() => {
        setList([]);
        handleRefresh(true).then();
    }, [id]);

    const handleCreate = useCallback(
        async (name: string) => {
            setLoading(true);
            const data = await methods.service.rooms.add(id, name);
            setLoading(false);

            if (!data) {
                console.error("Помилка", "Не вдалося створити точку");
                setLoading(false);
                return false;
            } else {
                setList((prevRooms) => {
                    const updatedRooms = [data, ...prevRooms];
                    console.log("Updated Rooms in useRooms:", updatedRooms);
                    console.log(
                        "Previous Rooms Reference:",
                        prevRooms === updatedRooms
                    );
                    return updatedRooms;
                });
                return data;
            }
        },
        [id]
    );

    return {
        loading,
        handleRefresh,
        rooms,
        handleCreate,
    };
};

export default useRooms;

When I add a new room it triggers handleCreate callback and inside it I’m setting new array of rooms in setList, so the “rooms” are updating.

 const handleCreate = useCallback(
        async (name: string) => {
            setLoading(true);
            const data = await methods.service.rooms.add(id, name);
            setLoading(false);

            if (!data) {
                console.error("Помилка", "Не вдалося створити точку");
                setLoading(false);
                return false;
            } else {
                setList((prevRooms) => {
                    const updatedRooms = [data, ...prevRooms];
                    console.log("Updated Rooms in useRooms:", updatedRooms);
                    console.log(
                        "Previous Rooms Reference:",
                        prevRooms === updatedRooms
                    );
                    return updatedRooms;
                }); 
                return data;
            }
        },
        [id]
    );

But it doesn’t trigger the re-render of List functional component that uses this hook. Why is it so?

import { FC, useEffect } from "react";
import styled from "styled-components";
import { token } from "@atlaskit/tokens";
import Spinner from "@atlaskit/spinner";
import useRooms from "../../hooks/useRooms.tsx";
import { useLocalState } from "../../store.tsx";
import Room from "./Room.tsx";

const List: FC = () => {
    const { object } = useLocalState();
    const { rooms, loading } = useRooms(object.id);

    useEffect(() => {
        console.log(rooms);
    }, [rooms]);

    return (
        <Container>
            <HeaderContainer>
                {loading ? (
                    <Spinner size={"large"} />
                ) : (
                    <HeadTitle>{rooms.length} комнат</HeadTitle>
                )}
            </HeaderContainer>
            <ListContainer>
                {rooms.map((room) => (
                    <Room key={room.id} room={room} />
                ))}
            </ListContainer>
        </Container>
    );
};

const Container = styled.div`
    display: flex;
    flex-direction: column;
    border: 1px solid ${token("color.border")};
    border-radius: 6px;
`;

const HeaderContainer = styled.div`
    padding: 12px 13px;
    box-sizing: border-box;
    border-bottom: 1px solid ${token("color.border")};
`;

const HeadTitle = styled.span`
    font-size: 14px;
    font-weight: 500;
`;

const ListContainer = styled.div`
    overflow-y: auto;

    & > :not(:last-child) {
        border-bottom: 1px solid ${token("color.border")};
    }
`;

export default List;

Quagga JS not returning accurate barcode results

I have been trying to create a barcode scanner component in Angular 14. Not getting accurate results or it’s taking too long to scan. I tried scanning EAN 13 and CODE 128 barcodes. Below is the code that I tried with Quagga JS version 0.12.1.

scanner.component.html:

<!-- Display the scanned barcode result -->


  <h3>Scanned Barcode: {{ barcodeResult }}</h3>


<!-- Add a button to restart the scanner if necessary -->

<button style="position:relative;top:20%" (click)="startScanner()">Restart Scanner</button>

scanner.component.ts:

import { Component, ElementRef, OnDestroy, OnInit } from '@angular/core';
// @ts-ignore
import Quagga from 'quagga';

@Component({
selector: 'app-scanner',
templateUrl: './scanner.component.html',
styleUrls: ['./scanner.component.css'],
})
export class ScannerComponent implements OnInit, OnDestroy {
barcodeResult: string = ''; // Variable to hold the scanned barcode value

constructor(private el: ElementRef) {}

ngOnInit(): void {
this.startScanner();
}

// Start the scanner
startScanner() {
this.barcodeResult = '';
// Set up QuaggaJS to start scanning from the webcam
navigator.mediaDevices
.getUserMedia({ video: { facingMode: 'environment' } })
.then((stream) = {
console.log('Camera access granted');
// Optional: You can also display the stream to the user for debugging
const videoElement = document.querySelector('video');
videoElement.srcObject = stream;
})
.catch((err) = {
console.error('Camera access denied:', err);
});
Quagga.init(
{
inputStream: {
name: 'Live',
type: 'LiveStream',
target: this.el.nativeElement.querySelector('#scanner-container'), // Target the video container
constraints: {
facingMode: 'environment', // Use the environment camera (back camera on mobile)
width: { ideal: 640 }, // Reduce the width of the video
height: { ideal: 480 }, // Reduce the height of the video
},
},
decoder: {
readers: ['code_128_reader', 'ean_reader', 'upc_reader', 'ean_13'], // Barcode types to scan
},
},
(err: any) = {
if (err) {
console.error('Error initializing Quagga', err);
return;
}
// Start the scanner once it's initialized
console.log('Quagga initialized successfully');
Quagga.start();
}
);

    // Listen for the result of a scan
    Quagga.onDetected((data: any) => {
      console.log('Detection callback:', data);
      if (data && data.codeResult && data.codeResult.code) {
        this.barcodeResult = data.codeResult.code; // Update the scanned result
        console.log('Scanned Barcode:', this.barcodeResult);
        // Optionally, you can stop scanning after a successful scan:
        Quagga.stop();
      }
    });

}

// Clean up when the component is destroyed
ngOnDestroy(): void {
Quagga.stop();
}
}

scanner.component.css:

#scanner-container {
width: 100%;
height: 600px; 
margin: 0 auto;
}

h3 {
color: green;
font-size: 1.2em;
}

Attached the images for barcode I have scanned and the result it returned.

Barcode sample scanned

Scanner output

https://stackblitz.com/edit/angular-ngx-barcode-example-scanner-pmnbexju?file=src%2Fapp%2Fapp.module.ts,src%2Findex.html

dropdown menu does not fit in the container when opened

I have got follow html:

nav {
  width: 100px;
}


.nav-menu {
  background-color: orange;
}

.dropdown {
  position: relative;
}


a[data-toggle="dropdown"] {
  display: flex;
  align-items: center;
  background: transparent;
  color: blue;
  padding: 10px 15px;
  border-radius: 4px;
  transition: background 0.3s ease;
  white-space: nowrap;
}

a[data-toggle="dropdown"]:hover {
  color: black;
}

.nav-menu {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  list-style-type: none;
  padding: 0;
  margin: 0;
  align-items: center;
  width: 100%;

}

.dropdown-menu {
  list-style: none;
  padding: 10px 15px;
  margin: 0;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 200px;
  background: #ffffff;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
  border-radius: 6px;
  overflow: hidden;
  transform: scaleY(0);
  transform-origin: top;
  opacity: 0;
  transition: transform 0.3s ease, opacity 0.3s ease;
  z-index: 1000;
}

.dropdown-menu.show {
  transform: scaleY(1);
  opacity: 1;
}

.dropdown-menu:before {
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  clip-path: inset(0 0 0 0);
}
<nav>
  <ul class="nav-menu">

    <li class="dropdown">
      <a href="#" data-toggle="dropdown">About</a>
      <ul class="dropdown-menu">
        <li><a href="/foo.html">Foo</a></li>
        <li><a href="/bar.html">Bar</a></li>
        <li><a href="/bar.html">Some long text here</a></li>
      </ul>
    </li>

  </ul>
</nav>

But I want to make menu be shown no wider than the dimensions of the container (orange color). The menu must always fit into the container.

menu tears apart the container

https://jsfiddle.net/Suliman123/8tg67sq4/

If menu is longer that container text menu it’s text should be fully displayed. In my case there is a lot of menu items. And if no space from right it always have space from left.

Here is illustration: https://jsfiddle.net/Suliman123/Lno7a5p0/