UNPKG

@nodeject/ui-components

Version:

UI library for non-trivial components

158 lines (157 loc) 6.19 kB
import { Tooltip } from 'antd'; import cc from 'classcat'; import * as React from 'react'; import { useEffect, useState, useRef } from 'react'; import { EditIcon, EnterIcon } from '../icons'; import styles from './styles.module.less'; export var EditableLabel = function (props) { var _a; var className = props.className, setCursorOnFocus = props.setCursorOnFocus; var _b = useState(props.initialValue), value = _b[0], setValue = _b[1]; var _c = useState(false), editing = _c[0], setEditing = _c[1]; var _d = useState(false), saving = _d[0], setSaving = _d[1]; var _e = useState(false), cancelChange = _e[0], setCancelChange = _e[1]; var focusOnMount = props.focusOnMount !== undefined ? props.focusOnMount : false; var stopCancelPropagation = props.stopCancelPropagation !== undefined ? props.stopCancelPropagation : true; var stopEnterPropagation = props.stopEnterPropagation !== undefined ? props.stopEnterPropagation : true; var domElm = useRef(); useEffect(function () { if (focusOnMount) { edit(); } }, []); useEffect(function () { setValue(props.initialValue); }, [props.initialValue]); useEffect(function () { domElm.current.focus(); if (isValueChanged() && !editing && !cancelChange) { var val = domElm.current.textContent.toString().trim(); setValue(val); props.onSave(val); setSaving(false); } else { domElm.current.textContent = props.initialValue; setCancelChange(false); return; } }, [editing]); var toggleEdit = function (e) { e.stopPropagation(); props.onBeforeEdit && props.onBeforeEdit(); if (!editing) { edit(); } }; var onFocus = function (e) { //console.log(domElm) //domElm.current. }; function placeCaretAtEnd(el) { el.focus(); if (typeof window.getSelection != 'undefined' && typeof document.createRange != 'undefined') { var range = document.createRange(); range.selectNodeContents(el); range.collapse(false); var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } else if (typeof document.body.createTextRange != 'undefined') { var textRange = document.body.createTextRange(); textRange.moveToElementText(el); textRange.collapse(false); textRange.select(); } } var selectElementContents = function (el) { var range = document.createRange(); range.selectNodeContents(el); var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); }; var edit = function () { setEditing(true); if (setCursorOnFocus !== undefined) { domElm.current.onfocus = function (e) { requestAnimationFrame(function () { if (setCursorOnFocus === 'selectAll') { selectElementContents(domElm.current); } else if (setCursorOnFocus === 'endOfSelection') { placeCaretAtEnd(domElm.current); } }); }; } }; var save = function () { setEditing(false); setSaving(true); }; var cancel = function () { setCancelChange(true); setEditing(false); }; var isValueChanged = function () { return (value.toString().trim() !== domElm.current.textContent.toString().trim()); // return props.initialValue !== domElm.current.textContent }; var handleKeyDown = function (e) { var key = e.key; switch (key) { case 'Enter': save(); if (stopEnterPropagation) { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); } break; case 'Escape': cancel(); if (stopCancelPropagation) { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); } break; } }; var editOnClick = true; if (props.editOnClick !== undefined) { editOnClick = props.editOnClick; } if (props.initialValue.trim() === '') { editOnClick = false; } var editableLabelClassName = editing ? styles.editableLabelWriteMode : styles.editableLabelReadMode; var editClassName = props.editClassName === undefined ? styles.edit : props.editClassName; var editDisabledClassName = props.labelClassName === undefined ? editOnClick ? styles.editDisabledInline : styles.editDisabled : props.labelClassName; var editIcon = editing ? (React.createElement(EnterIcon, { className: styles.editIcon, onClick: save })) : (React.createElement(Tooltip, { title: 'Click to edit' }, React.createElement(EditIcon, { className: styles.editIcon, onClick: toggleEdit }))); var onBlur = function () { window.setTimeout(function () { !saving && cancel(); }, 100); }; var classNameEditableLabel = cc((_a = {}, _a[editableLabelClassName] = true, _a[className] = Boolean(className), _a)); return (React.createElement("span", { className: classNameEditableLabel }, React.createElement(props.htmlTag, { className: editing ? editClassName : editDisabledClassName, style: editing ? props.editStyle : props.labelStyle, suppressContentEditableWarning: true, contentEditable: editing, ref: domElm, onBlur: editOnClick ? save : onBlur, onKeyDown: handleKeyDown, onFocus: onFocus, onClick: editOnClick ? toggleEdit : undefined }, value), !editOnClick && editIcon)); };