Changing colors
We want our users to be able to change the colors of our note cards. To do this we will render out a series of colors within the <Controls/>
component, then allow users to click on these colors to update a particular note card.
Color component
Each color will have it's own component: src/components/Color.jsx
Start by creating the following component and adding some functionality so we can see the selected color in the console.
color
will be passed down through the<Controls/>
component.
const Color = ({ color }) => {
const changeColor = () => {
console.log("CHange color clicked:", color);
};
return (
<div
onClick={changeColor}
className="color"
style={{ backgroundColor: color.colorHeader }}
></div>
);
};
Import <Color/>
and render out each color one by one while passing down the color object on each iteration.
//...
import colors from "../assets/colors.json";
import Color from "./Color";
const Controls = () => {
return (
<div id="controls">
<AddButton />
{colors.map((color) => (
<Color key={color.id} color={color} />
))}
</div>
);
};
Styling the <Color/>
component
.color {
background-color: grey;
height: 40px;
width: 40px;
border-radius: 50%;
cursor: pointer;
transition: 0.3s;
}
.color:hover {
height: 45px;
width: 45px;
}
Selected Note
Before we can update a Note color we first need to select a note. A "selected note" can be defined by any note we have actively clicked on or edited.
We'll set our selected note inside of the NoteContext
by setting the following state.
Be sure to pass the state and setter method down in contextData
so we can access these throught our app.
const NotesProvider = ({ children }) => {
const [selectedNote, setSelectedNote] = useState(null);
//...
const contextData = {
//...
selectedNote,
setSelectedNote
};
There are 2 ways to set a the selectedNote
state.
- On note header mousedown
- On focus, before we begin updating the note text
//...
const { setSelectedNote } = useContext(NotesContext);
const mouseDown = (e) => {
if (e.target.className === "card-header") {
//....
setSelectedNote(note);
}
};
//...
<div className="card-body">
<textarea
onKeyUp={handleKeyUp}
onFocus={() => {
setZIndex(cardRef.current);
setSelectedNote(note);
}}
Let's test this out by retreiving the selected note inside of the color component, and consoling it out when the color is clicked.
const Color = ({ color }) => {
const {selectedNote} = useContext(NotesContext)
const changeColor = () => {
console.log("Selected color:", selectedNote);
};
Handle color change
Once we get access to the selected note we can then update the note color on the frontend as well as in our database by doing the following:
- Find where note is in our
notes
state using the note id - Update our
notes
state - Sending new colors back to our database for updating.
const changeColor = () => {
console.log("Selected color:", selectedNote);
try {
const currentNoteIndex = notes.findIndex(
(note) => note.$id === selectedNote.$id
);
const updatedNote = {
...notes[currentNoteIndex],
colors: JSON.stringify(color),
};
const newNotes = [...notes];
newNotes[currentNoteIndex] = updatedNote;
setNotes(newNotes);
db.notes.update(selectedNote.$id, {
colors: JSON.stringify(color),
});
} catch (error) {
alert("You must select a note before changing colors");
}
};