@prefect9/ui
Version:
UI React components
145 lines (142 loc) • 5.35 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
require("core-js/modules/es.string.trim.js");
require("core-js/modules/web.dom-collections.iterator.js");
var _react = require("react");
var _isType = require("@prefect9/is-type");
var _jsxRuntime = require("react/jsx-runtime");
const TextSizedField = /*#__PURE__*/(0, _react.forwardRef)((_ref, initialApiRef) => {
let {
value: initialValue,
placeholder,
onChange
} = _ref;
const _apiRef = (0, _react.useRef)(null);
const apiRef = initialApiRef !== null && initialApiRef !== void 0 ? initialApiRef : _apiRef;
const blockRef = (0, _react.useRef)(null);
const inputRef = (0, _react.useRef)(null);
const [loading, setLoading] = (0, _react.useState)(false);
const [value, setValue] = (0, _react.useState)(initialValue);
(0, _react.useEffect)(() => setValue(initialValue), [initialValue]);
const [editing, setEditing] = (0, _react.useState)(false);
const [editedValue, setEditedValue] = (0, _react.useState)('');
const actualValue = (0, _react.useMemo)(() => {
if (!editing && !loading) return value;
return editedValue;
}, [editing, value, editedValue, loading]);
const showPlaceholder = (0, _react.useMemo)(() => actualValue.trim().length < 1, [actualValue]);
const editHandler = (0, _react.useCallback)(e => {
if (!inputRef || !inputRef.current) return;
if (loading) return;
setEditedValue(inputRef.current.value);
}, [inputRef, loading]);
// resizer
const [width, setWidth] = (0, _react.useState)(0);
const [height, setHeight] = (0, _react.useState)(0);
(0, _react.useEffect)(() => {
if (!blockRef || !blockRef.current) return;
if (!inputRef || !inputRef.current) return;
const textBlock = blockRef.current.querySelector('.prefect9-text-sized-field__text');
if (!textBlock) return;
const resize = () => {
const size = textBlock.getBoundingClientRect();
setWidth(size.width);
setHeight(size.height);
};
resize();
window.addEventListener('resize', resize, {
passive: true
});
inputRef.current.addEventListener('input', resize, {
passive: true
});
const resizeObserver = new ResizeObserver(() => resize());
resizeObserver.observe(textBlock);
return () => {
window.removeEventListener('resize', resize, {
passive: true
});
resizeObserver.disconnect();
if (inputRef.current) inputRef.current.addEventListener('input', resize, {
passive: true
});
};
}, [blockRef]);
// editing handlers
(0, _react.useEffect)(() => {
if (!inputRef || !inputRef.current) return;
if (!(0, _isType.isObj)(apiRef)) return;
apiRef.current = {};
const focusHandler = e => {
setEditedValue(value);
setEditing(true);
};
inputRef.current.addEventListener('focus', focusHandler);
const blurHandler = e => setEditing(false);
const blur = () => {
inputRef.current.blur();
blurHandler();
};
apiRef.current.blur = blur;
inputRef.current.addEventListener('blur', blurHandler);
const keyDownHandler = e => {
const keyCode = e.code;
if (keyCode !== 'Enter') return;
e.preventDefault();
setLoading(true);
const savedEditedValue = () => {
setLoading(false);
blur();
};
const newValue = inputRef.current.value;
if (newValue === value) return savedEditedValue();
const handlerResult = (0, _isType.isFunc)(onChange) ? onChange(newValue) : null;
if (!(0, _isType.isProm)(handlerResult)) savedEditedValue();else {
handlerResult.then(savedEditedValue).catch(e => {
throw e;
});
}
};
inputRef.current.addEventListener('keydown', keyDownHandler);
return () => {
if (inputRef.current) inputRef.current.removeEventListener('focus', focusHandler);
if (inputRef.current) inputRef.current.removeEventListener('blur', blurHandler);
if (inputRef.current) inputRef.current.removeEventListener('keydown', keyDownHandler);
};
}, [inputRef, apiRef, value]);
const className = (0, _react.useMemo)(() => {
const result = ['prefect9-text-sized-field'];
if (loading) result.push('prefect9-text-sized-field__loading');
return result.join(' ');
}, [loading]);
const classNameField = (0, _react.useMemo)(() => {
const result = ['prefect9-text-sized-field__input'];
if (showPlaceholder) result.push('prefect9-text-sized-field__input-placeholder');
return result.join(' ');
}, [showPlaceholder]);
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
ref: blockRef,
className: className,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
className: "prefect9-text-sized-field__text",
children: showPlaceholder ? placeholder : actualValue
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("input", {
ref: inputRef,
className: classNameField,
value: actualValue,
placeholder: placeholder,
onInput: editHandler,
disabled: loading,
style: {
width: "".concat(width, "px"),
height: "".concat(height, "px")
}
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
className: "prefect9-text-sized-field__loader"
})]
});
});
var _default = exports.default = TextSizedField;