Skip to content

Instantly share code, notes, and snippets.

@vickonrails
Last active September 17, 2019 20:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vickonrails/f6e6f9edb22b7688602171ed8c9f85b0 to your computer and use it in GitHub Desktop.
Save vickonrails/f6e6f9edb22b7688602171ed8c9f85b0 to your computer and use it in GitHub Desktop.
A little note taking app in ReactJs, styled components and TypeScript
import React, { useState } from "react";
import styled from "styled-components";
import "./App.css";
// Styled components definitions for all components
const Header = styled.header`
// padding: 0.5em 1em;
`;
const Nav = styled.nav`
background: red;
padding: 1em 0.7em;
`;
const MainContent = styled.main`
margin-top: 2em;
`;
const Container = styled.div`
max-width: 500px;
margin: 0 auto;
`;
const InputForm = styled.form`
padding: 0 0.6em;
margin-top: 2em;
`;
const Title = styled.p`
font-weight: 700;
`;
const Content = styled.p`
color: #666;
`;
const List = styled.ul`
list-style-type: none;
`;
const InputField = styled.input`
display: block;
font-size: 1em;
padding: 0.4em 0.8em;
width: 100%;
border: 1px solid #ccc;
margin-bottom: 0.6em;
`;
const TextareaField = styled.textarea`
font-size: 1em;
width: 100%;
height: 200px;
padding: 0.4em 0.8em;
resize: vertical;
border: 1px solid #ccc;
margin-bottom: 0.4em;
&:hover,
:active,
:focus {
border: 1px solid #000;
}
`;
const NotesList = styled.section`
padding: 0 0.6em;
margin-bottom: 2em;
`;
const Button = styled.button`
background: red;
border: none;
padding: 1em;
color: #eee;
transition: color 0.25s;
cursor: pointer;
&:hover {
color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.16);
}
`;
const Link = styled.a`
text-decoration: none;
color: #fff;
&:hover {
text-decoration: underline;
}
`;
const ListItem = styled.li`
background: #fff;
padding: 0.8em;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.05);
margin-bottom: 0.6em;
border-radius: 6px;
`;
const HorizontalLine = styled.hr`
border: none;
border-bottom: 1px solid #eee;
`;
// React Components Code
const App: React.FC = () => {
// Managing state with React Hooks
const [titleValue, setTitleValue]: [
string,
(newValue: string) => void
] = useState("");
const [contentValue, setContentValue]: [
string,
(newValue: string) => void
] = useState("");
const [notes, setNotes]: [Array<any>, Function] = useState([]);
// Event handlers for Input and Content fields
const handleTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setTitleValue(e.target.value);
};
const handleContentChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setContentValue(e.target.value);
};
const addNote = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
let newNote = { title: titleValue, content: contentValue };
setNotes((prevNotes: object[]) => [...prevNotes, newNote]);
// Empty both Input Fields
setContentValue("");
setTitleValue("");
};
return (
<>
<Header>
<Nav>
<Container>
<Link href="/">Notes App</Link>
</Container>
</Nav>
<MainContent>
<Container>
<NotesList>
{notes.map((note, index) => {
return (
<>
<List key={index}>
<ListItem>
<Title>{note.title}</Title>
<Content>{note.content}</Content>
</ListItem>
</List>
</>
);
})}
</NotesList>
{notes.length > 0 ? <HorizontalLine /> : null}
<InputForm onSubmit={addNote}>
<InputField
data-heading
type="text"
onChange={handleTitleChange}
placeholder="Title"
value={titleValue}
/>
<TextareaField
placeholder="Write Your Notes Here"
onChange={handleContentChange}
value={contentValue}
></TextareaField>
<Button type="submit">Add Note</Button>
</InputForm>
</Container>
</MainContent>
</Header>
</>
);
};
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment