@hitachivantara/uikit-react-core
Version:
Core React components for the NEXT Design System.
137 lines (136 loc) • 4.06 kB
JavaScript
import { jsx } from "react/jsx-runtime";
import { useState, useRef } from "react";
import { useDefaultProps, useTheme } from "@hitachivantara/uikit-react-utils";
import { useControlled } from "../hooks/useControlled.js";
import { useEnhancedEffect } from "../hooks/useEnhancedEffect.js";
import { HvIcon } from "../icons.js";
import { fixedForwardRef } from "../types/generic.js";
import { isKey } from "../utils/keyboardUtils.js";
import { useClasses } from "./InlineEditor.styles.js";
import { staticClasses } from "./InlineEditor.styles.js";
import { HvButton } from "../Button/Button.js";
import { HvInput } from "../Input/Input.js";
import { HvTooltip } from "../Tooltip/Tooltip.js";
import { HvTypography } from "../Typography/Typography.js";
const HvInlineEditor = fixedForwardRef(function HvInlineEditor2(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]: parseInt(lineHeight, 10) >= 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
}
) })
}
) });
});
export {
HvInlineEditor,
staticClasses as inlineEditorClasses
};