chayns-components
Version:
A set of beautiful React components for developing chayns® applications.
194 lines (186 loc) • 7 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _clsx = _interopRequireDefault(require("clsx"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _react = _interopRequireWildcard(require("react"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/**
* @component
*/
const DEFAULT_STYLE = {
width: '100%',
paddingBottom: '12px'
};
const BORDER_DESIGN_DEFAULT_STYLE = {
width: '100%'
};
/**
* A multiline text input that can automatically grow with its content.
*/
const TextArea = _ref => {
let {
style: styleProp,
className,
placeholder,
defaultValue,
design = TextArea.DEFAULT_DESIGN,
onChange,
autogrow,
onBlur,
onKeyUp,
onKeyDown,
value,
disabled = false,
required,
stopPropagation = false,
reference,
...props
} = _ref;
const ref = (0, _react.useRef)(null);
const offsetRef = (0, _react.useRef)(0);
const grow = (0, _react.useCallback)(() => {
ref.current.style.height = '0px';
ref.current.style.height = `${ref.current.scrollHeight + offsetRef.current}px`;
}, []);
// update in value prop
(0, _react.useEffect)(() => {
if (autogrow) {
grow();
}
}, [grow, autogrow, value]);
// reference or prop change executes initialisation code
const setRef = (0, _react.useCallback)(node => {
ref.current = node;
if (node) {
if (required) {
node.setAttribute('required', '');
}
node.setAttribute('row', '1');
if (!(styleProp !== null && styleProp !== void 0 && styleProp.overflow) && !(styleProp !== null && styleProp !== void 0 && styleProp.overflowX) && !(styleProp !== null && styleProp !== void 0 && styleProp.overflowY)) {
// eslint-disable-next-line no-param-reassign
node.style.overflow = 'hidden';
}
if (autogrow) {
offsetRef.current = node.offsetHeight - node.clientHeight;
grow();
}
}
if (reference) {
reference(node);
}
}, [reference, required, styleProp === null || styleProp === void 0 ? void 0 : styleProp.overflow, styleProp === null || styleProp === void 0 ? void 0 : styleProp.overflowX, styleProp === null || styleProp === void 0 ? void 0 : styleProp.overflowY, autogrow, grow]);
// autogrows on change and pass value to onChange-prop
const handleChange = (0, _react.useCallback)(() => {
if (onChange) {
onChange(ref.current.value);
}
if (autogrow) {
grow();
}
}, [grow, onChange, autogrow]);
// pass only value to onBlur-prop
const handleBlur = (0, _react.useCallback)(() => {
if (onBlur) {
onBlur(ref.current.value); // TODO: Get data from event
}
}, [onBlur]);
const style = {
...(design === TextArea.BORDER_DESIGN ? BORDER_DESIGN_DEFAULT_STYLE : DEFAULT_STYLE),
...styleProp
};
const classNames = (0, _clsx.default)('input', className, disabled && 'input--disabled', design === TextArea.BORDER_DESIGN && 'input--border-design');
return /*#__PURE__*/_react.default.createElement("textarea", (0, _extends2.default)({
className: classNames,
ref: setRef,
placeholder: placeholder,
style: style,
defaultValue: defaultValue,
onChange: handleChange,
onBlur: onBlur ? handleBlur : null,
onKeyUp: onKeyUp,
onKeyDown: onKeyDown,
value: value,
disabled: disabled,
onClick: stopPropagation ? event => event.stopPropagation() : null
}, props));
};
TextArea.DEFAULT_DESIGN = 0;
TextArea.BORDER_DESIGN = 1;
TextArea.propTypes = {
/**
* A React style object that will be applied to the text area.
*/
style: _propTypes.default.objectOf(_propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number])),
/**
* Wether the component ignores any user interaction and is rendered with a
* disabled style.
*/
disabled: _propTypes.default.bool,
/**
* A classname string that will be applied to the `<textarea>`-element.
*/
className: _propTypes.default.string,
/**
* A placeholder, that will be displayed if the text area is empty.
*/
placeholder: _propTypes.default.string,
/**
* Wether the text area is required for a form to complete. Renders the text
* area with an error style when its empty.
*/
required: _propTypes.default.bool,
/**
* The design of the input. Use either `TextArea.DEFAULT_DESIGN` or
* `TextArea.BORDER_DESIGN`.
*/
design: _propTypes.default.number,
/**
* A callback that is invoked when the value of the `<textarea>` changes.
*/
onChange: _propTypes.default.func,
/**
* A callback that is invoked when the text area loses focus.
*/
onBlur: _propTypes.default.func,
/**
* The default value of the text area. Has no effect when the `value` prop
* is used.
*/
defaultValue: _propTypes.default.string,
/**
* The current text value of the area.
*/
value: _propTypes.default.string,
/**
* A callback that will be called when the `keyup`-event is fired from the
* `<textarea>`-element.
*/
onKeyUp: _propTypes.default.func,
/**
* A callback that will be called when the `keydown`-event is fired from the
* `<textarea>`-element.
*/
onKeyDown: _propTypes.default.func,
/**
* Wether the text area should automatically grow with its content.
*/
autogrow: _propTypes.default.bool,
/**
* A function that will be invoked with a reference to the
* `<textarea>`-element or `null`.
*/
reference: _propTypes.default.func,
/**
* Wether click events should be stopped from propagating to parent
* elements.
*/
stopPropagation: _propTypes.default.bool
};
TextArea.displayName = 'TextArea';
var _default = TextArea;
exports.default = _default;
//# sourceMappingURL=TextArea.js.map