Why does replaceChildren() work eratically?

For the Javascript program below:

fnInit() appendChild() is working fine and the 3 images are displayed. But for fnRoll() replaceChildren() most of the time less than 3 images are displayed. Whats wrong and how do I fix it?

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script>
const imgArray = [];

let image1 = new Image();
image1.src = "image1.png";
imgArray[0] = image1;

let image2 = new Image();
image2.src = "image2.png";
imgArray[1] = image2;

let image3 = new Image();
image3.src = "image3.png";
imgArray[2] = image3;

function fnInit() {
  document.getElementById("slot1").appendChild(imgArray[0]);
  document.getElementById("slot2").appendChild(imgArray[1]);
  document.getElementById("slot3").appendChild(imgArray[2]);
}

function fnRoll() {
  rnd1 = Math.trunc(Math.random() * 3);
  rnd2 = Math.trunc(Math.random() * 3);
  rnd3 = Math.trunc(Math.random() * 3);
  document.getElementById("slot1").replaceChildren(imgArray[rnd1]);
  document.getElementById("slot2").replaceChildren(imgArray[rnd2]);
  document.getElementById("slot3").replaceChildren(imgArray[rnd3]);
}
</script>
</head>
<body onLoad="fnInit();">
<span id="slot1"></span>
<span id="slot2"></span>
<span id="slot3"></span>
<br>
<button id="roll" type="button" onclick="fnRoll();">Roll</button>
</body>
</html>

How to make a sub component close when another element sub component is open react table 6

//Below is the code where React Table subcomponent prop is used along with React Modal

//if i open one subcomponent and roll to another, i am seeing row data of first sub component.

//Please help.

<button className=”label” onClick={()=>{this.submitCell(this.state)}}>submit to database
submit if any of the records are edited
<ReactTable className=”react-table”
data={ this.state.schemaData } columns={ this.state.columns } showPagination={true}
showPaginationBottom= {true}
defaultPageSize={5}
page={this.state.page}
pageSizeOptions={[3,5,7,10,15]}
onPageChange={page => this.setState({page:page})}
collapseOnDataChange={true}
SubComponent={(row) => {
return (

View Record Data
<Modal
style={{
overlay: {
backgroundColor: ‘transparent’, // Make the background transparent
}
}}
className=”modalTest”
isOpen={this.state.isPopUpOpen}
onRequestClose={this.closePopUp}
contentLabel=”Example Modal”
>
Close

{Object.keys(row.original).map((key)=>{return {key} {key!==”is_enabled”?(row.original[key]!==null?row.original[key]:”NULL”):(row.original[key]===false?0:1)}})}

  </Modal>         
           
      </div>

How to add tab icon in react application

i have a react application where i need to display png image as shown below
enter image description here

HTML is as below

8×8 Integration
my folder structure is as shown below
enter image description here

but none of the images are coming in the img tab in browser network

tried all the solution only if put https://[domain]/v2/images/logo-4b47ba934d5d44393f7141168a23f5d8.svg

what should i do get the image in browser tab please help

basic script not working but no errors, console.log not working [duplicate]

this is a very basic question. I’m trying to get firebase to work with my javascript and I’m using a very basic script from a tutorial. I’m a beginner and I don’t know if there are other ways to insert debugging statements, but my console.log() calls are not working. I also tried putting in a debugger call to no effect. I read a lot of the other questions about console.log not working but they were much more complicated than my situation (and, honestly, I couldn’t make heads or tails of them). Basically, I get nothing, as though it’s not reading that code at all. Can anyone help me debug this? Code looks as follows. Thank you for any help!

<script type="module" src="https://www.gstatic.com/firebasejs/11.6.1/firebase-app.js">
      const firebase = require("firebase/app");

      // Your web app's Firebase configuration
      // For Firebase JS SDK v7.20.0 and later, measurementId is optional
      const firebaseConfig = {
            apiKey: "AIzaSyBADV4O4Oyc2xaHcLHwZficznzpoU13Gm0",
            authDomain: "my-first-project-1de2f.firebaseapp.com",
            projectId: "my-first-project-1de2f",
            storageBucket: "my-first-project-1de2f.firebasestorage.app",
            messagingSenderId: "741734388415",
            appId: "1:741734388415:web:6e4075ceaad15606816c0a",
            measurementId: "G-H0X2KKG0XP"
      };

      // Initialize Firebase
      const app = initializeApp(firebaseConfig);
      const analytics = getAnalytics(app);
      debugger:
      console.log('txt');
      
      // getting the text value from the database
      var bigOne = document.getElementById('bigOne');
      console.log(bigOne);
      var dbRef = firebase.database().ref().child('Text');
      console.log(dbRef);
      dbRef.on('value', snap => bigOne.innerText = snap.val());

      }
</script>

P.S. I know it was reading the code because when I’ve made errors in the code, I got errors in the console.

The limited role of “script src Property” in javascript

I need to ask a question about the script source: (<script type="text/javascript" src="A.js" defer></script>), for example, the A.js script contains many global functions that are created and not executed but called in a new script creating in many HTML pages (a.html, b.html, c.html). Is A.js important as a script source or is it the same with writing the same A.js in all these html pages. It’s just: I think JS starts working when the function is called and maybe does do nothing when it is created. So I think A.js should contain many global functions with its calling. Is it true, A.js with many functions without calling them in A.js is nothing ?

The A.js file :

`function a1() {......}
function a2() {......}
function a3() {........}
.............
function a1000() {........}`

The a.html, b.html, c.html files :

`<html>
<head></head>
<body>
  .........
<script type = "text/javascript" src = "A.js" defer></script>
<script>
 //calling the function that creating in A.js
</script>
</body>
</html>`

one of roles of script src is : If you want to run the same JavaScript on several pages in a web site, you should create an external JavaScript file, instead of writing the same script over and over again. Save the script file with A.js extension, and then refer to it using the src attribute in the tag. And that improve the performance of the page when move between pages.

But that role is it true when i creating a many functions without caliing in A.js ??. the functions is called in a.html, b.html, c.html. i bleive that nothing improving in the performance because the A.js is executing in a.html, b.html, c.html .

updating an out-of-scope variable in a recursive function

I am unable to wrap my head around how to write a recursive walkDir() function that updates an outside variable via a callback. Here is my attempt so far wherein I am trying to track the number of .js files and the size of the biggest .js file in stats{}

note: The actual code will have several different callbacks depending on some property of the file.

import fs from 'node:fs/promises';
import path from 'path';

async function walkDir(dir, cb) {
    const entries = await fs.readdir(dir, { withFileTypes: true });
    
    for (let i = 0; i < entries.length; i++) {
        const entry = entries[i];
        const newdir = path.join(dir, entry.name);
        
        if (entry.isDirectory()) {
            await walkDir(newdir, cb);
        }
        else {
            cb(entry, file);
        }
    }
}

function cb(entry, file) {
    const stats = { numOfJs: 0, sizeOfBiggest: 0 };

    return async function(entry, file, stats) {
        if (entry) {
            if (path.extname(entry.name).substring(1) === 'js') {
                stats.numOfJs++;
                const entryStats = await fs.stat(file);
        
                if (entryStats.size > stats.sizeOfBiggest) {
                    stats.sizeOfBiggest = entryStats.size;
                }
            }
        }
        else {
            return stats
        }
    }
}

const { numOfJs, sizeOfBiggest } = walkDir('.', cb);
console.log(numOfJs, sizeOfBiggest);
// undefined undefined

How to automatically activate scroll inside a sticky div when it reaches the viewport top?

Description

I have a page with multiple sections (A,B,C,D,E,F). Section D:

  • Has a fixed height with overflow-y: auto (contains scrollable content)
  • Uses position sticky with top: 0 (sticks to the top of the viewport when reached)

Problem

When Section D becomes stuck at the viewport top:

  • Users must first move their cursor inside the section in order to activate the scroll inside of it
  • The scroll continues inside root window and not section D

Goal

Automatically “activate” the section’s scroll when it sticks to the top:

  • Wheel and scroll events should target D’s scrollbar immediately
  • No cursor movement inside D should be required
  • Should work when scrolling both up and down

Attempted Solutions (failed)

Forward the scroll from window to Section D

I tried intercepting the window’s scroll events and manually forwarding them to Section D when sticky:

window.addEventListener('wheel', (e) => {
  if (isSectionDStuck()) {  // Pseudocode for stickiness check
    e.preventDefault();
    sectionD.scrollBy({ top: e.deltaY, behavior: 'smooth' });
  }
});
  • Only works for mouse/trackpad wheel events.
  • Ignores keyboard scrolls (Spacebar/Arrow Keys), making accessibility worse.
  • Canceling the event (preventDefault()) in order to prevent scrolling at the window level can break expected page behavior.

Auto-Focusing the Section D

I attempted programmatically focusing Section D when it becomes stuck to the top:

window.addEventListener('scroll', (e) => {
  if (isSectionDStuck()) {  // Pseudocode for stickiness check
    sectionD.focus({ preventScroll: true }) // Try to avoid jumping
  }
});
  • focus() does not activate scrolling inside Section D.
  • Even with tabindex=”0″, Section D will never respond to scrolling unless the user moves the pointer inside the section

PD: I’m not using JQuery, only React. I’m not giving the code on isSectionDStuck() because that does not matter, what I need to know is how to activate the scroll on Section D programatically.

Thank you so much for the help! If you have in mind a completely different approach for what I’m trying to achieve feel free to post your solution.

I’m trying to read when one of my users bumps the server with discous or disboard

client.on("messageCreate", async (message) => {
    const guildId = message.guild.id;
    const userId = message.interactionMetadata.user.id;
    const messageType = message.interactionMetadata.type;
    const bumpPoint = 1;
    const member = await message.guild.members.fetch(userId);
    const nickname = member.nickname;
    //console.log(messageType);
    //console.log(nickname);
    const bumpExists = await userBumpDatabase.findOne({
                guildId: guildId,
                username: nickname
                });
    if (messageType === 2) { 
        if (!bumpExists) {
            const newUser = new userBumpDatabase({
                guildId: guildId,
                username: nickname,
                points: bumpPoint,
            });
            await newUser.save();
            return message.reply({ content: `Added 1 point to ${nickname}`});
        } else {
            bumpExists.points += bumpPoint;
            bumpExists.save()
            return message.reply({ content: `Added 1 point to ${nickname}. They now have ${bumpExists.points} `});
        }
    }
});

I’m trying to reward users for bumping my server with discodus and disboard.
If I comment out the messageType if loop and uncomment the 2 console.log commands the code executes perfectly and the data is logged correctly to the console.

Am I just overlooking something? using discord.js version 14.19.3

User redirect to frontend after failing to login with google authentication

Im building a backend with nestjs and mongodb with regular authentication and google authentication. The problem is when user signs up with regular authentication and after tries to login with google it passes. What is the best practice to prevent that?
I tried throw an error if user is in db and user authprovider is ‘local’ but it doesnt seem to work.

Im posting my code in here. Hope you can help me.

auth.service.ts

BadRequestException,
Injectable,
NotFoundException,
UnauthorizedException,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { compare, hash } from 'bcryptjs';
import { Response } from 'express';
import { User } from 'src/users/schema/user.schema';
import { TokenPayload } from './token-payload.interface';
import { SignupDto } from './dtos/signup.dto';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { UsersService } from 'src/users/users.service';
import { ResetToken } from './schemas/reset-token.schema';
const { nanoid } = require('nanoid');
import { MailService } from './services/mail.service';

@Injectable()
export class AuthService {
constructor(
 @InjectModel(User.name) private readonly userModel: Model<User>,
 @InjectModel(ResetToken.name) private resetTokenModel: Model<ResetToken>,
 private readonly usersService: UsersService,
 private readonly configService: ConfigService,
 private readonly jwtService: JwtService,
 private mailService: MailService,
) {}


async login(user: User, response: Response, redirect = false) {
 //calculate expiration date for access token
 const expiresAcessToken = new Date();
 expiresAcessToken.setMilliseconds(
   expiresAcessToken.getTime() +
     parseInt(
       this.configService.getOrThrow('JWT_ACCESS_TOKEN_EXPIRATION_MS'),
     ),
 );

 //calculate expiration date for refresh token
 const expiresRefreshToken = new Date();
 expiresRefreshToken.setMilliseconds(
   expiresRefreshToken.getTime() +
     parseInt(
       this.configService.getOrThrow('JWT_REFRESH_TOKEN_EXPIRATION_MS'),
     ),
 );

 const tokenPayload: TokenPayload = {
   userId: user._id.toHexString(),
 };

 //create access token
 const accessToken = this.jwtService.sign(tokenPayload, {
   secret: this.configService.getOrThrow('JWT_ACCESS_TOKEN_SECRET'),
   expiresIn: `${this.configService.getOrThrow('JWT_ACCESS_TOKEN_EXPIRATION_MS')}ms`,
 });

 //create refresh token
 const refreshToken = this.jwtService.sign(tokenPayload, {
   secret: this.configService.getOrThrow('JWT_REFRESH_TOKEN_SECRET'),
   expiresIn: `${this.configService.getOrThrow('JWT_REFRESH_TOKEN_EXPIRATION_MS')}ms`,
 });

 await this.usersService.updateUser(
   {
     _id: user._id,
   },
   {
     $set: { refreshToken: await hash(refreshToken, 10) },
   },
 );

 response.cookie('access_token', accessToken, {
   httpOnly: true,
   secure: this.configService.getOrThrow('NODE_ENV') === 'production',
   expires: expiresAcessToken,
 });

 response.cookie('refresh_token', refreshToken, {
   httpOnly: true,
   secure: this.configService.getOrThrow('NODE_ENV') === 'production',
   expires: expiresRefreshToken,
 });

 if (redirect)
   response.redirect(this.configService.getOrThrow('FRONTEND_URL'));
 else
   response.status(200).json({
     _id: user._id,
     name: user.name,
     email: user.email,
   });
}

async verifyUser(email: string, password: string) {
   const user = await this.usersService.getUser({ email });

   if (!user) {
     throw new UnauthorizedException('Invalid credentials');
   }

   if (user.authProvider !== 'local') {
     console.log('User is not local');
     throw new UnauthorizedException('No account associated with this email for password login. Please use Google login.');
   }

   const authenticated = await compare(password, user.password);
   if (!authenticated) {
     throw new UnauthorizedException('Invalid credentials');
   }
   return user;
}
}

auth.controller.ts

import {
  Body,
  Controller,
  Get,
  Post,
  Put,
  Res,
  UseGuards,
} from '@nestjs/common';
import { LocalAuthGuard } from './guards/local-auth.guard';
import { CurrentUser } from './current-user.decorator';
import { User } from 'src/users/schema/user.schema';
import { Response } from 'express';
import { AuthService } from './auth.service';
import { JwtRefreshAuthGuard } from './guards/jwt-refresh-auth.guard';
import { GoogleAuthGuard } from './guards/google-auth.guard';
import { SignupDto } from './dtos/signup.dto';
import { ChangePasswordDto } from './dtos/change-password.dto';
import { JwtAuthGuard } from './guards/jwt-auth.guard';
import { ForgotPasswordDto } from './dtos/forgot-password.dto,';
import { ResetPasswordDto } from './dtos/reset-password.dto';
import { ConfigService } from '@nestjs/config';

@Controller('auth')
export class AuthController {
  constructor(
    private readonly authService: AuthService,
    private readonly configService: ConfigService,
  ) {}

  @Post('signup')
  async signup(@Body() signupData: SignupDto) {
    return this.authService.signup(signupData);
  }

  @Post('signin')
  @UseGuards(LocalAuthGuard)
  async login(
    @CurrentUser() user: User,
    @Res({ passthrough: true }) response: Response,
  ) {
    await this.authService.login(user, response);
  }


  @Get('google')
  @UseGuards(GoogleAuthGuard)
  loginGoogle() {}

  @Get('google/callback')
  @UseGuards(GoogleAuthGuard)
  async googleCallback(
    @CurrentUser() user: User,
    @Res({ passthrough: true }) response: Response,
  ) {
    await this.authService.login(user, response, true);
  }

}

user.service.ts

import { InjectModel } from '@nestjs/mongoose';
import { User } from './schema/user.schema';
import { FilterQuery, Model, UpdateQuery } from 'mongoose';
import { hash } from 'bcryptjs';
import { SignupDto } from 'src/auth/dtos/signup.dto';

@Injectable()
export class UsersService {
  constructor(
    @InjectModel(User.name)
    private readonly userModel: Model<User>,
  ) {}

  async createUser(data: SignupDto) {
    if(data.authProvider === 'local'){
        data.password = await hash(data.password, 10);
    }
    const createdUser = new this.userModel(data);
    await createdUser.save();
    return createdUser;
  }

  async getUser(query: FilterQuery<User>) {
    const user = await this.userModel.findOne(query);
    if (!user) {
      throw new NotFoundException('User not found');
    }
    return user;
  }

  async updateUser(query: FilterQuery<User>, data: UpdateQuery<User>) {
    return this.userModel.findOneAndUpdate(query, data);
  }

  async getOrCreateUser(data: SignupDto) {
    const user = await this.userModel.findOne({ email: data.email });
    if (user && data.password === '') {
      return user;
    }
    return this.createUser(data);
  }
}


google.strategy.ts

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-google-oauth20';
import { UsersService } from '../../users/users.service';

@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy) {
  constructor(
    configService: ConfigService,
    private readonly usersService: UsersService,
  ) {
    super({
      clientID: configService.getOrThrow('GOOGLE_AUTH_CLIENT_ID'),
      clientSecret: configService.getOrThrow('GOOGLE_AUTH_CLIENT_SECRET'),
      callbackURL: configService.getOrThrow('GOOGLE_AUTH_REDIRECT_URI'),
      scope: ['profile', 'email'],
    });
  }

  async validate(_accessToken: string, _refreshToken: string, profile: any) {
    if (!profile.emails || !profile.emails[0]?.value) {
      throw new UnauthorizedException('No email found in Google profile');
    }

    const email = profile.emails[0]?.value;

    const existingUser = await this.usersService.getUser({ email });
    if (existingUser && existingUser.authProvider === 'local') {
      throw new UnauthorizedException(
         'This email is already registered using password login.'
      );
    }

    const user = await this.usersService.getOrCreateUser({
      name: profile.displayName,
      email: profile.emails[0]?.value,
      password: '',
      authProvider: 'google',
    });

    return user;
  }
}

google-auth.guard.ts

// google-auth.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class GoogleAuthGuard extends AuthGuard('google') {
  handleRequest(err, user, info, context, status) {
    const res = context.switchToHttp().getResponse();
    
    if (err || !user) {
      // Redirect to frontend with error message
      return res.redirect(
        `${process.env.FRONTEND_URL}/auth/signin?message=Authentication failed`
      );
    }

    return user;
  }
}

Adding a custom operator in react-querybuilder and json-logic

I’m trying to add a custom operator to my react-querybuilder project, but it’s just not working.

I’ve added the following custom operators to my builder:

const customOperators = [
  {
    name: 'lengthequals',
    label: 'Length =',
  },
  {
    name: 'lengthgreaterthan',
    label: 'Length >',
  },
  {
    name: 'lengthlessthan',
    label: 'Length <',
  },
];

const operators = [...defaultOperators, ...customOperators];
<QueryBuilder
    fields={fields}
    operators={operators}
    query={query}
/>

This correctly adds the opperator to the list of available opperators in the builder.
This will add a rule to my builder query that looks like this:

{
    field: "FirstName",
    operator: "lengthgreaterthan",
    value: "4",
    valueSource: "value"
}

I also add an opperation to json-logic like this:

add_operation('lengthgreaterthan', (val, compareTo) => {
  return (val?.length ?? 0) > compareTo;
});

My understanding is that this would let jsonlogic understand what the operator is trying to do. But when I try to format the query with

formatQuery(query, 'jsonlogic')

It always returns false. Well, if I add a second rule in my query builder that isn’t custom, that rule will appear in the formatted query, so it’s more like the custom rules are being ignored.

What do I need to do to make formatQuery work with my operators? There’s gotta be a step where I tell the query formatter what to do with these operators, but there’s no documentation telling me what.

OpenCascade.js setup

I’m trying to set up OpenCascade.js in a project using Vite, Three.js, and Vue.js, but I’m having trouble getting it to work. Has anyone successfully integrated OpenCascade.js in this kind of setup? Any help or guidance would be greatly appreciated!

How to separate left and right audio channels from microphone?

How can I use JS to separate the left and right channels of audio from a microphone and process them individually?
I try these codes,but not work:

const audioContext = new(window.AudioContext || window.webkitAudioContext)();
const source = audioContext.createMediaStreamSource(stream);

// 创建分析器
const analyser = audioContext.createAnalyser();
analyser.fftSize = 2048;
source.connect(analyser);

// 创建分离声道的处理器
const splitter = audioContext.createChannelSplitter(2);
source.connect(splitter);

// 创建两个分析器,分别用于左右声道
const leftAnalyser = audioContext.createAnalyser();
const rightAnalyser = audioContext.createAnalyser();

Rerender after initial click

I have a popover-size selection in my Shopify shop, but after opening the popover for the first time and selecting a size, I experience an unsightly rerender. This issue only occurs on Android when I first open the page, after that it works fine. When I close and reopen the tab, it happens again.

{%- assign color_label_list = 'general.label.color' | t | replace: ', ', ',' | downcase | split: ',' -%}
{%- assign size_label_list = 'general.label.size' | t | replace: ', ', ',' | downcase | split: ',' -%}
{%- assign variant_image_options = block.settings.variant_image_options | replace: ', ', ',' | downcase | split: ',' -%}

{{ 'variant-picker-custom.css' | asset_url | stylesheet_tag }}

<script>
  function selectVariant(optionValueId, element, event) {
    // Prevent default behavior and stop propagation
    if (event) {
      event.preventDefault();
      event.stopPropagation();
    }

    // Find the radio input and check it
    const radioInput = document.querySelector(`input[value="${optionValueId}"]`);
    
    if (radioInput) {
      radioInput.checked = true;
      
      // Get the form
      const form = document.getElementById('{{ form_id }}');
      if (form) {
        // Get all the checked option inputs
        const checkedOptions = Array.from(form.elements)
          .filter(item => item.matches('input[data-option-position]:checked'))
          .sort((a, b) => parseInt(a.getAttribute('data-option-position')) - parseInt(b.getAttribute('data-option-position')));
        
        // Get the variant picker component
        const variantPicker = document.querySelector('variant-picker');
        if (variantPicker) {
          const optionValues = checkedOptions.map(input => input.value);
          
          // Trigger the variant picker's selectCombination method which will handle everything
          variantPicker.selectCombination({
            optionValues,
            productChange: false
          });
        }
        
        // Update add to cart button state in the drawer
        const drawer = element.closest('x-drawer');
        if (drawer) {
          const drawerSubmitButton = drawer.querySelector('[slot="footer"] button[type="submit"]');
          if (drawerSubmitButton) {
            const isAvailable = !element.classList.contains('is-disabled');
            drawerSubmitButton.disabled = !isAvailable;
          }
        }
      }
      
      // Update selected state styling for options within the same drawer
      const drawer = element.closest('x-drawer');
      if (drawer) {
        const allOptions = drawer.querySelectorAll('.variant-grid__option');
        allOptions.forEach(opt => {
          opt.classList.remove('is-selected');
        });
        element.classList.add('is-selected');
      }
    }
  }
</script>

{%- unless product.has_only_default_variant -%}
  <variant-picker class="variant-picker" section-id="{{ section.id }}" handle="{{ product.handle }}" form-id="{{ form_id }}" {% if update_url %}update-url{% endif %}>
    {%- comment -%}
    The variant data is outputted as a JSON, which allows the theme to emit an event with the data when the variant changes. This must not be removed.
    {%- endcomment -%}
    <script data-variant type="application/json">
      {{- product.selected_or_first_available_variant | json -}}
    </script>

    {%- for option in product.options_with_values -%}
      {% liquid
        assign option_downcase = option.name | downcase
        assign resolved_option_selector_style = block.settings.selector_style

        # Create a map of option values to their fast shipping status
        assign fast_shipping_values = ''
        for variant in product.variants
          if variant.inventory_management == 'shopify'
            assign option_position = option.position | minus: 1
            assign variant_option_value = variant.options[option_position]
            assign fast_shipping_values = fast_shipping_values | append: '|' | append: variant_option_value
          endif
        endfor
        assign fast_shipping_values = fast_shipping_values | remove_first: '|' | split: '|'

        assign swatch_count = option.values | map: 'swatch' | compact | size

        if swatch_count > 0 and block.settings.swatch_selector_style != 'none'
          # Use the swatch selector type only if we have at least one swatch and a supported swatch selector type
          assign resolved_option_selector_style = block.settings.swatch_selector_style
        endif

        # Implementation note: if the option value has no native swatch, BUT that the option name matches a hardcoded list of color names,
        # we fallback to the legacy config-based system. This allows to keep compatibility with stores that were using the config-based, and
        # allow those merchants to upgrade to the new system at their own pace.
        if swatch_count == 0 and color_label_list contains option_downcase and block.settings.swatch_selector_style != 'none'
          assign resolved_option_selector_style = block.settings.swatch_selector_style
        endif

        if resolved_option_selector_style == 'dropdown' and force_dropdown_as_block
          assign resolved_option_selector_style = 'block'
        endif

        if variant_image_options contains option_downcase
          assign resolved_option_selector_style = 'variant_image'
        endif
      %}

      <fieldset class="variant-picker__option">
        <div class="variant-picker__option-info">
          {%- if hide_size_chart != true and block.settings.size_chart_page != blank and size_label_list contains option_downcase -%}
            {%- capture drawer_id -%}size-chart-{{ option.position }}-{{ form_id }}{%- endcapture -%}

            <button type="button" class="text-sm text-subdued" aria-controls="{{ drawer_id | escape }}" aria-expanded="false">
              <span class="link">{{ 'product.general.size_chart' | t }}</span>
            </button>

            <x-drawer id="{{ drawer_id }}" class="drawer drawer--lg">
              <span class="h5" slot="header">{{ block.settings.size_chart_page.title }}</span>

              <div class="prose">
                {{- block.settings.size_chart_page.content -}}
              </div>
            </x-drawer>
          {%- endif -%}
        </div>

        {%- if resolved_option_selector_style == 'dropdown' -%}
          {%- capture variant_drawer_id -%}variant-picker-drawer-{{ section.id }}-{{ product.id }}-{{ option.position }}{%- endcapture -%}
          {%- assign param_name = form_id | append: '-option' | append: option.position -%}

          {% comment %} Drawer Trigger Button {% endcomment %}
          <button type="button" class="button button--xl button--primary button--full" aria-controls="{{ variant_drawer_id }}" aria-expanded="false">
            {{ option.name }} {{ 'product.general.select' | t }}
          </button>

          {% comment %} Drawer Definition {% endcomment %}
          <x-drawer id="{{ variant_drawer_id }}" class="drawer drawer--variant-picker drawer--lg" anchor="bottom">
            {% comment %} Drawer Header {% endcomment %}
            <div slot="header" class="h-stack items-center justify-between">
               <p class="h5">{{ option.name | upcase }} {{ 'product.general.select' | t | upcase }}</p>
            </div>

            {% comment %} Drawer Main Content {% endcomment %}
            <div>
              <div class="variant-grid__shipping-info">
                <span class="variant-grid__shipping-dot"></span>
                <span class="shipping-text">{{ 'product.general.shipping_in_48h' | t }}</span>
                <span class="variant-grid__shipping-badge">48H</span>
              </div>

              <div data-option-selector class="variant-grid">
                {%- for option_value in option.values -%}
                  {%- if hide_sold_out_variants == false or option_value.available or option_value.selected -%}
                    {% comment %} We use labels/radios even if update_url is true for consistent behavior in drawer {% endcomment %}
                    <label
                      class="variant-grid__option {% unless option_value.available %}is-disabled{% endunless %} {% if option_value.selected %}is-selected{% endif %}"
                      for="{{ param_name }}-{{ option_value.id | escape }}"
                      onclick="selectVariant('{{ option_value.id }}', this, event);"
                    >
                      <input class="sr-only" type="radio" id="{{ param_name }}-{{ option_value.id | escape }}" form="{{ form_id }}" name="{{ param_name }}" data-option-position="{{ option.position }}" value="{{ option_value.id }}" {% if option_value.selected %}checked{% endif %} {% unless option_value.available %}disabled{% endunless %}>
                      {% if fast_shipping_values contains option_value.name %}
                        <span class="variant-grid__option-available">
                          48H
                        </span>
                      {% endif %}
                      <input class="sr-only" type="radio" id="{{ param_name }}-{{ option_value.id | escape }}" form="{{ form_id }}" name="{{ param_name }}" data-option-position="{{ option.position }}" value="{{ option_value.id }}" {% if option_value.selected %}checked{% endif %} {% unless option_value.available %}disabled{% endunless %}>
                      <span class="variant-grid__option-value">{{ option_value.name | remove: " - Sofort verfügbar!" }}</span>
                      <span class="variant-grid__option-price">{{ option_value.variant.price | money }}</span>
                    </label>
                  {%- endif -%}
                {%- endfor -%}
              </div>
            </div>

            {% comment %} Drawer Footer {% endcomment %}
            <div slot="footer">
              {%- assign drawer_form_id = form_id | append: '-drawer' -%}
              {%- form 'product', product, id: drawer_form_id -%}
                <input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}">
                <button type="button" class="button button--xl button--secondary button--full" 
                        onclick="
                          const form = document.getElementById('{{ drawer_form_id }}');
                          const drawer = this.closest('x-drawer');
                          const formData = new FormData(form);
                          
                          fetch('/cart/add.js', {
                            method: 'POST',
                            body: formData
                          })
                          .then(response => response.json())
                          .then(data => {
                            // Update cart count or show success message if needed
                            if (drawer) {
                              drawer.dispatchEvent(new CustomEvent('dialog:force-close', { bubbles: true }));
                            }
                            // Trigger cart drawer to open or update cart
                            document.documentElement.dispatchEvent(new CustomEvent('cart:refresh', { bubbles: true }));
                            
                            // Open cart drawer
                            const cartDrawer = document.getElementById('cart-drawer');
                            if (cartDrawer) {
                              setTimeout(() => {
                                cartDrawer.setAttribute('open', '');
                                cartDrawer.dispatchEvent(new CustomEvent('dialog:open', { bubbles: true }));
                              }, 300);
                            }
                          })
                          .catch(error => console.error('Error:', error));
                          
                          return false;
                        ">
                  {%- if product.selected_or_first_available_variant.available -%}
                    {{ 'product.general.add_to_cart_button' | t }}
                  {%- else -%}
                    {{ 'product.general.sold_out_button' | t }}
                  {%- endif -%}
                </button>
              {%- endform -%}
            </div>
          </x-drawer>
        {%- else -%}
          <div {% unless block.settings.stack_blocks %}class="scroll-area bleed sm:unbleed"{% endunless %}>
            <div class="variant-picker__option-values {% if block.settings.stack_blocks %}wrap{% else %}scroll-area bleed sm:unbleed{% endif %} {% if resolved_option_selector_style == 'swatch' and settings.color_swatch_style == 'rectangle' %}variant-picker__option-values--color gap-4{% else %}gap-2{% endif %}">
              {% liquid
                assign name = form_id | append: '-option' | append: option.position

                for option_value in option.values
                  case resolved_option_selector_style
                    when 'variant_image'
                      render 'option-value', type: 'thumbnail', form: form_id, option_value: option_value, param_name: name, option_position: option.position, hide_if_disabled: hide_sold_out_variants, reload_page_for_combined_products: update_url, id_prefix: forloop.index, bordered: true
                    when 'swatch'
                      render 'option-value', type: 'swatch', form: form_id, option_value: option_value, param_name: name, option_position: option.position, hide_if_disabled: hide_sold_out_variants, reload_page_for_combined_products: update_url, id_prefix: forloop.index
                    when 'block'
                      render 'option-value', type: 'block', form: form_id, option_value: option_value, param_name: name, option_position: option.position, hide_if_disabled: hide_sold_out_variants, reload_page_for_combined_products: update_url, id_prefix: forloop.index
                    when 'block_swatch'
                      render 'option-value', type: 'block', form: form_id, option_value: option_value, param_name: name, option_position: option.position, show_swatch: true, hide_if_disabled: hide_sold_out_variants, reload_page_for_combined_products: update_url, id_prefix: forloop.index
                  endcase
                endfor
              %}
            </div>
          </div>
        {%- endif -%}
      </fieldset>
    {%- endfor -%}
  </variant-picker>
{%- endunless -%}

enter image description here

how to make vertical slider slide-in just as much as the mouse scrolls

Scenario:
I’m building a website in WordPress using the free version of Elementor. I want to create a vertical slider on a page built with Elementor. My top priority is to achieve this without using any paid plugins.

Issue:
The vertical sliders I’ve tried behave inconsistently — sometimes it takes a lot of scrolling to move to the next slide, other times even a slight scroll jumps to the next one. This makes for a poor user experience. I want smooth, consistent scrolling: the next section should come into view naturally based on how much the user scrolls (like native page scroll).

What I’ve tried:

Smart Slider 3 plugin, Vertical Scroll widget from Premium Addons for Elementor
I’m not considering Slider Revolution due to its large size and performance issues.

What I don’t want:

Snap-to-section scroll like this: Premium Addons Demo

This kind of slider layout: Example

What I do want (reference examples):

Luminar site example

Athos site example

Is there a way to achieve this kind of natural vertical scroll behavior in Elementor (free), possibly with custom code or a lightweight plugin?