tldraw
Version:
A tiny little drawing editor.
143 lines (142 loc) • 4.53 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { stopEventPropagation, tlenv, tltime, useMaybeEditor } from "@tldraw/editor";
import classNames from "classnames";
import * as React from "react";
import { useTranslation } from "../../hooks/useTranslation/useTranslation.mjs";
import { TldrawUiIcon } from "./TldrawUiIcon.mjs";
const TldrawUiInput = React.forwardRef(
function TldrawUiInput2({
className,
label,
icon,
iconLeft,
autoSelect = false,
autoFocus = false,
defaultValue,
placeholder,
onComplete,
onValueChange,
onCancel,
onFocus,
onBlur,
shouldManuallyMaintainScrollPositionWhenFocused = false,
children,
value
}, ref) {
const editor = useMaybeEditor();
const rInputRef = React.useRef(null);
React.useImperativeHandle(ref, () => rInputRef.current);
const msg = useTranslation();
const rInitialValue = React.useRef(defaultValue ?? "");
const rCurrentValue = React.useRef(defaultValue ?? "");
const [isFocused, setIsFocused] = React.useState(false);
const handleFocus = React.useCallback(
(e) => {
setIsFocused(true);
const elm = e.currentTarget;
rCurrentValue.current = elm.value;
if (editor) {
editor.timers.requestAnimationFrame(() => {
if (autoSelect) {
elm.select();
}
});
} else {
tltime.requestAnimationFrame("anon", () => {
if (autoSelect) {
elm.select();
}
});
}
onFocus?.();
},
[autoSelect, editor, onFocus]
);
const handleChange = React.useCallback(
(e) => {
const value2 = e.currentTarget.value;
rCurrentValue.current = value2;
onValueChange?.(value2);
},
[onValueChange]
);
const handleKeyDownCapture = React.useCallback(
(e) => {
switch (e.key) {
case "Enter": {
e.currentTarget.blur();
stopEventPropagation(e);
onComplete?.(e.currentTarget.value);
break;
}
case "Escape": {
e.currentTarget.value = rInitialValue.current;
onCancel?.(e.currentTarget.value);
e.currentTarget.blur();
stopEventPropagation(e);
break;
}
}
},
[onComplete, onCancel]
);
const handleBlur = React.useCallback(
(e) => {
setIsFocused(false);
const value2 = e.currentTarget.value;
onBlur?.(value2);
},
[onBlur]
);
React.useEffect(() => {
if (!tlenv.isIos) return;
const visualViewport = window.visualViewport;
if (isFocused && shouldManuallyMaintainScrollPositionWhenFocused && visualViewport) {
const onViewportChange = () => {
rInputRef.current?.scrollIntoView({ block: "center" });
};
visualViewport.addEventListener("resize", onViewportChange);
visualViewport.addEventListener("scroll", onViewportChange);
if (editor) {
editor.timers.requestAnimationFrame(() => {
rInputRef.current?.scrollIntoView({ block: "center" });
});
} else {
tltime.requestAnimationFrame("anon", () => {
rInputRef.current?.scrollIntoView({ block: "center" });
});
}
return () => {
visualViewport.removeEventListener("resize", onViewportChange);
visualViewport.removeEventListener("scroll", onViewportChange);
};
}
}, [isFocused, editor, shouldManuallyMaintainScrollPositionWhenFocused]);
return /* @__PURE__ */ jsxs("div", { draggable: false, className: "tlui-input__wrapper", children: [
children,
label && /* @__PURE__ */ jsx("label", { children: msg(label) }),
iconLeft && /* @__PURE__ */ jsx(TldrawUiIcon, { icon: iconLeft, className: "tlui-icon-left", small: true }),
/* @__PURE__ */ jsx(
"input",
{
ref: rInputRef,
className: classNames("tlui-input", className),
type: "text",
defaultValue,
onKeyDownCapture: handleKeyDownCapture,
onChange: handleChange,
onFocus: handleFocus,
onBlur: handleBlur,
autoFocus,
placeholder,
value
}
),
icon && /* @__PURE__ */ jsx(TldrawUiIcon, { icon, small: !!label })
] });
}
);
export {
TldrawUiInput
};
//# sourceMappingURL=TldrawUiInput.mjs.map