@braineet/ui
Version:
Braineet design system
231 lines • 7.84 kB
JavaScript
var _excluded = ["value", "defaultValue", "isDisabled", "onChange", "startWithEditView", "onCancel", "onSubmit", "selectAllOnFocus", "submitOnBlur", "isPreviewFocusable", "placeholder", "children", "onEdit"],
_excluded2 = ["onBlur", "children"];
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
/* eslint-disable no-underscore-dangle */
/* eslint-disable no-unused-expressions */
import React, { createContext, useContext, useEffect, useRef, useState, forwardRef } from 'react';
import Box from '../box';
import { jsx as _jsx } from "react/jsx-runtime";
var EditableContext = /*#__PURE__*/createContext();
var Editable = /*#__PURE__*/forwardRef(function (_ref, ref) {
var valueProp = _ref.value,
defaultValue = _ref.defaultValue,
isDisabled = _ref.isDisabled,
onChange = _ref.onChange,
startWithEditView = _ref.startWithEditView,
onCancel = _ref.onCancel,
onSubmit = _ref.onSubmit,
selectAllOnFocus = _ref.selectAllOnFocus,
submitOnBlur = _ref.submitOnBlur,
isPreviewFocusable = _ref.isPreviewFocusable,
_ref$placeholder = _ref.placeholder,
placeholder = _ref$placeholder === void 0 ? 'Click to edit...' : _ref$placeholder,
children = _ref.children,
onEdit = _ref.onEdit,
rest = _objectWithoutPropertiesLoose(_ref, _excluded);
var _useState = useState(startWithEditView && !isDisabled),
isEditing = _useState[0],
setIsEditing = _useState[1];
var _useRef = useRef(!!valueProp),
isControlled = _useRef.current;
var _useState2 = useState(defaultValue || ''),
value = _useState2[0],
setValue = _useState2[1];
var _value = isControlled ? valueProp : value;
var _useState3 = useState(_value),
previousValue = _useState3[0],
setPreviousValue = _useState3[1];
var inputRef = useRef(null);
var onRequestEdit = React.useCallback(function () {
if (!isDisabled) {
setIsEditing(true);
}
}, [isDisabled]);
useEffect(function () {
if (isEditing) {
onEdit && onEdit();
}
}, [isEditing, onEdit]);
useEffect(function () {
if (isEditing && inputRef.current) {
inputRef.current.focus();
selectAllOnFocus && inputRef.current.select();
}
}, [isEditing, selectAllOnFocus]);
var handleCancel = React.useCallback(function () {
setIsEditing(false);
setValue(previousValue);
if (value !== previousValue) {
onChange && onChange(previousValue);
}
onCancel && onCancel(previousValue);
}, [value, previousValue, onChange, onCancel]);
var handleSubmit = React.useCallback(function () {
setIsEditing(false);
setPreviousValue(value);
onSubmit && onSubmit(value);
}, [value, onSubmit]);
var handleChange = React.useCallback(function (event) {
if (!isControlled) {
setValue(event.target.value);
}
onChange && onChange(event.target.value);
}, [isControlled, onChange]);
var handleKeyDown = React.useCallback(function (event) {
var key = event.key;
if (key === 'Escape') {
handleCancel();
return;
}
if (key === 'Enter') {
handleSubmit();
}
}, [handleCancel, handleSubmit]);
var handleFocus = React.useCallback(function () {
if (selectAllOnFocus) {
inputRef.current.select();
}
}, [selectAllOnFocus]);
var childContext = React.useMemo(function () {
return {
inputRef: inputRef,
isEditing: isEditing,
isDisabled: isDisabled,
placeholder: placeholder,
onRequestEdit: onRequestEdit,
submitOnBlur: submitOnBlur,
isPreviewFocusable: isPreviewFocusable,
value: _value,
onKeyDown: handleKeyDown,
onChange: handleChange,
onSubmit: handleSubmit,
onCancel: handleCancel,
onFocus: handleFocus
};
}, [inputRef, isEditing, isDisabled, placeholder, onRequestEdit, submitOnBlur, isPreviewFocusable, _value, handleKeyDown, handleChange, handleSubmit, handleCancel, handleFocus]);
return /*#__PURE__*/_jsx(EditableContext.Provider, {
value: childContext,
children: /*#__PURE__*/_jsx(Box, _extends({
ref: ref
}, rest, {
children: typeof children === 'function' ? children({
isEditing: isEditing,
onSubmit: handleSubmit,
onCancel: handleCancel,
onRequestEdit: onRequestEdit
}) : children
}))
});
});
Editable.displayName = 'Editable';
var sharedProps = {
fontFamily: 'inherit',
fontSize: 'inherit',
fontWeight: 'inherit',
textAlign: 'inherit',
fontStyle: 'normal',
fontStretch: 'normal',
lineHeight: 'normal',
background: 'transparent',
transition: 'all 0.2s',
borderRadius: '4px',
padding: '0',
margin: '0',
border: '2px solid transparent'
};
export var EditablePreview = function EditablePreview(props) {
var _useContext = useContext(EditableContext),
isEditing = _useContext.isEditing,
isDisabled = _useContext.isDisabled,
value = _useContext.value,
onRequestEdit = _useContext.onRequestEdit,
placeholder = _useContext.placeholder,
isPreviewFocusable = _useContext.isPreviewFocusable;
var hasValue = value != null && value !== '';
var getTabIndex = function getTabIndex() {
if ((!isEditing || !isDisabled) && isPreviewFocusable) {
return 0;
}
return null;
};
var styleProps = _extends({}, sharedProps, {
cursor: 'text',
display: 'inline-block',
opacity: !hasValue ? 0.6 : undefined
});
if (isEditing) {
return null;
}
return /*#__PURE__*/_jsx(Box, _extends({
as: "span",
"aria-disabled": isDisabled,
tabIndex: getTabIndex(),
onFocus: onRequestEdit
}, styleProps, props, {
children: hasValue ? value : placeholder
}));
};
export var EditableInput = function EditableInput(_ref2) {
var _onBlur = _ref2.onBlur,
children = _ref2.children,
restProps = _objectWithoutPropertiesLoose(_ref2, _excluded2);
var _useContext2 = useContext(EditableContext),
inputRef = _useContext2.inputRef,
isEditing = _useContext2.isEditing,
onChange = _useContext2.onChange,
onKeyDown = _useContext2.onKeyDown,
value = _useContext2.value,
onSubmit = _useContext2.onSubmit,
onCancel = _useContext2.onCancel,
submitOnBlur = _useContext2.submitOnBlur,
placeholder = _useContext2.placeholder,
isDisabled = _useContext2.isDisabled;
if (!isEditing) {
return null;
}
var styleProps = _extends({}, sharedProps, {
width: '100%',
padding: '0',
margin: '0'
});
var renderProps = {
ref: inputRef,
onBlur: function onBlur(event) {
submitOnBlur ? onSubmit() : onCancel();
if (_onBlur) {
_onBlur(event);
}
},
value: value,
placeholder: placeholder,
onChange: onChange,
onKeyDown: onKeyDown
};
return children ? children(renderProps) : /*#__PURE__*/_jsx(Box, _extends({
as: "input",
outline: "none",
"aria-disabled": isDisabled,
disabled: isDisabled
}, renderProps, styleProps, restProps));
};
EditableInput.defaultProps = {
children: null,
onBlur: function onBlur() {}
};
Editable.defaultProps = {
defaultValue: '',
isPreviewFocusable: true,
submitOnBlur: true,
selectAllOnFocus: true,
isDisabled: false,
startWithEditView: false,
onCancel: function onCancel() {},
onChange: function onChange() {},
onEdit: function onEdit() {},
onSubmit: function onSubmit() {},
placeholder: '',
value: ''
};
Editable.displayName = 'Editable';
export default Editable;