Final NoteCard Styling
We've already added some basic stying to our note card component, but now it's time to add the final touches.
Body styling
- Inside of the card component, add another div around
{body}
and give this dive the class name ofcard-body
- Within the card body div, add a
<textarea>
and pass in the the values shown below.
<div className="card"
//...
>
<div className="card-body">
<textarea
style={{ color: colors.colorText }}
defaultValue={body}
></textarea>
</div>
</div>
Add the following styles in index.css
.card-body {
padding: 1em;
border-radius: 0 0 5px 5px;
}
.card-body textarea {
background-color: inherit;
border: none;
width: 100%;
height: 100%;
resize: none;
font-size: 16px;
}
textarea:focus {
background-color: inherit;
outline: none;
width: 100%;
height: 100%;
}
Header Styling
Each card will have it's own header bar. This will sit within our card
component, above card-body
<div className="card"
//...
>
<div
className="card-header"
style={{ backgroundColor: colors.colorHeader }}
></div>
<div className="card-body">
</div>
Card header styling: index.css
.card-header {
background-color: #9bd1de;
border-radius: 5px 5px 0 0;
display: flex;
justify-content: space-between;
align-items: center;
padding: 5px;
}
Create a trash Icon in src/icons/Trash.jsx
const Trash = ({ size = "24" }) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width={size}
height={size}
stroke="#000000"
fill="none"
strokeWidth="1.5"
>
<path d="m6 8 .668 8.681c.148 1.924.222 2.885.84 3.423.068.06.14.115.217.165.685.449 1.63.26 3.522-.118.36-.072.54-.108.721-.111h.064c.182.003.361.039.72.11 1.892.379 2.838.568 3.523.12.076-.05.15-.106.218-.166.617-.538.691-1.5.84-3.423L18 8"></path>
<path
strokeLinecap="round"
d="m10.151 12.5.245 3.492M13.849 12.5l-.245 3.492M4 8s4.851 1 8 1 8-1 8-1M8 5l.447-.894A2 2 0 0 1 10.237 3h3.527a2 2 0 0 1 1.789 1.106L16 5"
></path>
</svg>
);
};
Import the new <Icon/>
component into the <NoteCard/>
header.
<div className="card-header"
//....
>
<Trash />
</div>
Absolute Positioning
Each card will have its own unique position and can be placed anywhere on our page. To accomplish this, we will give every card an absolute position and then utilize the position
x
and y
values to set this in the styles.
.card {
/* ... */
position: absolute;
}
const NoteCard = ({ note }) => {
//...
return (
<div
className="card"
style={{
backgroundColor: colors.colorBody,
left: `${position.x}px`,
top: `${position.y}px`,
}}
>
//...
Autogrow text field
Because there is not predetermined height for each card, we will auto adjust the card size based on the contents within the text area.
By using a ref
we will access the textarea and auto grow the height when the card is rendered, by calling this inside of the useEffect
hook.
const textAreaRef = useRef(null);
//...
<textarea
ref={textAreaRef}
Create and call function
useEffect(() => {
autoGrow(textAreaRef);
}, []);
function autoGrow(textAreaRef) {
const { current } = textAreaRef;
current.style.height = "auto"; // Reset the height
current.style.height = current.scrollHeight + "px"; // Set the new height
}
We want the text area to grow OR shrink anytime we make add or remove values as well.
onInput={() => {
autoGrow(textAreaRef);
}}