@hitachivantara/uikit-react-core
Version:
UI Kit Core React components.
111 lines (110 loc) • 3.79 kB
JavaScript
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 };