@hitachivantara/uikit-react-pentaho
Version:
UI Kit Pentaho React components.
155 lines (154 loc) • 4.62 kB
JavaScript
import { jsxs, jsx } from "react/jsx-runtime";
import { useRef, useState } from "react";
import { createClasses, theme, useControlled, useEnhancedEffect, HvTypography, isKey } from "@hitachivantara/uikit-react-core";
import { Edit } from "@hitachivantara/uikit-react-icons";
const { staticClasses, useClasses } = createClasses(
"HvCanvasToolbarTabs-editor",
{
root: {
position: "relative",
display: "flex",
width: "100%",
overflow: "hidden",
"&:has($label:hover:not($edit))": {
color: theme.colors.textSubtle,
"& $editIcon": { visibility: "visible" }
}
},
edit: {
color: theme.colors.textSubtle,
borderColor: "currentColor",
backgroundColor: theme.colors.bgContainer,
cursor: "text"
},
label: {
width: "100%",
boxSizing: "border-box",
border: "1px solid transparent",
borderRadius: theme.radii.base,
padding: theme.spacing(0, "sm", 0, "xs"),
textAlign: "start",
whiteSpace: "nowrap",
overflow: "hidden",
outline: "none",
"&:not($edit)": {
textOverflow: "ellipsis"
},
"&:hover:not($edit)": {
color: theme.colors.textSubtle,
borderColor: theme.colors.bgHover,
backgroundColor: theme.colors.bgHover
}
},
editIcon: {
position: "absolute",
right: theme.space.xxs,
top: 4,
width: 16,
height: 16,
visibility: "hidden",
pointerEvents: "none"
}
}
);
const sanitize = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
const ToolbarTabEditor = ({
id,
className,
edit: editProp,
value: valueProp,
defaultValue: defaultValueProp = "",
classes: classesProp,
onInput: onInputProp,
onClick: onClickProp,
onBlur: onBlurProp,
onKeyDown: onKeyDownProp,
onChange: onChangeProp,
onEditChange: onEditChangeProp,
...others
}) => {
const { cx, classes } = useClasses(classesProp);
const contentEditableRef = useRef(null);
const [value, setValue] = useControlled(
valueProp ? sanitize(valueProp) : valueProp,
defaultValueProp ? sanitize(defaultValueProp) : defaultValueProp
);
const [cachedValue, setCachedValue] = useState(value);
const [isEditing, setIsEditing] = useControlled(editProp, false);
const moveCursorToEnd = () => {
if (!contentEditableRef.current) return;
const element = contentEditableRef.current;
const range = document.createRange();
const selection = window.getSelection();
range.selectNodeContents(element);
range.collapse(false);
selection?.removeAllRanges();
selection?.addRange(range);
element.scrollLeft = element.scrollWidth;
};
const scrollContentToStart = () => {
if (!contentEditableRef.current) return;
const element = contentEditableRef.current;
element.scrollLeft = 0;
};
const changeEdit = (edit) => {
setIsEditing(edit);
onEditChangeProp?.(edit);
};
useEnhancedEffect(() => {
if (isEditing) moveCursorToEnd();
}, [isEditing, value]);
const handleInput = (event) => {
const newValue = sanitize(event.target.textContent) || "";
setValue(newValue);
onInputProp?.(event);
onChangeProp?.(event, newValue);
};
const handleClick = (event) => {
setCachedValue(value);
changeEdit(true);
onClickProp?.(event);
};
const handleBlur = (event) => {
changeEdit(false);
scrollContentToStart();
const newValue = value.trim() || cachedValue;
setValue(newValue);
onBlurProp?.(event, newValue);
};
const handleKeyDown = (event) => {
if (isKey(event, "Enter")) {
handleBlur(event);
} else if (isKey(event, "Esc")) {
changeEdit(false);
setValue(cachedValue);
onChangeProp?.(event, cachedValue);
}
onKeyDownProp?.(event);
};
return /* @__PURE__ */ jsxs("div", { id, className: cx(classes.root, className), children: [
/* @__PURE__ */ jsx(
HvTypography,
{
ref: contentEditableRef,
contentEditable: isEditing,
className: cx(classes.label, { [classes.edit]: isEditing }),
variant: "label",
component: "span",
onInput: handleInput,
onClick: handleClick,
onBlur: handleBlur,
onKeyDown: handleKeyDown,
dangerouslySetInnerHTML: {
__html: value
},
...others
}
),
/* @__PURE__ */ jsx(Edit, { className: classes.editIcon, iconSize: "XS" })
] });
};
export {
ToolbarTabEditor,
staticClasses as toolbarTabEditorClasses
};