better handling of textbox focus for mobile
This commit is contained in:
parent
798e879863
commit
cfa0b9bc07
3 changed files with 102 additions and 22 deletions
|
@ -1,20 +1,23 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect } from "react";
|
||||
|
||||
interface AddBulkIngredientsProps {
|
||||
ingredients: string[];
|
||||
onChange?: (ingredients: string[]) => void;
|
||||
}
|
||||
|
||||
const AddBulkIngredients: React.FC<AddBulkIngredientsProps> = ({ ingredients, onChange }) => {
|
||||
const [textValue, setTextValue] = useState<string>('');
|
||||
const AddBulkIngredients: React.FC<AddBulkIngredientsProps> = ({
|
||||
ingredients,
|
||||
onChange,
|
||||
}) => {
|
||||
const [textValue, setTextValue] = useState<string>("");
|
||||
|
||||
useEffect(() => {
|
||||
const textRepresentation = ingredients.join('\n');
|
||||
const textRepresentation = ingredients.join("\n");
|
||||
setTextValue(textRepresentation);
|
||||
}, [ingredients]);
|
||||
|
||||
const parseAndUpdate = (value: string) => {
|
||||
const lines = value.split('\n').filter(line => line.trim() !== '');
|
||||
const lines = value.split("\n").filter((line) => line.trim() !== "");
|
||||
|
||||
if (onChange) onChange(lines);
|
||||
};
|
||||
|
@ -24,26 +27,66 @@ const AddBulkIngredients: React.FC<AddBulkIngredientsProps> = ({ ingredients, on
|
|||
};
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||
if (e.key === 'Enter') {
|
||||
if (e.key === "Enter") {
|
||||
parseAndUpdate(textValue);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBlur = () => {
|
||||
parseAndUpdate(textValue);
|
||||
document.body.style.overflow = "";
|
||||
removeTouchListeners();
|
||||
};
|
||||
|
||||
const manageOverflow = () => {
|
||||
const lineCount = textValue
|
||||
.split("\n")
|
||||
.filter((line) => line.trim() !== "").length;
|
||||
if (lineCount > 8) {
|
||||
document.body.style.overflow = "hidden";
|
||||
addTouchListeners();
|
||||
} else {
|
||||
document.body.style.overflow = "";
|
||||
removeTouchListeners();
|
||||
}
|
||||
};
|
||||
|
||||
const handleFocus = () => {
|
||||
manageOverflow();
|
||||
};
|
||||
|
||||
const handleTouchEnd = () => {
|
||||
manageOverflow();
|
||||
};
|
||||
|
||||
const addTouchListeners = () => {
|
||||
window.addEventListener("touchmove", preventDefault, { passive: false });
|
||||
};
|
||||
|
||||
const removeTouchListeners = () => {
|
||||
window.removeEventListener("touchmove", preventDefault);
|
||||
};
|
||||
|
||||
const preventDefault = (e: TouchEvent) => {
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3 className="text-xl font-bold text-[var(--color-secondaryTextDark)]">Ingredients:</h3>
|
||||
<h3 className="text-xl font-bold text-[var(--color-secondaryTextDark)]">
|
||||
Ingredients:
|
||||
</h3>
|
||||
<textarea
|
||||
rows={8}
|
||||
value={textValue}
|
||||
onChange={handleInputChange}
|
||||
onKeyDown={handleKeyDown}
|
||||
onBlur={handleBlur}
|
||||
onFocus={handleFocus}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
placeholder="Enter ingredients separated by new line"
|
||||
className="mb-4 p-2 border border-[var(--color-primaryBorder)] rounded w-full"
|
||||
className="mb-4 p-2 border border-[var(--color-primaryBorder)] rounded w-full overflow-y-auto"
|
||||
style={{ overflowY: "auto" }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
|
||||
interface Step {
|
||||
step_number: number;
|
||||
|
@ -11,12 +11,13 @@ interface AddBulkStepsProps {
|
|||
}
|
||||
|
||||
const AddBulkSteps: React.FC<AddBulkStepsProps> = ({ steps, onChange }) => {
|
||||
const [textValue, setTextValue] = useState<string>('');
|
||||
const [textValue, setTextValue] = useState<string>("");
|
||||
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const textRepresentation = steps.map(step =>
|
||||
`${step.instruction}`
|
||||
).join('\n');
|
||||
const textRepresentation = steps
|
||||
.map((step) => `${step.instruction}`)
|
||||
.join("\n");
|
||||
setTextValue(textRepresentation);
|
||||
}, [steps]);
|
||||
|
||||
|
@ -24,38 +25,71 @@ const AddBulkSteps: React.FC<AddBulkStepsProps> = ({ steps, onChange }) => {
|
|||
setTextValue(e.target.value);
|
||||
};
|
||||
|
||||
|
||||
const parseAndUpdate = (value: string) => {
|
||||
const lines = value.split('\n').filter(line => line.trim() !== '');
|
||||
const lines = value.split("\n").filter((line) => line.trim() !== "");
|
||||
|
||||
const parsedSteps: Step[] = lines.map((line, idx) => {
|
||||
return { step_number: idx + 1, instruction: line }
|
||||
})
|
||||
return { step_number: idx + 1, instruction: line };
|
||||
});
|
||||
|
||||
if (onChange) onChange(parsedSteps);
|
||||
};
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||
if (e.key === 'Enter') {
|
||||
if (e.key === "Enter") {
|
||||
parseAndUpdate(textValue);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBlur = () => {
|
||||
parseAndUpdate(textValue);
|
||||
document.body.style.overflow = "";
|
||||
};
|
||||
|
||||
const manageOverflow = () => {
|
||||
const lineCount = textValue
|
||||
.split("\n")
|
||||
.filter((line) => line.trim() !== "").length;
|
||||
if (lineCount > 8) {
|
||||
document.body.style.overflow = "hidden";
|
||||
if (textareaRef.current) {
|
||||
textareaRef.current.className += " overflow-y-auto"; // Set className for scrolling
|
||||
}
|
||||
} else {
|
||||
document.body.style.overflow = "";
|
||||
if (textareaRef.current) {
|
||||
textareaRef.current.className = textareaRef.current.className.replace(
|
||||
"overflow-y-auto",
|
||||
"",
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleFocus = () => {
|
||||
manageOverflow();
|
||||
};
|
||||
|
||||
const handleTouchEnd = () => {
|
||||
manageOverflow();
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3 className="text-xl font-bold text-[var(--color-secondaryTextDark)]">Steps:</h3>
|
||||
<h3 className="text-xl font-bold text-[var(--color-secondaryTextDark)]">
|
||||
Steps:
|
||||
</h3>
|
||||
<textarea
|
||||
rows={8}
|
||||
value={textValue}
|
||||
onChange={handleInputChange}
|
||||
onKeyDown={handleKeyDown}
|
||||
onBlur={handleBlur}
|
||||
onFocus={handleFocus}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
placeholder="Enter steps separated by new line"
|
||||
className="mb-4 p-2 border border-[var(--color-primaryBorder)] rounded w-full"
|
||||
className="mb-4 p-2 border border-[var(--color-primaryBorder)] rounded w-full overflow-y-auto"
|
||||
style={{ overflowY: "auto" }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue