Skip to content

Instantly share code, notes, and snippets.

@nestarz
Created May 27, 2020 13:15
Show Gist options
  • Save nestarz/475863dee335d6d8d3b7458fb68399b0 to your computer and use it in GitHub Desktop.
Save nestarz/475863dee335d6d8d3b7458fb68399b0 to your computer and use it in GitHub Desktop.
Contenteditable Input with a placeholder and a validation function
export const setCaretNode = (node, index) => {
if (node.lastChild)
window
.getSelection()
.collapse(
node.lastChild,
index > 0 ? index : node.lastChild.textContent.length + index + 1
);
};
export default ({ current = "", init, set, onValid }) => {
const ref = useRef();
const [focus, setFocus] = useState(false);
useEffect(() => {
ref.current.textContent = init;
}, []);
useEffect(() => {
if (focus) setCaretNode(ref.current, -1);
if (focus && ref.current.textContent === init) ref.current.textContent = "";
else if (!focus && ref.current.textContent === "")
ref.current.textContent = init;
}, [focus]);
useEffect(() => {
if (!focus && current && current != init) ref.current.textContent = current;
}, [current, focus]);
return (
<span
ref={ref}
contentEditable={true}
onKeyDown={(e) => e.keyCode === 13 && e.preventDefault()}
onKeyUp={() => {
if (!["", init].includes(ref.current.textContent)) {
onValid(true);
set(ref.current.textContent);
} else set(null);
}}
onBlur={() => setFocus(false)}
onFocus={() => setFocus(true)}
></span>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment