aboutsummaryrefslogtreecommitdiffstats
path: root/public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements
diff options
context:
space:
mode:
Diffstat (limited to 'public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements')
-rw-r--r--public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/Input/Input.js31
-rw-r--r--public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/TextArea/TextArea.js52
-rw-r--r--public/projects/react-small-apps/apps/notebook/src/components/commons/FormElements/index.js4
3 files changed, 87 insertions, 0 deletions
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 };