Using React 16 Node Modules in a React 18 Application

“Is it safe to use React 16 node modules in a React 18 application?

I’m working on a React project where I need to incorporate a third-party library that’s built for React 16. I’m concerned about potential compatibility issues and performance impacts when using this library in a React 18 environment.

Are there any specific challenges or workarounds I should be aware of when mixing React 16 and React 18 components?
What are the potential risks involved?

Will it work will react 18 application as we not not using any concurrent feature, will still concurrent rendering will work inside react and cause issue with react 16 node_module as it used lifecyles like unsafe_componentWillMount?

How do I align the button with the center of the neon circle?

What I’m trying to do is align the fingerprint button with the center of the neon loading circle. Also, when I click the finger print button it should start the animation rather than at the start of loading page.

I’ve included the HTML/CSS/JS I’m using right now.

HTML:

<!DOCTYPE html>

<head> 
    <title> @isaranwrap - Chess Lessons</title>
    <link href = "css/style.css" type = "text/css" rel = "stylesheet">
    <script src = "https://d3js.org/d3.v3.min.js"></script>
    <script src = "https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
    <script src = "https://kit.fontawesome.com/fd3faaa138.js" crossorigin="anonymous"></script>
</head>
<!-- 
<a href = "https://github.com/isaranwrap/StandardizingAKI"> jj
    <div id="flaggerLogo"> <img width=132 height=144 src="images/07hexlogo.png" style = "float: left"></div>
</a> -->

<body>

    <div class="card">
        <div class="rating">
            <div class="block">
                <button class="btn">
                <span class="material-icons-outlined"><i class='fas fa-fingerprint'></i></span>
                </button>
            </div>
        </div>
    </div>

        <!-- <div class="rating">
          <h2><span class="counter" data-target="50">50</span><sup>%</sup><br>HTML</h2>
          <div class="block"></div>
      </div>
    </div> -->

    <script>
        document.addEventListener('DOMContentLoaded', function () {
          var circleCursor = document.createElement('div');
          circleCursor.className = 'circle-cursor';
          document.body.appendChild(circleCursor);
        
          document.addEventListener('mousemove', function (e) {
            circleCursor.style.left = e.clientX + 'px';
            circleCursor.style.top = e.clientY + 'px';
            circleCursor.style.display = 'block';
            // document.removeEventListener('mousemove', this);
          });
        });
    </script>

    <script>
        const rating = document.getElementsByClassName('rating')[0];
        const block = document.getElementsByClassName('block');

        for (var i = 1; i < 100; i++){
        rating.innerHTML += "<div class='block'></div>";
        block[i].style.transform = "rotate("+ 3.6 * i + "deg)";
        block[i].style.animationDelay = `${i/40}s`; 
        }
    </script>

    <script src = "code/landingPage.js"></script>
</body>

CSS:

@import url('https://fonts.googleapis.com/css?family=Poppins:200,300,400,500,600,700,800,900&display=swap');
body {
    background: linear-gradient(
        90deg, rgba(46, 44, 45, 1) 0%,
        rgba(66, 64, 67, 1) 100%
    );
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    height: 100vh;
    margin: 0;
}

html, body, span, button {
    cursor: none;
}

.card {
    z-index:100;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Poppins', sans-serif;
}

body {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background: radial-gradient(#444,#222);
}

.card {
    position: relative;
    width: 200px;
    height: 200px;
}

.card .rating {
    position: relative;
    width: 100%;
    height: 100%;
    /* background: #f00; */
}

.card .rating .block {
    position: absolute;
    width: 2px;
    height: 10px;
    background: #000;
    left: 50%;
    transform-origin: 50% 100px;
    opacity: 0;
    animation: animate 2s linear forwards;
    /* transform: rotate(25deg); */
}

/* .block .btn {
    transform: translate(-50%, -50%);
} */

@keyframes animate {
    to {
        opacity: 1;
    }
}

.card .rating .block:nth-child(-n+51) {
    background: aquamarine;
    box-shadow: 0 0 15px aquamarine, 0 0 30px #0f0;
}

.card .rating h2 {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: #fff;
    font-size: 1.2em;
    font-weight: 500;
    text-align: center;
    line-height: 1.5em;
}

.card .rating h2 span {
    font-size: 2.5em;
    font-weight: 700;
}

.card .rating h2 sup {
    font-size: 1.5em;
    font-weight: 300;
}


.circle-cursor {
    position: fixed;
    width: 10px;
    height: 10px;
    /* background-color: #008ECE; */
    background-color: rgb(135, 206, 235);
    border-radius: 50%;
    pointer-events: auto;
    z-index: 9999;
    display: none;
}

.btn {
    position: relative;
    width: 7em;
    height: 7em;
    border-radius: 50%;
    outline: none;
    border: 4px #090909 solid;
    background: linear-gradient(
        145deg, #171717, #444245
    );
    box-shadow: inset 2px 2px 0px #7d7c7e,
        inset -2px -2px 0px #1c1c1c;
    color: #a6a6a6;
}

.btn span {
    font-size: 2.9em;
}

.btn::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border-radius: inherit;
    background: linear-gradient(
        145deg, #262626, #606060
    );
    width: 7.25em;
    height: 7.25em;
    z-index: -1;
    box-shadow: 11px 11px 22px #141414,
                -11px -11px 22px #525252;
}

.button-clicked {
    background: linear-gradient(
        -185deg, #131313, #444245;
    );
    box-shadow: inset -2px -2px 0px #5e5e5e,
        inset 2px 2px 0px #1c1c1c;
}

.button-hover {
    background: #5e5e5e;
}

.icon-clicked {
    color: #0fa;
    text-shadow:
    0 0 7px #fff,
    0 0 10px #fff,
    0 0 21px #fff,
}
/* .icon-clicked {
    color: #fff;
    text-shadow: 0px 0px 15px #008ECE;
} */

/* https://css-tricks.com/how-to-create-neon-text-with-css/ */

Javascript:

// Select the button

const btn = document.querySelectorAll('.btn');

for(let i = 0; i < btn.length; i++) {
    btn[i].addEventListener('click', function(e) {
        btn[i].classList.toggle('button-clicked');
        btn[i].firstElementChild.classList.toggle('icon-clicked');
    })
    btn[i].addEventListener('mouseover', function(e) {
        btn[i].classList.toggle('button-hover');
    })
    btn[i].addEventListener('mouseover', function(e) {
        btn[i].classList.add('button-hover');
    })
    btn[i].addEventListener('mouseout', function(e) {
        btn[i].classList.remove('button-hover');
    })
}

output

I tried messing around with the CSS and JS to no avail.

Problem with playing sound in Safari using JS and AudioContext

My game has background music and separate sounds, I play all of this differently. The problem is that the looped background music disappears at some point, some sounds play with a defect.

Here is my JS code to perform these functions

const allSounds   = []
let allSoundsName = [
    //names of sounds
]


function preloadSounds() {
    allSoundsName.forEach(soundName => {
        let audio = new Audio(`./assets/audio/${soundName}.mp3`)

        allSounds.push({
            name: soundName,
            audio: audio,
        })
    })
}

function playAudio({
                       audioName,
                       isLoop,
                       startTime = 0,
                       endTime = null,
                       volume = 1,
                       delay = 0,
                       decrease = 0,
                       duration,
                   }) {
    if (!audioCtx) {
        audioCtx               = new (window.AudioContext || window.webkitAudioContext)();
        audioCtx.onstatechange = () => {
            if (audioCtx.state === 'suspended') {
                console.log('suspended')
                audioCtx.resume();
            }
        };
        addAllSoundGain()
    }
    let sound = getSound(audioName)

    setVolume(sound, off ? 0 : volume)
    if (volume !== 1) addVolumes(audioName, volume)

    sound.audio.currentTime = startTime

    if (endTime) {
        setTime(sound.audio, startTime, endTime, isLoop)

    } else if (isLoop) {
        setLoop(sound.audio, startTime)
    }

    setTimeout(() => {
        sound.audio.play()
        setDurationAndDecrease(sound.audio, audioName, duration, decrease)

    }, delay)

    return sound.audio
}
function addAllSoundGain() {
    allSounds.forEach(sound => {
        let source   = audioCtx.createMediaElementSource(sound.audio);
        let gainNode = audioCtx.createGain();
        source.connect(gainNode);
        gainNode.connect(audioCtx.destination);
        sound.source   = source
        sound.gainNode = gainNode
    })
}
function setDurationAndDecrease(audio, audioName, duration, decrease) {
    if (duration) setTimeout(() => pauseAudio({audioName, decrease}), duration)
}

function setLoop(audio, startTime) {
    audio.onended = () => {
        audio.currentTime = startTime
        audio.play()
    }
}

function setTime(audio, startTime, endTime, isLoop) {
    audio.ontimeupdate = () => {

        if (audio.currentTime >= endTime && isLoop) {
            audio.currentTime = startTime
        } else if (audio.currentTime >= endTime) {
            audio.pause()
        }
    }

}

I don’t know what to do, because everything is fine in Chrome, this problem only occurs in Safari Mac

FullCalendar with resourceTimeline draggable events

let calendarEl = document.getElementById(‘calendar’);

let calendar = new FullCalendar.Calendar(calendarEl, {
plugins: [‘interaction’, ‘resourceTimeline’],

with var Draggable = FullCalendarInteraction.Draggable;

my events Draggable have start and end date

like number 7 in this image

my work
change background color to lightgreen

how at move event above Calendar read start and end date
then the duration from 2 dates changes the background color of the Calendar
just duration and above Calendar ?

How to fix “unable to start program js-debug the debugger is not properly installed”

I am unable to find a solution to this issue anywhere.
Whenever I run my project (React + ASP.NET Core), it opens a command line window that runs the front-end using vite. But along with it comes this popup that gives the error “unable to start program js-debug the debugger is not properly installed”.

I have tried disabling and enabling “Enable JS debugging in Chrome, Edge, etc.” in the debugger tab.

How to Implement Streaming in React Native?

I’m trying to implement streaming in a React Native application, but I’m encountering issues. Specifically, I’m using the react-native-fetch-api library along with react-native-polyfill-globals to make a streaming request, but it doesn’t seem to work as expected.

I’ve read this: Stream api with fetch in a react-native app

Could not get it working. After some debugging, I came up with this:

import 'react-native-polyfill-globals/auto';
import { fetch as fetchh } from 'react-native-fetch-api';

const streamBotResponse = async (conversationId: string, content: string) => {
  const response = await fetchh(
    `${process.env.EXPO_PUBLIC_API_URL}/api/v1/protected/chats/message/stream/${conversationId}?content=${content}`,
    {
      headers: {
        Authorization: '632133e6-c400-43fe-b4c9-357d05cde8ee',
      },
      reactNative: { textStreaming: true },
    }
  );

  async function* streamAsyncIterator(stream: ReadableStream) {
    const reader = stream.getReader();
    try {
      while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        yield value;
      }
    } finally {
      reader.releaseLock();
    }
  }

  for await (const chunk of streamAsyncIterator(response.body)) {
    console.log(new TextDecoder().decode(chunk));
  }
};

Can’t seem to resolve: Could not find a declaration file for module ‘react-native-fetch-api’.
Seems to me like this library does not support TypeScript (I could solve the error using a d.ts file but there is not a @types library for react-native-fetch-api (same goes for react-native-polyfill-globals))

But that is not a big problem, I manage to get it to work sort of, but my entire stream response is given back to me in 1 chunk. Is it possible to get it back in multiple smaller chunks? Or is this a limitation of RN and I should just give up on this?

I am using a bootstrap datetimepicker. i have requirement add popover near to the year

(https://i.sstatic.net/Q5P0wxnZ.png) I have a requirement to show a popover at the location of the “Select Year” tooltip in the Bootstrap datetimepicker,

I have go through the datetimepicker and I couldn’t find any solution it shows tooltip .

$(‘.date’).datetimepicker({
format: ‘DD-MM-YYYY’,
tooltips: {
selectYear: ‘To easily change the year, rather than using the left/right arrow icons, click on the year at the top (e.g. 2024) and select the year you require, followed by the month.’
}
});

instead of tooltip i want to show popover

How to detect back button and forward button in Firefox?

My goal

I am developing an online mouse tester, where users can test left/middle/right/forward/back button. I use mousedown event and MouseEvent.button to detect buttons. It works on Chrome 127.0.6533.88 . It doesn’t work on Firefox 128.0.3 .

Reproduction

  • Open the JS Bin live demo (you may need to click “Run with JS”)
  • In Chrome, click forward button and back button, and you will see 4 and 3 in the console
  • In Firefox, click forward button and back button, and there will be no output in the console

Live demo: https://jsbin.com/qucofakebi/1/edit?html,console,output

Demo code:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script>
    document.addEventListener('mousedown',e=>console.log(e.button))
  </script>
</head>
<body>
</body>
</html>

Default option in v-select not clearing/deselecting

I’ve a survey page in Vue JS which there is a dropdown which contains multiple options. There must be an answer selected by default whose answerid is stored in the api response as DefaultAnswerId. The problem is:
Whenever I’m opening the dropdown and trying to clear the default option which is No Answer, I’m neither able to clear it nor deselect it from the dropdown.
Can anyone help what can be the reason. Code given below

<template>
  <v-select
    v-model="question.SelectedAnswers"
    :items="question.Answers"
    item-text="ansName"
    item-value="ansId"
    clearable
    placeholder="Select Answer"
    multiple
@update:modelValue="getAvailableAnswers"
  ></v-select>
</template>
methods: {
  getAvailableAnswers() {
    if (!this.question.Answers || this.question.Answers.length === 0) {
      return [];
    }

    if (this.question.SelectedAnswers === null || 
        this.question.SelectedAnswers === undefined || 
        this.question.SelectedAnswers.length === 0) {
      // Check if there is a default system ID and it's not null
      if (this.question.DefaultAnswerId !== undefined && this.question.DefaultAnswerId !== null) {
        this.question.SelectedAnswers = [this.question.DefaultAnswerId];
      } 
      this.question.saveResponse = true; // This saves the answer
    } 
      // Regular handling for answers
      const answers = this.question.Answers.filter(ans => ans.ResponseId === this.question.ResponseId);
      return answers; //This returns the answers array
    
  }

  
}

Accessibility concerns of span/mark tags nested in paragraphs

So I am creating my portfolio right now and I want to put emphasis on some words inside my paragraph by changing their color. I’ve been using the mark tag, which makes sure screen readers are aware of the emphasis, but it also acts as if the mark tag is separate from the paragraph; making the screen reader stop until the user continues manually.

I just want to make sure this is not an accessibility concern. Here is my code:

<p>
  Having <mark class="blue">authority</mark> over your brand is important in business. You decide how you want your brand to be <mark class="blue">perceived</mark>, interacted with, and <mark class="blue">connected</mark> to your community. If you ever need guidance on any of these aspects, I am more than willing to provide feedback and services related to brand identity.
</p>

If anyone could provide some tips that would be very appreciated. I just want to learn a little more about accessibility and ways to keep a good visual style at no cost.

I have a problem creating a swiper with image and text with swiper.js

I am using swiper.js and and I’m trying to have a swiper with text slide, video slide and image slide, the slide are created in a js file because their is different swiper with not the same amount of slide, not problem when creating a swiper with only image but when I try to add text slide it won’t work, the text isn’t really considered a slide and so on the same slide their is the text and the next slide an image or an another text for example.I don’t understand why I can’t put the text on a slide by himself.

function forceLazyLoad(swiper) {
    const slides = swiper.slides;
    slides.forEach((slide) => {
        const images = slide.querySelectorAll('.swiper-lazy');
        images.forEach((img) => {
            if (!img.src) {
                img.src = img.getAttribute('data-src');
            }
        });
    });
}


function createSlides(collection) {
    const swiperWrapper = document.getElementById('swiper-wrapper');
    swiperWrapper.innerHTML = '';
    collection.forEach((item, index) => {
        const slide = document.createElement('div');
        slide.className = 'swiper-slide';
        
        if (item.type === 'text' || item.type ==='textS') {
            const textDiv = document.createElement('div');
            textDiv.className = 'carousel-text swiper-lazy';
            textDiv.style.display = 'block';
            textDiv.innerHTML = item.content; 
            textDiv.style.textAlign = 'center';
            slide.appendChild(textDiv);
        } else if (item.type === 'video') {
            const video = document.createElement('video');
            video.setAttribute('data-src', item.src);
            video.className = 'swiper-lazy';
            video.controls = true;
            video.setAttribute('data-text', item.text);
            const preloader = document.createElement('div');
            preloader.className = 'swiper-lazy-preloader';
            slide.appendChild(video);
            slide.appendChild(preloader);
        } else if (item.type === 'double') {
            const img1 = document.createElement('img');
            img1.setAttribute('data-src', item.src1);
            img1.className = 'img-fluid swiper-lazy';
            img1.setAttribute('data-text', item.text);
            
            const img2 = document.createElement('img');
            img2.setAttribute('data-src', item.src2);
            img2.className = 'img-fluid swiper-lazy';
            img2.setAttribute('data-text', item.text2);
            
            const preloader1 = document.createElement('div');
            preloader1.className = 'swiper-lazy-preloader';
            
            const preloader2 = document.createElement('div');
            preloader2.className = 'swiper-lazy-preloader';

            slide.appendChild(img1);
            slide.appendChild(preloader1);
            slide.appendChild(img2);
            slide.appendChild(preloader2);
        } else if (item.type === 'quatre') {
            const img1 = document.createElement('img');
            img1.setAttribute('data-src', item.src1);
            img1.className = 'img-fluid2 swiper-lazy';
            img1.setAttribute('data-text', item.text);
            
            const img2 = document.createElement('img');
            img2.setAttribute('data-src', item.src2);
            img2.className = 'img-fluid2 swiper-lazy';
            img2.setAttribute('data-text', item.text2);

            const img3 = document.createElement('img');
            img3.setAttribute('data-src', item.src3);
            img3.className = 'img-fluid2 swiper-lazy';
            img3.setAttribute('data-text', item.text3);

            const img4 = document.createElement('img');
            img4.setAttribute('data-src', item.src4);
            img4.className = 'img-fluid2 swiper-lazy';
            img4.setAttribute('data-text', item.text4);
            
            const preloader1 = document.createElement('div');
            preloader1.className = 'swiper-lazy-preloader';
            
            const preloader2 = document.createElement('div');
            preloader2.className = 'swiper-lazy-preloader';

            const preloader3 = document.createElement('div');
            preloader3.className = 'swiper-lazy-preloader';

            const preloader4 = document.createElement('div');
            preloader4.className = 'swiper-lazy-preloader';

            slide.appendChild(img1);
            slide.appendChild(preloader1);
            slide.appendChild(img2);
            slide.appendChild(preloader2);
            slide.appendChild(img3);
            slide.appendChild(preloader3);
            slide.appendChild(img4);
            slide.appendChild(preloader4);
        } else if (item.type === 'slime') {
            const slimeDiv = document.createElement('div');
            slimeDiv.className = 'slime-slide';
            slimeDiv.innerHTML = '<div class="slime"></div>';
            slide.appendChild(slimeDiv);
        } else {
            const img = document.createElement('img');
            img.setAttribute('data-src', item.src); 
            img.id = 'dynamicImage';
            img.className = 'img-fluid swiper-lazy'; 
            img.setAttribute('data-text', item.text);
            img.onclick = () => toggleFullscreen(img);
            const preloader = document.createElement('div');
            preloader.className = 'swiper-lazy-preloader';
            img.addEventListener('mouseover', () => {
                const curseurTexte = document.getElementById('curseurTexte');
                curseurTexte.textContent = item.text;
                curseurTexte.style.display = 'block';
            });
    
            img.addEventListener('mousemove', (e) => {
                const curseurTexte = document.getElementById('curseurTexte');
                curseurTexte.style.left = (e.clientX + window.scrollX - 10) + 'px';
                curseurTexte.style.top = (e.clientY + window.scrollY - 30) + 'px';
            });
    
            img.addEventListener('mouseout', () => {
                const curseurTexte = document.getElementById('curseurTexte');
                curseurTexte.style.display = 'none';
            });
            slide.appendChild(img);
            slide.appendChild(preloader); 

        }
        swiperWrapper.appendChild(slide);
    });
    
    swiper.update(); 
    swiper.slideTo(0); 
    currentSlide = 0;
    swiper = new Swiper('.swiper-container', {
        loop: true,
        slidesPerView : 'auto',
        mousewheel: {
            invert: true,
        },
        lazy: {
            loadPrevNext: true,
            loadOnTransitionStart: true,
        },
        on:{
        slideChangeTransitionEnd: function () {
            currentSlide = swiper.realIndex; 
            if( currentSlide === previousIndex ) {
                swiper.slideTo(0);
            }
            previousIndex = currentSlide;
            //updateCarousel();
        },
        slideChange: function () {
            forceLazyLoad(swiper);
        }
    }
 
    });
}`

In this code their is a case for every type of slide, it’s use whenever their is a new swiper
I also “store” my image and text like this

'KITTY': [
        { type:'text', content:"text example"},
        { src: '/Carousel/HELLO KITTY/affiche/モントルハローキティ.webp', text: 'モントルハローキティ' }
    ],

And the html

<div class="swiper-container">
                <div class="swiper-wrapper" id="swiper-wrapper">
                </div>
                <div class="carousel-controls">
                  <div class="carousel-control-prev">&#8249;</div>
                  <div class="carousel-control-next">&#8250;</div>
              </div>
 </div>

I tried to change the setting of my swiper, slide per view or things like that, the thought the problem came from the lazy loader because without the forceLazyLoad function the image won’t show up but even without the problem remains the same.
Thank you for the help.

CKEditor5 can’t get editor instance

I have this CKEditor 5 code for my website. I want to get the data and set new data but i can’t get the editor instance. Here is revelant codes.

<script type="module">
import {
    // ...
} from 'ckeditor5';

import translations from 'ckeditor5/translations/tr.js';

const editorConfig = {
    // ...
};

let CKeditor;
ClassicEditor.create(document.querySelector('#editor'), editorConfig).then( editor => {
        editor.setData("<p>Hello World</p>");

        CKeditor = editor;
    } )
    .catch( error => {
        console.error( error );
    } );

console.log (CKeditor);
CKeditor.setData("<p>Another Hello World</p>");
</script>

<textarea name="content" id="editor" class="block"></textarea>

When executed, CKeditor value is undefined and the editor shows “Hello World”, not “Another Hello World”.
I tried other aproaches like this, but it didn’t work either.

const domEditableElement = document.querySelector( '.ck-editor__editable' );
    
const editorInstance = domEditableElement.ckeditorInstance;
    
editorInstance.setData( '<p>Another Hello World<p>' );

Javascript Node.js vs Python Flask, making a website [closed]

I’m an IT student and to pass my 3rd year i have to make a project based on business application.
I want to create a website that will allow for hotel service, i.e. accepting reservations, handling orders and tasks. Therefore, I am wondering which technologies I should use. In the classes I dealt with the older version of node.js, but reading articles on the Internet I often see that Flask is mentioned as an easier and more pleasant way of creating websites. Any opinions on these technologies? Or maybe other suggestions?

I was using old version of node.js and i was reading some articles about flask and both have their own advantages etc

This code is for a sticky note project the code is working for the first note but there’s a glitch after the first note

So I was making this sticky note adding project, where if you click on the “plus” icon a window will pop up where you can type your note content with your name.

For the first note it’s working good when I tap on preview another window pops-up and I can how my note actually looks before submitting or I can tap on “submit” in the first window to save it in an empty container.

So as I was saying it’s working well for the first note but from the second note the “preview” button isn’t working all the notes are getting saved inside preview but I want them inside that empty container just like the first Note.

HTML

<!DOCTYPE html> <html lang="en"> <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="sticky.css"> </head> <body>

<div class="welcome">
    <div class="text-1">
        <h1 class="h1">Welcome to stickey Notez just stick something memorable </h1>
    </div> </div>


<div class="plus">
    <div class="icon-plus">
        <div id="plus" class="fa-solid">+</div> 
    </div> </div>

<div id="newModel" class="model">    <h2>Note Form</h2>    <div class="close" id="closeButton">X</div>    <div id="notePreview" class="notez">
    <!-- <label class="content" for="inputTitle">Name:</label> -->
    <input class="content" placeholder="Name:" id="inputTitle" name="title">
    <!-- <label class="content" for="inputContent">Content:</label> -->
    <textarea class="content" placeholder="Content:" id="inputContent" name="content"></textarea>
    <div class="color-opts">

        <label class="color-option" style="background-color: rgb(131, 26, 26);">

        </label>
        <div class="color-option" style="background-color: rgb(118, 212, 117);">

        </div>
        <div class="color-option" style="background-color: rgb(250, 159, 220);">

        </div>
        <div class="color-option" style="background-color: rgb(102, 200, 215);">

        </div>
    </div>

   </div>    <div class="sutton">    <button  type="button" id="submitNote">Submit</button>    <button type="menu" id="noteMenu">Preview?</button>    </div>



</div>

<div id="preview" class="preview1">
    <div class="rutton">
    <button  type="button" id="submitNote1">Submit</button>    <button type="menu" id="noteeMenu">Back?</button> </div> </div>




<div id="savedNotesContainer">

</div>



<script src="sticky.js"></script> <script src="https://kit.fontawesome.com/29e2b58a51.js" crossorigin="anonymous"></script> </body> </html>

CSS

@import url('https://fonts.googleapis.com/css2?family=Lobster&family=Source+Code+Pro:ital,wght@0,200..900;1,200..900&display=swap');



body{
    padding: 0 40px;
    display: grid;
    /* align-items: center;
    flex-direction: column; */
    background: #0c0e16;
}

.h1{
    font-family: 'Lobster',cursive;
    display: flex;
    justify-content: center;
    font-size: 60px;
    color: #cc00ff;
    text-shadow: 2px 2px #601e6298;


}


.fa-solid{
    
  
    color: #ffffff;
    font-size: 70px;
    position: fixed;
    right: 50px;
    bottom: 70px;
    padding: 10px 14px;
    border-radius: 50%;
    transition:  background 0.5s ease;
    cursor: pointer;;
}
.fa-solid:hover{
    background: #cc00ff2c;
    
}
.icon-plus{
    display: flex;
    position: absolute;
    /* padding: 30px; */
    flex-direction: column;
    justify-content: center;
    right: 70px;
    top: 500px;
    
}

h2{
    font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
    font-size: 35px;
    color: white;
    margin: 0 0 20px 0;
}

.model{
    height: 400px;
    width: 50%;
    align-items: center;
    display: none;
    padding: 30px;
    justify-self: center;
    flex-direction: column;
    justify-content: space-evenly;
    background-color: rgba(67, 31, 44, 0.418);
    position: relative;
    border-radius: 20px;
    position: absolute;
    bottom: 100px;
}



.close{
    font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
    position: absolute;
    right: 10px;
    top: 10px;
    cursor: pointer;
    font-weight: bolder;
    padding: 10px;
    color: white;;

}
.close:hover{
    color: red;
}

label{
    display: block;
}

.color-opts{
    display: flex;
    margin: 10px;
}

.notez{
    background-color: #0c0e16;
    justify-content: center;
    align-self: center;
    flex-direction: column;
    padding: 30px;
    display: flex;
    width: 40%;
    border-radius: 20px;
}
.content{
    font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
    font-size: large;
    color: rgb(105, 93, 218);
    padding: 5px;
}
input, textarea{
    background-color: transparent;
    border: none;
    width: 70%;
    border-bottom: 1px dashed  green;
    margin: 10px; 
    /* resize: none;  */
    height: auto;
    
}

#inputTitle{
    font-weight: bolder;
    font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
    font-size: 30px;
    color: white;
}

#inputContent{
    font-family: Arial, Helvetica, sans-serif;
    font-size: 20px;
    color: white;
}

input,textarea:focus{
    outline: none;
}


textarea::-webkit-scrollbar {
    width: 10px;
  
}

textarea::-webkit-scrollbar-track {
    -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0);
    
}

textarea::-webkit-scrollbar-thumb {
  background-color: rgba(53, 48, 48, 0.377);
  cursor: pointer;
}

button{
    padding: 10px 10px;
    border: 3px solid rgb(255, 0, 0);
    background-color: #0c0e16;
    color: white;
    font-size: medium;
    cursor: pointer;
}

.color-option {
   height: 45px;
   width: 50px;
   margin: 0 10px;
   border-radius: 10px;
   border: 2px solid black;
}

.sutton{
    width: 100%;
    display: flex;
    justify-content: space-between;
}


.preview1{
    height: 500px;
    width: 600px;
    display: none;
    background-color: rgba(255, 255, 255, 0);
    position: absolute;
    bottom: 50px;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    justify-self: center;
    padding: 0 20px;

}

.note{
    width: 340px;
    height: 370px;
    display: flex;
    border-radius: 20px;
    color: white;
    font-size: 29px;
    flex-direction: column;
    padding: 10px;
    margin: 20px;
    align-items: center;
    font-family: Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif;
}
/* .note h3{
    
} */

.rutton{
    display: flex;
    justify-content: space-between;
    width: 100%;
}


JavaScript

document.addEventListener('DOMContentLoaded', function() {

const  newModel = document.getElementById("newModel");
const  plus = document.getElementById("plus")
const closeBtn = document.getElementById("closeButton")
const notePreview = document.getElementById("notePreview")

plus.addEventListener('click', () => {
    if(newModel.style.display === "none"){
        newModel.style.display = "flex"
    }
    else if(newModel.style.display = "flex"){
        newModel.style.display = "none"
    }
})

closeBtn.addEventListener('click',() =>{
    newModel.style.display = "none"
} 
)

const colorBtn = document.querySelectorAll(".color-option")


if (colorBtn.length > 0) {
    notePreview.style.backgroundColor = getComputedStyle(colorBtn[0]).backgroundColor;
}

colorBtn.forEach(child => {
    child.addEventListener('click', () => {
        notePreview.style.backgroundColor = getComputedStyle(child).backgroundColor;
    })
})


const noteMenu = document.getElementById("noteMenu");
const preview = document.getElementById("preview");
let newNote = null;


noteMenu.addEventListener('click', () => {
    const title = document.getElementById("inputTitle");
    const content = document.getElementById("inputContent");
    const noteColor = getComputedStyle(notePreview).backgroundColor;
    
    // const newNote = document.createElement('div');
        // newNote.classList.add('note');
        newNote = document.createElement('div');
        newNote.className = 'note';
        newNote.style.backgroundColor = noteColor;
        newNote.innerHTML = `
            <h3>${title.value}</h3>
            <p>${content.value}</p>
        `;

        preview.appendChild(newNote);
     
    
        // if (noteMenu === 'click') {
            // Toggling the preview visibility
            if (preview.style.display === "flex") {
                preview.style.display = "none";
            } else {
                preview.style.display = "flex";
            }
        

        inputTitle.value = "";
        inputContent.value = "";
        newModel.style.display = "none";
})



const noteemenu = document.getElementById("noteeMenu");
const submiteNote = document.getElementById("submitNote");
const savedNotesContainer = document.getElementById("savedNotesContainer");
const submiteNote1 = document.getElementById("submitNote1");











    noteemenu.addEventListener('click', () => {
    


        preview.style.display = "none";
        
        newModel.style.display = "flex"
        
        // newNote.remove();
    
    
    
    })
    



  
    // const note = document.getElementsByClassName("note");
   submiteNote.addEventListener('click', () => {
    


    if (newNote) {
        const savedNote = newNote.cloneNode(true); // Clone the previewed note
        savedNotesContainer.appendChild(savedNote);
        newNote = null;
        preview.innerHTML = ''; // Clear the preview after submission
        preview.style.display = "none"; // Hide the preview
    } else {
        console.log("No note to submit.");
    }
});

submiteNote1.addEventListener('click', ()=>{
    if (newNote) {
        const savedNote = newNote.cloneNode(true); // Clone the previewed note
        savedNotesContainer.appendChild(savedNote);
        newNote = null;
        preview.innerHTML = ''; // Clear the preview after submission
        preview.style.display = "none"; // Hide the preview
    } else {
        console.log("No note to submit.");
    }
})











})