UNPKG

tldraw

Version:

A tiny little drawing editor.

165 lines (164 loc) 5.23 kB
import { jsx, jsxs } from "react/jsx-runtime"; import { 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, iconLabel, autoSelect = false, autoFocus = false, defaultValue, placeholder, onComplete, onValueChange, onCancel, onFocus, onBlur, shouldManuallyMaintainScrollPositionWhenFocused = false, children, value, "data-testid": dataTestId, disabled, "aria-label": ariaLabel }, 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 isComposing = React.useRef(false); 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": { if (isComposing.current) return; e.currentTarget.blur(); e.stopPropagation(); onComplete?.(e.currentTarget.value); break; } case "Escape": { e.currentTarget.value = rInitialValue.current; onCancel?.(e.currentTarget.value); e.currentTarget.blur(); e.stopPropagation(); break; } } }, [onComplete, onCancel] ); const handleBlur = React.useCallback( (e) => { setIsFocused(false); const value2 = e.currentTarget.value; onBlur?.(value2); }, [onBlur] ); const handleCompositionStart = React.useCallback(() => isComposing.current = true, []); const handleCompositionEnd = React.useCallback(() => isComposing.current = false, []); React.useEffect(() => { if (!tlenv.isIos) return void 0; 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); }; } return void 0; }, [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, { label: iconLabel ? msg(iconLabel) : "", 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, onCompositionStart: handleCompositionStart, onCompositionEnd: handleCompositionEnd, autoFocus, "aria-label": ariaLabel, placeholder, value, "data-testid": dataTestId, disabled } ), icon && /* @__PURE__ */ jsx(TldrawUiIcon, { label: iconLabel ? msg(iconLabel) : "", icon, small: !!label }) ] }); } ); export { TldrawUiInput }; //# sourceMappingURL=TldrawUiInput.mjs.map