Creating a javascript/react transition for expanded - javascript

I'm trying to create a transition that will expand this over half a second. I'm not sure how to go about this I tried attaching css but no use. Any suggestions?
const getFullMetricList = () =>
Object.keys(comparisonChartsKeyMap)
.map((category) => Object.values(comparisonChartsKeyMap[category]))
.flat();
const MetricCatalog = ({ AddMetric, DeleteMetric, Metrics, width, height }) => {
const [expanded, setExpanded] = useState(false);
const [filteredMetricList, setFilteredMetricList] = useState(
getFullMetricList()
);
const handleFuzzyFilterItems = (value) => {
let newConf = matchSorter(getFullMetricList(), value);
setFilteredMetricList(newConf);
};
const handleCloseCatalog = () => {
setExpanded(false);
setFilteredMetricList(getFullMetricList());
};
if (!expanded) {
return (
<div
className='metric-catalog-btn-container'
onClick={() => setExpanded(!expanded)}
>
Metric Catalog
</div>
);
}

import { useState } from "react";
import "./styles.css";
export default function App() {
const [expanded, setExpanded] = useState(false);
return (
<div
className={expanded ? "expanded" : ""}
onClick={() => setExpanded(!expanded)}
>
hello
</div>
);
}
div {
width: 100px;
height: 100px;
background: red;
transition: width 0.5s;
}
.expanded {
width: 300px;
}
complete code link

Related

how to pin a note and sort it in an array

I was creating a notes app in react which has a pin functionality such that when I click on the pin icon on a particular note that particular note is displayed first. the user should only be able to pin 2 notes (and I've added that condition) the problem is The pin functionality is working perfectly fine but when I again click on a pinned note I want to un-pin it and again arrange it back in its place, how can i achieve this?
React code =
import React, { useState } from "react";
import "../styles/Notes.css";
import { useToast, Wrap, WrapItem, Button } from '#chakra-ui/react'
import { BsFillPinFill } from "react-icons/bs"
import { BsTrashFill } from "react-icons/bs"
import { BsPinAngle } from "react-icons/bs";
function NotesComponent() {
const [notes, setNotes] = useState([]);
const [title, setTitle] = useState("");
const [tagline, setTagline] = useState("");
const [body, setBody] = useState("");
const [page, setPage] = useState(1);
const toast = useToast()
// submit handler
const handleSubmit = (event) => {
event.preventDefault();
if (!title || !tagline || !body) {
toast({
title: 'Please complete the input',
status: 'error',
duration: 9000,
isClosable: true,
});
return;
}
// generating randome number to use as id
function generateUniqueNumber() {
let uniqueNumber = "";
while (uniqueNumber.length < 4) {
let digit = Math.floor(Math.random() * 10);
if (!uniqueNumber.includes(digit)) {
uniqueNumber += digit;
}
}
return uniqueNumber;
}
let number = generateUniqueNumber();
setNotes([...notes, { title, tagline, body, pinned: false, id: number }]);
setTitle("");
setTagline("");
setBody("");
};
// executing on click on the pen icon
const togglePin = (index) => {
setNotes(
notes.map((note, i) => {
if (i === index) {
let newNote = { ...note };
newNote.pinned = !note.pinned;
return newNote;
}
return note;
})
);
};
// sorting it
const sortedNotes = notes.sort((a, b) => {
if (a.pinned === b.pinned) {
return 0;
}
return a.pinned ? -1 : 1;
})
.map((note, i) => {
let newNote = { ...note };
if (note.pinned) {
const pinnedCount = notes.filter((n) => n.pinned).length;
if (pinnedCount > 2) {
newNote.pinned = false;
}
}
return newNote;
});
const pages = [1, 2, 3, 4, 5, 6];
const pageChnageHandler = (e) => {
setPage(e.target.innerText);
};
const deleteHandler = (id) => {
let index = id
const newArrayAfterDeleting = notes.filter((item) => item.id !== index)
setNotes(newArrayAfterDeleting)
}
return (
<div className="notes-app-container">
<form onSubmit={handleSubmit} className="notes-form">
<input
type="text"
placeholder="Title"
value={title}
onChange={(event) => setTitle(event.target.value)}
className="notes-input"
/>
<input
type="text"
placeholder="Tagline"
value={tagline}
onChange={(event) => setTagline(event.target.value)}
className="notes-input"
/>
<textarea
placeholder="Body"
value={body}
onChange={(event) => setBody(event.target.value)}
className="notes-textarea"
/>
<button type="submit" className="notes-button">
Add Note
</button>
</form>
<div className="enteredNotesMainParent">
{sortedNotes.slice(page * 6 - 6, page * 6).map((note, i) => (
<div key={i} className="enteredNoteIndivitual">
<div>{note.title}</div>
<div>{note.tagline}</div>
<div>{note.body}</div>
<br />
<div className="noteCtaHold">
<div>
<BsFillPinFill className="noteIcon" onClick={() => togglePin(i)} />
</div>
<div>
<BsTrashFill className="noteIcon" onClick={() => deleteHandler(note.id)} />
</div>
</div>
</div>
))}
</div>
{notes.length === 0 ? <p> Add some notesâś… </p> : ""}
{notes.length >= 4 && <div className="pagesHold">
{pages.map((item) => {
return <p onClick={pageChnageHandler} className="indivitualPage"> {item} </p>
})}
</div>}
</div>
);
}
export default NotesComponent;
can somebody please help me achieve this that if a note is pinned and if I click on that pinned note it should get un-pinned and re arrange back
You don't necessarily have to use sort() to get the pinned notes on top.
Just render the list twice: once for the pinned notes, filtering out the unpinned ones, and again for the rest of the list, filtering the pinned ones.
This way you don't have to concern yourself with where a given note is within the original list, because the original list doesn't change.
// creates a list of sample notes; not relevant to the funcionality.
const notes = Array.from({length: 6}, (_, i) => ({
title: `Note ${i + 1}`,
id: i
}))
function Notes ({notes}) {
// keep a list of the pinned note ids
const [pinned, setPinned] = React.useState([]);
// filter to get separate lists of pinned and unpinned notes
const pinnedNotes = notes.filter(({ id }) => pinned.includes(id));
const unpinnedNotes = notes.filter(({ id }) => !pinned.includes(id));
// to pin a note: add its id to the pinned list
const pin = id => setPinned([...pinned, id]);
// to unpin a note: remove its id from the pinned list
const unpin = id => {
pinned.splice(pinned.indexOf(id), 1);
setPinned([...pinned]);
}
// render both lists
return (
<div className="container">
<ul className="pinned">
{ pinnedNotes.map(note => (
<li key={note.id} onClick={() => unpin(note.id)}>{note.title}</li>
))}
</ul>
<ul className="unpinned">
{ unpinnedNotes.map(note => (
<li key={note.id} onClick={() => pin(note.id)}>{note.title}</li>
))}
</ul>
</div>
)
}
const root = ReactDOM.render(<Notes notes={notes} />, document.getElementById('root'));
/* all cosmetic. not necessary for it to work. */
.container {
font-family: sans-serif;
font-size: 12px;
}
.pinned {
background: skyblue;
margin-bottom: 1rem;
display: flex;
flex-wrap: wrap;
gap: 0.5em;
padding: 0 0.5em;
}
.pinned:empty::after {
content: "No pinned items. Click a note below to pin it.";
padding: 1rem;
display: block;
text-align: center;
}
.unpinned:empty::after {
content: "No unpinned notes.";
padding: 1rem;
display: block;
text-align: center;
}
.pinned li {
background: aliceblue;
}
.unpinned {
background: aliceblue;
}
li {
margin: 0.5em 0;
padding: 1em;
border: 1px solid steelblue;
border-radius: 2px;
}
ul {
list-style: none;
margin: 0;
padding: 0.25em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

hiding and showing array of images

So I have an array of images, which I would like to hide or show on a click of a button.
right now when I try to hide the image, it will hide the entire array.
import "./main.css";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import React, { useEffect, useState } from "react";
import {
faCircleChevronLeft,
faCircleChevronRight,
faCircleXmark,
} from "#fortawesome/free-solid-svg-icons";
const Main = ({ galleryImages }) => {
const [slideNumber, setSlideNumber] = useState(0);
const [openModal, setOpenModal] = useState(false);
const [pics, setPics] = useState([]);
const [show, toggleShow] = useState(true);
// buttons next to name of diff charts (hide/show chart)
const handleOpenModal = (index) => {
setSlideNumber(index);
setOpenModal(true);
};
const removeImage = (id) => {
setPics((oldState) => oldState.filter((item) => item.id !== id));
};
// const hide = () => {
// setShow(false)
// }
const handleCloseModal = () => {
setOpenModal(false)
}
useEffect(()=> {
setPics(galleryImages)
},[]);
return (
<div>
<button onClick={() => toggleShow(!show)}>toggle: {show ? 'show' : 'hide'}</button>
{show &&
<div>
{pics.map((pic) => {
return (
<div style = {{marginBottom:'100px'}}>
{pic.id}
<img
src={pic.img}
width='500px'
height='500px'
/>
<button onClick ={() => removeImage(pic.id)}>Delete</button>
</div>
)
})}
</div>
I tried making a state component to try to hide and show the images, however it will hide the entire array instead of the individual image
i would add a show var to the galleryImages array and then set it so you get control of each image like this
import { useState } from "react";
import { v4 as uuidv4 } from "uuid";
import "./main.css";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import React, { useEffect, useState } from "react";
import {
faCircleChevronLeft,
faCircleChevronRight,
faCircleXmark,
} from "#fortawesome/free-solid-svg-icons";
function Main({ galleryImages }) {
const [slideNumber, setSlideNumber] = useState(0);
const [openModal, setOpenModal] = useState(false);
const [pics, setPics] = useState([]);
// buttons next to name of diff charts (hide/show chart)
const toggleShow = ({ id, show }) => {
setPics((oldState) =>
oldState.map((item) => {
if (item.id !== id) return item;
return { ...item, show: !show };
})
);
};
const removeImage = (id) => {
setPics((oldState) => oldState.filter((item) => item.id !== id));
};
useEffect(() => {
setPics(
galleryImages.map((galleryImage) => {
return { ...galleryImage, show: true };
})
);
}, []);
return (
<div>
<div>
{pics.map((pic) => {
return (
<>
<button
onClick={() => toggleShow({ show: pic.show, id: pic.id })}
>
toggle: {pic.show ? "show" : "hide"}
</button>
{pic.show && (
<div style={{ marginBottom: "100px" }}>
{pic.id}
<img src={pic.img} width="500px" height="500px" />
<button onClick={() => removeImage(pic.id)}>Delete</button>
</div>
)}
</>
);
})}
</div>
</div>
);
}
export default Main;
`
If you would like the option to hide individual pics, to accomplish this you are correct in your state component approach.
First you can create a pic component that has its own state with a hide/show button:
export default function Pic({pic}) {
const [showPic, setShowPic] = useState(true);
const handleClick = () => {setShowPic(!showPic)}
return (
<div>
<div style={showPic ? {display : "block"} : {display : "none"}}>
<img
src={pic.img}
width='500px'
height='500px'
/>
</div>
<button onClick={handleClick}>{showPic ? 'Hide' : 'Show'}</button>
</div>
)
}
Next, you can import this component into your main file
import Pic from 'location/Pic.js';
and map each pic to a <Pic> component.
{pics.map((pic) => <Pic pic={pic} key={pic.id}/>)}
Now the images will be shown each with their own Hide/Show button that can toggle their display with the state contained within each <Pic/> component. This is good practice because toggling one image will not cause a re-render of the entire image gallery.

React play different audio files at once - working with different refs

I'm creating a small app that plays an audio file and have some functionalities (loop, stop, mute). My goal is to add some more audio files that all should be played and stopped at once (one button to control all), but each will have a mute button, and I'm not sure what is the best practice to do so. I used useRef and thought maybe I need to set a refs array but how will I be able to start/stop them all at once, but still have the ability to control the mute separately?
This is my code so far. I guess I should split and have a different component for the audio sounds. Thanks for helping!
import React, {useState, useRef, useEffect} from 'react'
import {ImPlay2} from "react-icons/im"
import {ImStop} from "react-icons/im"
import styled from "styled-components"
import drums from '../loopfiles/DRUMS.mp3'
//import other audio files//
const AudioPlayer = () => {
const [isPlaying, setIsPlaying] = useState(false);
const [isLooping, setIsLooping] = useState(false);
const [isOnMute, setIsOnMute] = useState(false);
const audioRef = useRef(new Audio(drums));
useEffect(() => {
if (isOnMute) {
audioRef.current.volume=0;
}
else {
audioRef.current.volume=1;
}
}, [isOnMute]);
useEffect(() => {
if (isPlaying) {
audioRef.current.play();
} else {
audioRef.current.pause();
audioRef.current.load();
}
}, [isPlaying]);
useEffect(() => {
if (isLooping) {
audioRef.current.loop = true;
} else {
audioRef.current.loop = false;
}
}, [isLooping]);
return (
<div>
{!isPlaying ? (
<button type="button"
className="play"
onClick={() => setIsPlaying(true)}>
<ImPlay2></ImPlay2> Play
</button>
) : (
<button type="button"
className="pause"
onClick={() => setIsPlaying(false)}>
<ImStop></ImStop> Stop
</button>
)}
<Flex>
<Switcher selected={isLooping} />
<Text
onClick={() => setIsLooping(true)}>
Loop
</Text>
<Text
onClick={() => setIsLooping(false)}>
Unloop
</Text>
</Flex>
<Flex>
<Switcher selected={isOnMute} />
<Text
onClick={() => setIsOnMute(true)}>
Mute
</Text>
<Text
onClick={() => setIsOnMute(false)}>
UnMute
</Text>
</Flex>
</div>
)
}
const Flex = styled.div`
margin-top: 5px;
display: flex;
align-items: center;
border-radius: 2px;
background: grey;
height: 20px;
width: 120px;
position: relative;
margin-bottom: 5px;
`;
const Switcher = styled.div`
background: black;
border-radius: 2px;
height: 20px;
line-height: 41px;
width: 50%;
cursor: pointer;
position: absolute;
transition: 0.5s;
-webkit-transition: 0.5s;
-moz-transition: 0.5s;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16);
z-index: 1;
left: ${({ selected }) =>
selected === true ? "0px" : "60px"};
`;
const Text = styled.div`
color: ${({ selected }) => (selected ? "black" : "white")};
font-size: 13px;
font-weight: 20;
line-height: 4px;
padding: 30;
width: 50%;
text-align: center;
cursor: pointer;
`;
export default AudioPlayer
If you would like to mute/unmute individual sounds, but play/pause all sounds together, then you will need to create a mute/unmute slider for each sound. I can think of a number of ways to do this. The "best choice" might depend upon the standards in the rest of the application, how many sounds you're importing, and whether they're likely to change.
Method 1: One way to do this would be creating one array containing isOnMute values for each sound and another array containing all refs, and then map(...) over each of the elements of the isOnMute array to create your sliders.
Method 2: Another way would be to have one array of objects containing all sounds, and then the ref and the isOnMute values could be stored within each object. You could map(...) over that to create your sliders as well.
Method 3: You could also create separate child components for each sound like you said, and then pass the mute property between the parent AudioPlayer and the child AudioChannel components.
Then anytime the play/pause button is clicked, you would need to update each of the refs in the array (via a forEach or each of the child components via toggling a single isPlaying property).
Regardless of which you choose, I also might like to recommend the use-sound npm package. It makes managing multiple sounds and their properties a little bit less cumbersome in my opinion, including the ability to play and pause with a single method call.
Here is a snippet for you/
Also do not forget to use according ids instead of idx and idx2
const AudioList = () => {
/* here populate the array in format: array of objects
{
drums: mp3file,
isPlaying: boolean,
setIsPlaying: boolean,
isLooping: boolean,
setIsLooping: boolean,
isOnMute: boolean,
setIsOnMute: boolean,
}[]
*/
const [audios, setAudios] = useState([
{ isPlaying: true, isOnMute: false, isLooping: true, drums: "Your mpr" },
]); // use initial audios
return (
<div>
<button
onClick={() => {
// similar to start all, mute all, you have full controll logic over all elements
// also you could implement add new audiofile, or delete, similar logic :)
setAudios((audios) =>
audios.map((audio) => ({ ...audio, isPlaying: false }))
);
}}
>
Stop all
</button>
<div>
{audios.map((audio, idx) => (
<AudioPlayer
key={idx}
{...audio}
setIsPlaying={(val) =>
setAudios((audios) =>
audios.map((audio, idx2) =>
idx === idx2 ? { ...audio, isPlaying: val } : audio
)
)
}
// similar for setMute and setLopping function,
// i think you can figure it out, it is just a snippet:)
/>
))}
</div>
</div>
);
};
const AudioPlayer = ({
drums,
isPlaying,
setIsPlaying,
isLooping,
setIsLooping,
isOnMute,
setIsOnMute,
}) => {
const audioRef = useRef(new Audio(drums));
// also you have full controll of element inside component
useEffect(() => {
if (isOnMute) {
audioRef.current.volume = 0;
} else {
audioRef.current.volume = 1;
}
}, [isOnMute]);
useEffect(() => {
if (isPlaying) {
audioRef.current.play();
} else {
audioRef.current.pause();
audioRef.current.load();
}
}, [isPlaying]);
useEffect(() => {
if (isLooping) {
audioRef.current.loop = true;
} else {
audioRef.current.loop = false;
}
}, [isLooping]);
return (
<div>
{!isPlaying ? (
<button
type="button"
className="play"
onClick={() => setIsPlaying(true)}
>
<ImPlay2></ImPlay2> Play
</button>
) : (
<button
type="button"
className="pause"
onClick={() => setIsPlaying(false)}
>
<ImStop></ImStop> Stop
</button>
)}
<Flex>
<Switcher selected={isLooping} />
<Text onClick={() => setIsLooping(true)}>Loop</Text>
<Text onClick={() => setIsLooping(false)}>Unloop</Text>
</Flex>
<Flex>
<Switcher selected={isOnMute} />
<Text onClick={() => setIsOnMute(true)}>Mute</Text>
<Text onClick={() => setIsOnMute(false)}>UnMute</Text>
</Flex>
</div>
);
};
I changed the following:
I added Audios.js containing:
const audios = () => {
return [
{
color: 'lightgreen',
isOnMute: false,
audio: drums,
title: 'Drums'
}, ...
AudioList.js:
const AudioList = ({isPlaying, isLooping}) => {
const [audioToPlay, setAudioToPlay] = useState();
useEffect(()=> {
setAudioToPlay(audios())
},[]) ....//and mapped through <AudioItem>:
AudioItem.js:
const AudioItem = ({audio, isPlaying, isLooping}) => {
const [isOnMute, setIsOnMute] = useState(false);
const audioRef = useRef(null);
useEffect(() => {
if (isLooping) {
audioRef.current.loop = true;
} else {.... //other functionality
added a progressBar.js:
const ProgressBar = ({isPlaying}) => {
const [completed, setCompleted] = useState({
count: 0
});const intervalId = useRef(null)
useEffect(() => {...
ControlPanel.js:
const ControlPanel = ({
setIsLooping, isLooping, isPlaying, setIsPlaying}) => {
return (
<div>
<PlayButton> //....
and Home.js containing controlpanel, AudioList, ProgressBar:
const Home = () => {
const [isPlaying, setIsPlaying] = useState(false);
const [isLooping, setIsLooping] = useState(false);
return (
<div>
<ControlPanel
setIsLooping={setIsLooping} //....

React ProgressBar

Hello I need to setup a progress bar. So when I press on the button progress bar shows, the button and the content inside of it dispears proggress bar starts to go 0 100 and as well shows some text above, and
when it reaches the 100% progress bar disppears and text above, but after that new text shows. Thanks in Advance
import React,{useEffect, useState} from 'react'
import LinearProgress from '#material-ui/core/LinearProgress'
const useStyles = makeStyles({
root: {
width: '100%',
},
});
const Content =(props)=> {
const classes = useStyles();
const[hideContent, setHideContent]= React.useState(false)
const [progress, setProgress] = React.useState(10);
function handleClick12 ()
{setHideEset(true) }
useEffect(() => {
const timer = setInterval(() => {
setProgress((prevProgress) => (prevProgress >= 100 ? 10 : prevProgress + 10));
}, 800);
return () => {
clearInterval(timer);
};
}, []);
return (
{!hideContent &&
<div className='esetNod__info'>
<h3>Hello</h3>
<Button onClick={handleClick12} className='fix__button'variant='outlined'></Button>
<div >
<LinearProgress value={progress} />
</div>
</div>
}
</div>
)
}
export default Content;
I tried to write something for you:
import React, { useState } from "react";
import LinearProgress from "#material-ui/core/LinearProgress";
const Content = () => {
const [isLoading, setIsLoading] = useState(false);
const [hasLoaded, setHasLoaded] = useState(false);
const [progress, setProgress] = useState(0);
const handleClick = () => {
setIsLoading(true);
const interval = setInterval(() => {
setProgress((prevProgress) => {
const next = prevProgress + 10;
if (next === 100) {
clearInterval(interval);
setIsLoading(false);
setHasLoaded(true);
}
return next;
});
}, 800);
};
if (!isLoading && !hasLoaded) {
return (
<div className="esetNod__info">
<h3>Pre load content</h3>
<button onClick={handleClick} className="fix__button">
Load Content
</button>
</div>
);
} else if (isLoading && !hasLoaded) {
return (
<diV>
<h3>Loading content</h3>
<LinearProgress value={progress} />
</diV>
);
} else {
return (
<div>
<h3>Post load content</h3>
</div>
);
}
};
export default Content;

React Context values not referenced correctly in dynamic element functions

I created a Context and hook to be able to see if areas of the application has been changed, and validate actions based on the current state in context.
Its called DirtyContext and the Implementation is used as follows:
const {isDirty, setDirtyContextFor} = useDirtyContext();
setDirtyContextFor(key) - Ads a key to a list, to mark something as dirty.
isDirty - Reports the current state of the application based on a memoized value that updates everytime something is removed or added to the list of keys.
I have a list of objects, that helps me create a set of dynamic elements on the page.
const thisFunctionWillLooseContextReference = (e) => {
e.preventDefault();
console.log('Context Value - IsDirty: ', isDirty)
};
const [buttons, setButtons] = useState(() => {
return [{onClick: thisFunctionWillLooseContextReference}]
});
This is tied together in the UI using the following:
const renderButtons = () => {
return buttons.map((btn, index) => (
<button onClick={btn.onClick}>Button-{index}</button>
));
}
Even if the context value isDirty is set to true, the function passed to the button, always just reports the initial value of isDirty.
Would appreciate any help on why this is happening, and how i can get the expected results (which is the correct/current value of isDirty)
Codepen - Have a look at the console when clicking the buttons:
(Code and implementation details are reduced to the smallest reproducable state)
const { useState, useMemo } = React;
const DirtyContext = React.createContext();
const DirtyContextProvider = ({ children }) => {
const [dirtyList, setDirtyList] = useState(new Set());
const isDirty = useMemo(() => {
return dirtyList.size > 0;
}, [dirtyList]);
function setDirtyStateFor(componentName) {
const newDirtyList = new Set(dirtyList);
newDirtyList.add(componentName);
setDirtyList(newDirtyList);
}
return (<DirtyContext.Provider value={{
setDirtyStateFor,
isDirty,
}}>
{children}
</DirtyContext.Provider>);
};
const useDirtyContext = () => React.useContext(DirtyContext);
const MyDirtyLittleApp = () => {
const {isDirty, setDirtyStateFor} = useDirtyContext();
const [input, setValue] = useState("");
const thisFunctionWillLooseContextReference = (e) => {
e.preventDefault();
console.log('Context Value - IsDirty: ', isDirty)
};
const [buttons, setButtons] = useState(() => {
return [{onClick: thisFunctionWillLooseContextReference}]
});
function handleInput(event) {
setValue(event.target.value);
setDirtyStateFor('MyDirtyLittleApp');
}
function updateInput(event) {
event.preventDefault();
console.log('Am i dirty ?', isDirty)
}
const renderButtons = () => {
return buttons.map((btn, index) => (
<button class="button is-dark" data-reactstuff={isDirty} onClick={btn.onClick}>btn {index}</button>
));
}
return (
<React.Fragment>
<h1>{isDirty ? 'I`m Dirty': 'I`m Clean'}</h1>
<form className="form">
<div class="field">
<label for="name-1">Update DirtyContext</label>
<div class="control">
<input type="text" value={input} name="name-1" onChange={handleInput} class="input"/>
</div>
</div>
<div class="field">
<div class="control">
<button onClick={updateInput} class="button is-dark">Save</button>
{renderButtons()}
</div>
<control>
<h5>Check console for results when clicking on the buttons</h5>
</control>
</div>
</form>
</React.Fragment>
)
}
const App = () => {
return (
<DirtyContextProvider>
<div className="box">
<MyDirtyLittleApp />
</div>
</DirtyContextProvider>
)
}
ReactDOM.render(<App />,
document.getElementById("root"))
body {
height: 100vh;
margin: 0;
display: grid;
place-items: center;
}
.box {
width: 300px;
h1 {
font-size: 20px;
margin: 0 0 1rem 0;
}
h5 {
font-size: 12px;
}
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css" type="text/css" />
<script src="https://unpkg.com/react#16.13.1/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom#16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
https://codepen.io/Cnordbo/pen/zYqwVRL

Categories

Resources