UNPKG

chayns-components

Version:

A set of beautiful React components for developing chayns® applications.

194 lines (186 loc) 7 kB
"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