UNPKG

@hitachivantara/uikit-react-pentaho

Version:
155 lines (154 loc) 4.62 kB
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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;"); 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 };