Add Button
In this step we will work on the note create functionality, which will be built out in it's own separate component, wrapping the Plus
icon
Add Component
Create a new component called components/AddButton.jsx
We'll create the Plus
icon in the next step.
import Plus from "../icons/Plus";
const AddButton = () => {
return (
<div id="add-btn">
<Plus />
</div>
);
};
Plus icon
Create the folling icon component inside of src/icons/Plus.jsx
const Plus = ({ size = "24", color = "#FFFFFF" }) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
stroke={color}
fill="none"
strokeWidth="2.5"
>
<path strokeLinecap="round" d="M18 12H6M12 6v12"></path>
</svg>
);
};
Controls panel
Our <AddButton/>
will be place inside of another component called src/components/Controls
.
import AddButton from "./AddButton";
const Controls = () => {
return (
<div id="controls">
<AddButton />
</div>
);
};
export default Controls;
Add the Controls
component inside of NotesPage.jsx
. This item will have a fixed position, so where we place this is not particularly important.
<div>
{notes.map((note) => (
//...
))}
<Controls />
</div>
Add CSS to controls and button
#controls {
display: flex;
flex-direction: column;
gap: 1em;
align-items: center;
position: fixed;
left: 1em;
top: 50%;
transform: translateY(-50%);
background-color: #35363e;
padding: 1em 1em;
border-radius: 40px;
box-shadow: 0 1px 1px hsl(0deg 0% 0% / 0.075), 0 2px 2px hsl(0deg 0% 0% /
0.075), 0 4px 4px hsl(0deg 0% 0% / 0.075), 0 8px 8px hsl(0deg
0% 0% / 0.075), 0 16px 16px hsl(0deg 0% 0% / 0.075);
z-index: 10000;
}
#add-btn {
background-color: rgba(107, 107, 107, 1);
display: flex;
justify-content: center;
align-items: center;
height: 40px;
width: 40px;
border-radius: 50%;
cursor: pointer;
transition: 0.3s;
}
#add-btn:hover {
height: 45px;
width: 45px;
}
Note color options
Each note will have 4 different color options. Let's store these options and their values in a separate file called src/assets/colors.json
We will reference the first color in this array as the default note color when a new note is added.
[
{
"id": "color-yellow",
"colorHeader": "#FFEFBE",
"colorBody": "#FFF5DF",
"colorText": "#18181A"
},
{
"id": "color-green",
"colorHeader": "#AFDA9F",
"colorBody": "#BCDEAF",
"colorText": "#18181A"
},
{
"id": "color-blue",
"colorHeader": "#9BD1DE",
"colorBody": "#A6DCE9",
"colorText": "#18181A"
},
{
"id": "color-purple",
"colorHeader": "#FED0FD",
"colorBody": "#FEE5FD",
"colorText": "#18181A"
}
]
addNote
method
To add a note, we will refence the first index in the colors
array, as well as a default starting position for our x
& y
position.
This data will be pass along as the payload in the create
method, as a new note is added to our database.
import colors from "../assets/colors.json";
const AddButton = () => {
const startingPos = useRef(10);
const addNote = async () => {
const payload = {
position: JSON.stringify({
x: startingPos.current,
y: startingPos.current,
}),
colors: JSON.stringify(colors[0]),
};
const response = await db.notes.create(payload);
};
return (
<div id="add-btn" onClick={addNote}>
<Plus />
</div>
);
};
Update context state
Once a note is added, we will reference our notes state and add the new note to our current state.
As a note is added we will also increment the starting position to ensure that the next note wont overlap the previously created note.
import { useContext } from "react";
import { NotesContext } from "../context/NotesContext";
const AddButton = () => {
const { setNotes } = useContext(NotesContext);
//...
const addNote = async () => {
const payload = {
//..
};
startingPos.current += 10;
const response = await db.notes.create(payload);
setNotes((prevState) => [response, ...prevState]);
};
Staring zIndex
To ensure a new note is always visible, lets call the setZIndex
method with the useEffect
hook inside of our <NoteCard/>
component.
useEffect(() => {
autoGrow(textAreaRef);
setZIndex(cardRef.current);
}, []);