UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

604 lines (603 loc) 27.3 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.inputPropTypes = exports.default = exports.SubmitButton = void 0; require("core-js/modules/web.dom-collections.iterator.js"); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _classnames = _interopRequireDefault(require("classnames")); var _componentHelper = require("../../shared/component-helper"); var _AlignmentHelper2 = _interopRequireDefault(require("../../shared/AlignmentHelper")); var _SpacingHelper = require("../space/SpacingHelper"); var _SkeletonHelper = require("../skeleton/SkeletonHelper"); var _filterValidProps = require("../../shared/helpers/filterValidProps"); var _Button = _interopRequireWildcard(require("../button/Button")); var _FormLabel = _interopRequireDefault(require("../form-label/FormLabel")); var _FormStatus = _interopRequireDefault(require("../form-status/FormStatus")); var _IconPrimary = _interopRequireDefault(require("../icon-primary/IconPrimary")); var _Context = _interopRequireDefault(require("../../shared/Context")); var _Suffix = _interopRequireDefault(require("../../shared/helpers/Suffix")); var _AlignmentHelper; const _excluded = ["type", "size", "label", "label_direction", "label_sr_only", "status", "globalStatus", "status_state", "status_props", "status_no_animation", "disabled", "skeleton", "placeholder", "clear", "keep_placeholder", "suffix", "align", "input_class", "submit_button_title", "clear_button_title", "submit_button_variant", "submit_button_icon", "submit_button_status", "submit_element", "inner_element", "autocomplete", "readOnly", "stretch", "input_attributes", "icon", "icon_position", "icon_size", "className", "id", "children", "value", "selectall", "on_submit", "input_element"], _excluded2 = ["id", "title", "disabled", "skeleton", "variant", "icon", "icon_size", "status", "status_state", "status_props", "className"]; function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } 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 _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; } 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; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } const inputPropTypes = exports.inputPropTypes = _objectSpread(_objectSpread({ type: _propTypes.default.string, size: _propTypes.default.oneOfType([_propTypes.default.oneOf(['default', 'small', 'medium', 'large']), _propTypes.default.number]), value: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), id: _propTypes.default.string, label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.func, _propTypes.default.node]), label_direction: _propTypes.default.oneOf(['horizontal', 'vertical']), label_sr_only: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]), status: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool, _propTypes.default.func, _propTypes.default.node]), globalStatus: _propTypes.default.shape({ id: _propTypes.default.string, message: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.node]) }), status_state: _propTypes.default.string, status_props: _propTypes.default.object, status_no_animation: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]), input_state: _propTypes.default.string, autocomplete: _propTypes.default.string, submit_button_title: _propTypes.default.string, clear_button_title: _propTypes.default.string, placeholder: _propTypes.default.node, clear: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]), keep_placeholder: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]), suffix: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.func, _propTypes.default.node]), align: _propTypes.default.oneOf(['left', 'center', 'right']), selectall: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]), stretch: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]), disabled: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]), skeleton: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]), input_class: _propTypes.default.string, input_attributes: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.object]), input_element: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.node]), icon: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.node, _propTypes.default.func]), icon_size: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), icon_position: _propTypes.default.oneOf(['left', 'right']), inner_ref: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object]), readOnly: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]), inner_element: _propTypes.default.node, submit_element: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.node]), submit_button_variant: _Button.buttonVariantPropType.variant, submit_button_icon: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.node, _propTypes.default.func]), submit_button_status: _propTypes.default.string }, _SpacingHelper.spacingPropTypes), {}, { className: _propTypes.default.string, children: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func]), on_change: _propTypes.default.func, on_key_down: _propTypes.default.func, on_submit: _propTypes.default.func, on_focus: _propTypes.default.func, on_blur: _propTypes.default.func, on_submit_focus: _propTypes.default.func, on_submit_blur: _propTypes.default.func, on_state_update: _propTypes.default.func, on_clear: _propTypes.default.func }); class Input extends _react.default.PureComponent { static getDerivedStateFromProps(props, state) { const value = Input.getValue(props); if (value !== 'initval' && value !== state.value && value !== state._value) { if (value !== state.value && typeof props.on_state_update === 'function') { (0, _componentHelper.dispatchCustomElementEvent)({ props }, 'on_state_update', { value }); } state.value = value; } if (props.input_state) { state.inputState = props.input_state; } state._value = props.value; return state; } static hasValue(value) { return (typeof value === 'string' || typeof value === 'number') && String(value).length > 0 || false; } static getValue(props) { const value = (0, _componentHelper.processChildren)(props); if (value === '' || Input.hasValue(value)) { return value; } return props.value; } constructor(props, context) { super(props); _defineProperty(this, "state", { inputState: 'virgin', value: null, _value: null }); _defineProperty(this, "updateInputValue", () => { if (this._ref.current && !this.props.input_element) { const value = this.state.value; const hasValue = Input.hasValue(value); this._ref.current.value = hasValue ? value : ''; } }); _defineProperty(this, "onFocusHandler", event => { const { value } = event.target; this.setState({ inputState: 'focus' }); (0, _componentHelper.dispatchCustomElementEvent)(this, 'on_focus', { value, event }); if ((0, _componentHelper.isTrue)(this.props.selectall) && this._ref.current) { clearTimeout(this._selectallTimeout); this._selectallTimeout = setTimeout(() => { try { this._ref.current.select(); } catch (e) { (0, _componentHelper.warn)(e); } }, 1); } }); _defineProperty(this, "onBlurHandler", event => { const { value } = event.target; const result = (0, _componentHelper.dispatchCustomElementEvent)(this, 'on_blur', { value, event }); if (result !== false) { this.setState({ inputState: Input.hasValue(value) && value !== this.state._value ? 'dirty' : 'initial' }); } }); _defineProperty(this, "onChangeHandler", event => { const { value } = event.target; const result = (0, _componentHelper.dispatchCustomElementEvent)(this, 'on_change', { value, event }); if (result === false) { this.updateInputValue(); return; } if (typeof result === 'string') { this.setState({ value: result }); } else { this.setState({ value }); } }); _defineProperty(this, "onKeyDownHandler", event => { const value = event.target.value; (0, _componentHelper.dispatchCustomElementEvent)(this, 'on_key_down', { value, event }); if (event.key === 'Enter') { (0, _componentHelper.dispatchCustomElementEvent)(this, 'on_submit', { value, event }); } }); _defineProperty(this, "clearValue", event => { const previousValue = this.state.value; const value = ''; this.setState({ value }); (0, _componentHelper.dispatchCustomElementEvent)(this, 'on_change', { value, event }); (0, _componentHelper.dispatchCustomElementEvent)(this, 'on_clear', { value, previousValue, event }); this._ref.current.focus({ preventScroll: true }); }); this._ref = props.inner_ref || _react.default.createRef(); this._id = props.id || context.FormRow && typeof context.FormRow.useId === 'function' && context.FormRow.useId() || context.formElement && typeof context.formElement.useId === 'function' && context.formElement.useId() || (0, _componentHelper.makeUniqueId)(); if ((0, _componentHelper.isTrue)(props.clear) && props.icon_position === 'right') { (0, _componentHelper.warn)('You cannot have a clear button and icon_position="right"'); } } componentWillUnmount() { clearTimeout(this._selectallTimeout); } componentDidMount() { this.updateInputValue(); } componentDidUpdate() { this.updateInputValue(); } render() { var _this$context, _this$context2, _this$context3; const props = (0, _componentHelper.extendPropsWithContextInClassComponent)(this.props, Input.defaultProps, { skeleton: (_this$context = this.context) === null || _this$context === void 0 ? void 0 : _this$context.skeleton }, this.context.getTranslation(this.props).Input, (0, _filterValidProps.pickFormElementProps)((_this$context2 = this.context) === null || _this$context2 === void 0 ? void 0 : _this$context2.FormRow), (0, _filterValidProps.pickFormElementProps)((_this$context3 = this.context) === null || _this$context3 === void 0 ? void 0 : _this$context3.formElement), this.context.Input); const { type, size, label, label_direction, label_sr_only, status, globalStatus, status_state, status_props, status_no_animation, disabled, skeleton, placeholder, clear, keep_placeholder, suffix, align, input_class, submit_button_title, clear_button_title, submit_button_variant, submit_button_icon, submit_button_status, submit_element, inner_element, autocomplete, readOnly, stretch, input_attributes, icon, icon_position, icon_size, className, id: _id, children, value: _value, selectall, on_submit, input_element: _input_element } = props, attributes = _objectWithoutProperties(props, _excluded); let { value, focusState, inputState } = this.state; if ((0, _componentHelper.isTrue)(disabled) || (0, _componentHelper.isTrue)(skeleton)) { inputState = 'disabled'; } const sizeIsNumber = parseFloat(size) > 0; const id = this._id; const showStatus = (0, _componentHelper.getStatusState)(status); const hasSubmitButton = submit_element || submit_element !== false && type === 'search'; const hasValue = Input.hasValue(value); const iconSize = size === 'large' && (icon_size === 'default' || !icon_size) ? 'medium' : icon_size; const mainParams = { className: (0, _classnames.default)("dnb-input dnb-input__border--tokens dnb-form-component", (0, _SpacingHelper.createSpacingClasses)(props), className, icon && `dnb-input--icon-position-${icon_position} dnb-input--has-icon` + (iconSize ? ` dnb-input--icon-size-${iconSize}` : ""), type && `dnb-input--${type}`, size && !sizeIsNumber && `dnb-input--${size}`, hasSubmitButton && 'dnb-input--has-submit-element', inner_element && 'dnb-input--has-inner-element', (0, _componentHelper.isTrue)(clear) && 'dnb-input--has-clear-button', align && `dnb-input__align--${align}`, status && `dnb-input__status--${status_state}`, disabled && 'dnb-input--disabled', label_direction && `dnb-input--${label_direction}`, (0, _componentHelper.isTrue)(stretch) && `dnb-input--stretch`, (0, _componentHelper.isTrue)(keep_placeholder) && 'dnb-input--keep-placeholder'), 'data-input-state': inputState, 'data-has-content': hasValue ? 'true' : 'false' }; const innerParams = { className: 'dnb-input__inner' }; let { input_element: InputElement } = props; const inputAttributes = input_attributes ? typeof input_attributes === 'string' ? JSON.parse(input_attributes) : input_attributes : {}; const inputParams = _objectSpread(_objectSpread(_objectSpread({ className: (0, _classnames.default)('dnb-input__input', input_class), autoComplete: autocomplete, type, id, disabled: (0, _componentHelper.isTrue)(disabled), name: id, 'aria-placeholder': placeholder ? (0, _componentHelper.convertJsxToString)(placeholder) : undefined }, attributes), inputAttributes), {}, { onChange: this.onChangeHandler, onKeyDown: this.onKeyDownHandler, onFocus: this.onFocusHandler, onBlur: this.onBlurHandler }); if (sizeIsNumber) { inputParams.size = size; } if (showStatus || suffix || hasSubmitButton) { inputParams['aria-describedby'] = (0, _componentHelper.combineDescribedBy)(inputParams, hasSubmitButton && !submit_element ? id + '-submit-button' : null, showStatus ? id + '-status' : null, suffix ? id + '-suffix' : null); } if (readOnly) { inputParams['aria-readonly'] = inputParams.readOnly = true; } const shellParams = { className: (0, _classnames.default)("dnb-input__shell dnb-input__border", (0, _SkeletonHelper.createSkeletonClass)('shape', skeleton, this.context)) }; (0, _SkeletonHelper.skeletonDOMAttributes)(inputParams, skeleton, this.context); (0, _componentHelper.validateDOMAttributes)(this.props, inputParams); (0, _componentHelper.validateDOMAttributes)(null, shellParams); if (InputElement && typeof InputElement === 'function') { InputElement = InputElement(_objectSpread(_objectSpread({}, inputParams), {}, { value }), this._ref); } else if (!InputElement && _input_element) { InputElement = _input_element; } return _react.default.createElement("span", mainParams, label && _react.default.createElement(_FormLabel.default, { id: id + '-label', forId: id, text: label, labelDirection: label_direction, srOnly: label_sr_only, disabled: disabled, skeleton: skeleton }), _react.default.createElement("span", innerParams, _AlignmentHelper || (_AlignmentHelper = _react.default.createElement(_AlignmentHelper2.default, null)), _react.default.createElement(_FormStatus.default, _extends({ show: showStatus, id: id + '-form-status', globalStatus: globalStatus, label: label, text: status, state: status_state, text_id: id + '-status', no_animation: status_no_animation, skeleton: skeleton }, status_props)), _react.default.createElement("span", { className: "dnb-input__row" }, _react.default.createElement("span", shellParams, InputElement || _react.default.createElement("input", _extends({ ref: this._ref }, inputParams)), inner_element && _react.default.createElement("span", { className: "dnb-input__inner__element dnb-p" }, inner_element), icon && _react.default.createElement(InputIcon, { className: "dnb-input__icon", icon: icon, size: iconSize }), !hasValue && placeholder && focusState !== 'focus' && _react.default.createElement("span", { id: id + '-placeholder', className: 'dnb-input__placeholder' + (align ? ` dnb-input__align--${align}` : ""), role: "presentation", "aria-hidden": true }, placeholder), (0, _componentHelper.isTrue)(clear) && icon_position !== 'right' && _react.default.createElement("span", { className: "dnb-input--clear dnb-input__submit-element" }, _react.default.createElement(InputSubmitButton, { "aria-hidden": !hasValue, attributes: { className: 'dnb-input__clear-button' }, id: id + '-clear-button', type: "button", variant: "tertiary", "aria-controls": id, "aria-label": clear_button_title, tooltip: hasValue && clear_button_title, icon: "close", icon_size: size === 'small' ? 'small' : undefined, skeleton: skeleton, disabled: (0, _componentHelper.isTrue)(disabled) || !hasValue, onClick: this.clearValue }))), hasSubmitButton && _react.default.createElement("span", { className: "dnb-input__submit-element" }, submit_element ? submit_element : _react.default.createElement(InputSubmitButton, _extends({}, attributes, { id: id + '-submit-button', value: inputParams.value, icon: submit_button_icon, status: (0, _componentHelper.convertStatusToStateOnly)(submit_button_status || status, status_state), status_state: status_state, icon_size: size === 'medium' || size === 'large' ? 'medium' : 'default', title: submit_button_title, variant: submit_button_variant, disabled: (0, _componentHelper.isTrue)(disabled), skeleton: (0, _componentHelper.isTrue)(skeleton), size: size, on_submit: on_submit }, status_props))), suffix && _react.default.createElement(_Suffix.default, { className: "dnb-input__suffix", id: id + '-suffix', context: props }, suffix)))); } } exports.default = Input; _defineProperty(Input, "contextType", _Context.default); _defineProperty(Input, "defaultProps", { type: 'text', size: null, value: 'initval', id: null, label: null, label_direction: null, label_sr_only: null, status: null, globalStatus: null, status_state: 'error', status_props: null, status_no_animation: null, input_state: null, autocomplete: 'off', placeholder: null, clear: null, keep_placeholder: null, suffix: null, align: null, selectall: null, stretch: null, disabled: null, skeleton: null, input_class: null, input_attributes: null, input_element: null, inner_ref: null, icon: null, icon_size: null, icon_position: 'left', readOnly: false, inner_element: null, submit_element: null, submit_button_title: null, clear_button_title: null, submit_button_variant: 'secondary', submit_button_icon: 'loupe', submit_button_status: null, className: null, children: null, on_change: null, on_key_down: null, on_submit: null, on_focus: null, on_blur: null, on_submit_focus: null, on_submit_blur: null, on_state_update: null, on_clear: null }); process.env.NODE_ENV !== "production" ? Input.propTypes = _objectSpread({}, inputPropTypes) : void 0; class InputSubmitButton extends _react.default.PureComponent { constructor() { super(...arguments); _defineProperty(this, "state", { focusState: 'virgin' }); _defineProperty(this, "onFocusHandler", event => { const value = this.props.value; this.setState({ focusState: 'focus' }); (0, _componentHelper.dispatchCustomElementEvent)(this, 'on_submit_focus', { value, event }); }); _defineProperty(this, "onBlurHandler", event => { const value = this.props.value; this.setState({ focusState: 'dirty' }); (0, _componentHelper.dispatchCustomElementEvent)(this, 'on_submit_blur', { value, event }); }); _defineProperty(this, "onSubmitHandler", event => { const value = this.props.value; (0, _componentHelper.dispatchCustomElementEvent)(this, 'on_submit', { value, event }); }); } render() { const _this$props = this.props, { id, title, disabled, skeleton, variant, icon, icon_size, status, status_state, status_props, className } = _this$props, rest = _objectWithoutProperties(_this$props, _excluded2); const params = _objectSpread({ id, type: 'submit', 'aria-label': title, disabled }, rest); (0, _SkeletonHelper.skeletonDOMAttributes)(params, skeleton, this.context); (0, _componentHelper.validateDOMAttributes)(this.props, params); return _react.default.createElement("span", { className: "dnb-input__submit-button", "data-input-state": this.state.focusState }, _react.default.createElement(_Button.default, _extends({ className: (0, _classnames.default)("dnb-input__submit-button__button dnb-button--input-button", className), variant: variant, icon: icon, icon_size: icon_size, status: status, status_state: status_state, onClick: this.onSubmitHandler, onFocus: this.onFocusHandler, onBlur: this.onBlurHandler }, params, status_props))); } } _defineProperty(InputSubmitButton, "defaultProps", { id: null, value: null, title: null, disabled: false, skeleton: false, variant: 'secondary', icon: 'loupe', icon_size: null, status: null, status_state: 'error', status_props: null, className: null, on_submit: null, on_submit_focus: null, on_submit_blur: null }); process.env.NODE_ENV !== "production" ? InputSubmitButton.propTypes = { id: _propTypes.default.string, value: _propTypes.default.string, title: _propTypes.default.string, variant: _Button.buttonVariantPropType.variant, disabled: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]), skeleton: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool]), icon: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.node, _propTypes.default.func]), icon_size: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), status: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.bool, _propTypes.default.func, _propTypes.default.node]), status_state: _propTypes.default.string, status_props: _propTypes.default.object, className: _propTypes.default.string, on_submit: _propTypes.default.func, on_submit_focus: _propTypes.default.func, on_submit_blur: _propTypes.default.func } : void 0; const SubmitButton = exports.SubmitButton = _react.default.forwardRef((props, ref) => _react.default.createElement(InputSubmitButton, _extends({ innerRef: ref }, props))); const InputIcon = _react.default.memo(props => _react.default.createElement(_IconPrimary.default, props), (_ref, _ref2) => { let { icon: prev } = _ref; let { icon: next } = _ref2; if (typeof prev === 'string' && typeof next === 'string') { return false; } return typeof prev === typeof next; }); InputIcon.propTypes = { icon: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.node, _propTypes.default.func]).isRequired }; Input._formElement = true; Input._supportsSpacingProps = true; //# sourceMappingURL=Input.js.map