UNPKG

@hitachivantara/uikit-react-core

Version:
111 lines (110 loc) 3.79 kB
import { fixedForwardRef } from "../types/generic.js"; import { HvTypography } from "../Typography/Typography.js"; import { isKey } from "../utils/keyboardUtils.js"; import { HvIcon } from "../icons.js"; import { useControlled } from "../hooks/useControlled.js"; import { HvButton } from "../Button/Button.js"; import { HvTooltip } from "../Tooltip/Tooltip.js"; import { HvInput } from "../Input/Input.js"; import { useEnhancedEffect } from "../hooks/useEnhancedEffect.js"; import { useClasses } from "./InlineEditor.styles.js"; import { useDefaultProps, useTheme } from "@hitachivantara/uikit-react-utils"; import { useRef, useState } from "react"; import { jsx } from "react/jsx-runtime"; //#region src/InlineEditor/InlineEditor.tsx /** * An Inline Editor allows the user to edit a record without making a major switch * between viewing and editing, making it an efficient method of updating a record. */ var HvInlineEditor = fixedForwardRef(function HvInlineEditor(props, ref) { const { className, classes: classesProp, value: valueProp, defaultValue = "", showIcon, component: InputComponent = HvInput, variant = "body", placeholder = "Enter text", onBlur, onChange, onKeyDown, buttonProps, typographyProps, disabled, ...others } = useDefaultProps("HvInlineEditor", props); const { classes, cx } = useClasses(classesProp); const [value, setValue] = useControlled(valueProp, defaultValue); const [editMode, setEditMode] = useState(false); const [cachedValue, setCachedValue] = useState(value); const inputRef = useRef(void 0); const { activeTheme } = useTheme(); const [isOverflowing, setIsOverflowing] = useState(false); const typographyStyles = activeTheme?.typography[variant] || {}; const { lineHeight } = typographyStyles; const checkOverflow = (el) => { if (!el) return; setIsOverflowing(el.scrollWidth > el.clientWidth); }; useEnhancedEffect(() => { const input = inputRef.current; if (editMode && input) { input.focus(); input.select(); } }, [editMode]); const handleClick = () => { setEditMode(true); setCachedValue(value); }; const handleBlur = (event) => { setEditMode(false); const newValue = value || cachedValue; setValue(newValue); onBlur?.(event, newValue); }; const handleKeyDown = (event) => { let newValue = value; if (isKey(event, "Esc")) { newValue = cachedValue; setEditMode(false); setValue(newValue); } onKeyDown?.(event, newValue); }; const handleChange = (event, val) => { setValue(val); onChange?.(event, val); }; return /* @__PURE__ */ jsx("div", { className: cx(classes.root, className), children: editMode && !disabled ? /* @__PURE__ */ jsx(InputComponent, { ref, inputRef, classes: { inputRoot: classes.inputRoot, input: classes.input }, inputProps: { style: { ...typographyStyles, height: InputComponent === HvInput ? lineHeight : void 0 } }, value, onBlur: handleBlur, onChange: handleChange, onKeyDown: handleKeyDown, ...others }) : /* @__PURE__ */ jsx(HvButton, { variant: "secondaryGhost", endIcon: /* @__PURE__ */ jsx(HvIcon, { compact: true, name: "Edit", color: "textDisabled", className: cx(classes.icon, { [classes.iconVisible]: showIcon }) }), className: cx(classes.button, { [classes.largeText]: Number(lineHeight) >= 28 }), onClick: handleClick, disabled, ...buttonProps, children: /* @__PURE__ */ jsx(HvTooltip, { title: isOverflowing && value, children: /* @__PURE__ */ jsx(HvTypography, { component: "div", ref: checkOverflow, variant, noWrap: true, className: cx(classes.text, { [classes.textEmpty]: !value }), ...typographyProps, children: value || placeholder }) }) }) }); }); //#endregion export { HvInlineEditor };