diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-02-20 16:11:50 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-02-20 16:15:08 +0100 |
| commit | 73a5c7fae9ffbe9ada721148c8c454a643aceebe (patch) | |
| tree | c8fad013ed9b5dd589add87f8d45cf02bbfc6e91 /public/projects/react-small-apps/apps/notebook/src/components/commons | |
| parent | b01239fbdcc5bbc5921f73ec0e8fee7bedd5c8e8 (diff) | |
chore!: restructure repo
I separated public files from the config/dev files. It improves repo
readability.
I also moved dotenv helper to public/inc directory and extract the
Matomo tracker in the same directory.
Diffstat (limited to 'public/projects/react-small-apps/apps/notebook/src/components/commons')
8 files changed, 224 insertions, 0 deletions
diff --git a/public/projects/react-small-apps/apps/notebook/src/components/commons/Button/Button.css b/public/projects/react-small-apps/apps/notebook/src/components/commons/Button/Button.css new file mode 100644 index 0000000..16268d3 --- /dev/null +++ b/public/projects/react-small-apps/apps/notebook/src/components/commons/Button/Button.css @@ -0,0 +1,78 @@ +.btn { + cursor: pointer; +} + +.btn--delete { + background: hsl(0, 44%, 44%); + border: none; + border-radius: 50%; + box-shadow: 0 0 0 2px hsl(0, 44%, 29%), 1px 2px 1px 2px hsl(0, 44%, 29%); + width: 2.4rem; + height: 2.4rem; + padding: 0.5rem; + transition: transform 0.3s ease-in-out 0s; +} + +.btn--delete:hover, +.btn--delete:focus { + background: hsl(0, 44%, 50%); + transform: scale(1.1); +} + +.btn--delete:active { + background: hsl(0, 44%, 40%); + transform: scale(1); +} + +.btn .icon { + height: 100%; + width: 100%; +} + +.btn--delete #trash-lid-handle { + stroke: #fff; + stroke-width: 4; +} + +.btn--delete #trash-container, +.btn--delete #trash-lid { + fill: hsl(0, 44%, 49%); + stroke: #fff; + stroke-width: 5; +} + +.btn--delete #trash-stroke1, +.btn--delete #trash-stroke2, +.btn--delete #trash-stroke3 { + fill: #fff; + stroke: #fff; + stroke-width: 1; +} + +.btn--restore { + background: hsl(212, 44%, 44%); + border: none; + border-radius: 50%; + box-shadow: 0 0 0 2px hsl(212, 44%, 29%), 1px 2px 1px 2px hsl(212, 44%, 29%); + width: 2.4rem; + height: 2.4rem; + padding: 0.5rem; + transition: transform 0.3s ease-in-out 0s; +} + +.btn--restore:hover { + background: hsl(212, 44%, 50%); + transform: scale(1.1); +} + +.btn--restore:active { + background: hsl(212, 44%, 40%); + transform: scale(1); +} + +.btn--restore #restore-circle, +.btn--restore #restore-arrow, +.btn--restore #restore-first-clock-hand, +.btn--restore #restore-second-clock-hand { + fill: #fff; +} diff --git a/public/projects/react-small-apps/apps/notebook/src/components/commons/Button/Button.js b/public/projects/react-small-apps/apps/notebook/src/components/commons/Button/Button.js new file mode 100644 index 0000000..4580815 --- /dev/null +++ b/public/projects/react-small-apps/apps/notebook/src/components/commons/Button/Button.js @@ -0,0 +1,26 @@ +import "./Button.css"; + +function Button({ + children, + onClickHandler, + onBlurHandler, + modifier, + additionalClassnames, +}) { + let classNames = modifier ? `btn btn--${modifier}` : "btn"; + classNames = additionalClassnames + ? `${classNames} ${additionalClassnames}` + : classNames; + + return ( + <button + className={classNames} + onClick={onClickHandler} + onBlur={onBlurHandler} + > + {children} + </button> + ); +} + +export default Button; diff --git a/public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/Input/Input.js b/public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/Input/Input.js new file mode 100644 index 0000000..7d8cb45 --- /dev/null +++ b/public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/Input/Input.js @@ -0,0 +1,31 @@ +import { forwardRef } from "react"; + +function Input( + { + type = "text", + name, + value, + onChangeHandler, + onBlurHandler, + additionalClasses, + }, + ref +) { + const classNames = additionalClasses + ? `form__input ${additionalClasses}` + : "form__input"; + + return ( + <input + ref={ref} + type={type} + name={name} + className={classNames} + value={value} + onChange={onChangeHandler} + onBlur={onBlurHandler} + /> + ); +} + +export default forwardRef(Input); diff --git a/public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/TextArea/TextArea.js b/public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/TextArea/TextArea.js new file mode 100644 index 0000000..ca2a52e --- /dev/null +++ b/public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/TextArea/TextArea.js @@ -0,0 +1,52 @@ +import { forwardRef, useEffect, useState } from "react"; + +function autoGrow(field, initialValue = null) { + let fieldHeight = initialValue ?? field.style.height; + if (field.scrollHeight > field.clientHeight) { + fieldHeight = field.scrollHeight + "px"; + } + return fieldHeight; +} + +function isSetHeightNeeded(e) { + const key = e.key; + const isBackspace = key === "Backspace"; + const isDelete = key === "Delete"; + const isCtrlZ = e.ctrlKey && e.key === "z"; + const isCut = e.ctrlKey && e.key === "x"; + return isBackspace || isDelete || isCtrlZ || isCut; +} + +function TextArea( + { value, name, onBlurHandler, onChangeHandler, additionalClasses }, + ref +) { + const [fieldHeight, setFieldHeight] = useState(); + const classNames = additionalClasses + ? `form__textarea ${additionalClasses}` + : "form__textarea"; + + useEffect(() => { + ref && setFieldHeight(autoGrow(ref.current)); + }, [ref]); + + return ( + <textarea + ref={ref} + className={classNames} + name={name} + value={value} + onChange={(e) => { + onChangeHandler(e); + setFieldHeight(autoGrow(e.target)); + }} + onKeyDown={(e) => { + if (isSetHeightNeeded(e)) setFieldHeight(autoGrow(e.target, "auto")); + }} + onBlur={onBlurHandler} + style={{ height: fieldHeight }} + /> + ); +} + +export default forwardRef(TextArea); diff --git a/public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/index.js b/public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/index.js new file mode 100644 index 0000000..1d1f610 --- /dev/null +++ b/public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/index.js @@ -0,0 +1,4 @@ +import Input from "./Input/Input"; +import TextArea from "./TextArea/TextArea"; + +export { Input, TextArea }; diff --git a/public/projects/react-small-apps/apps/notebook/src/components/commons/List/List.css b/public/projects/react-small-apps/apps/notebook/src/components/commons/List/List.css new file mode 100644 index 0000000..ae897a5 --- /dev/null +++ b/public/projects/react-small-apps/apps/notebook/src/components/commons/List/List.css @@ -0,0 +1,3 @@ +.list__item + .list__item { + margin-top: 0.5rem; +} diff --git a/public/projects/react-small-apps/apps/notebook/src/components/commons/List/List.js b/public/projects/react-small-apps/apps/notebook/src/components/commons/List/List.js new file mode 100644 index 0000000..631e6a5 --- /dev/null +++ b/public/projects/react-small-apps/apps/notebook/src/components/commons/List/List.js @@ -0,0 +1,25 @@ +import "./List.css"; + +function List({ type = "ul", data = [], modifier = "" }) { + const classNames = modifier ? `list list--${modifier}` : "list"; + + const listItems = data.map((object) => { + return ( + <li key={object.id} className="list__item"> + {object.body} + </li> + ); + }); + + return ( + <> + {type === "ol" ? ( + <ol className={classNames}>{listItems}</ol> + ) : ( + <ul className={classNames}>{listItems}</ul> + )} + </> + ); +} + +export default List; diff --git a/public/projects/react-small-apps/apps/notebook/src/components/commons/index.js b/public/projects/react-small-apps/apps/notebook/src/components/commons/index.js new file mode 100644 index 0000000..f0ca17b --- /dev/null +++ b/public/projects/react-small-apps/apps/notebook/src/components/commons/index.js @@ -0,0 +1,5 @@ +import Button from "./Button/Button"; +import { Input, TextArea } from "./FormElements"; +import List from "./List/List"; + +export { Button, Input, List, TextArea }; |
