UNPKG

@itwin/itwinui-react

Version:

A react component library for iTwinUI

162 lines (161 loc) 5.74 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true, }); Object.defineProperty(exports, 'InputGrid', { enumerable: true, get: function () { return InputGrid; }, }); const _interop_require_default = require('@swc/helpers/_/_interop_require_default'); const _interop_require_wildcard = require('@swc/helpers/_/_interop_require_wildcard'); const _react = /*#__PURE__*/ _interop_require_wildcard._(require('react')); const _index = require('../../utils/index.js'); const _classnames = /*#__PURE__*/ _interop_require_default._( require('classnames'), ); const _Label = require('../Label/Label.js'); const _Input = require('../Input/Input.js'); const _Textarea = require('../Textarea/Textarea.js'); const _StatusMessage = require('../StatusMessage/StatusMessage.js'); const _InputWithDecorations = require('../InputWithDecorations/InputWithDecorations.js'); const _ComboBox = require('../ComboBox/ComboBox.js'); const _Select = require('../Select/Select.js'); const InputGrid = _react.forwardRef((props, ref) => { let { children: childrenProp, className, labelPlacement, ...rest } = props; let children = useChildrenWithIds(childrenProp); return _react.createElement( _index.Box, { className: (0, _classnames.default)('iui-input-grid', className), 'data-iui-label-placement': labelPlacement, ref: ref, ...rest, }, children, ); }); if ('development' === process.env.NODE_ENV) InputGrid.displayName = 'InputGrid'; const useChildrenWithIds = (children) => { let { labelId, inputId, messageId } = useSetup(children); return _react.useMemo( () => _react.Children.map(children, (child) => { if (!_react.isValidElement(child)) return child; if (child.type === _Label.Label || 'label' === child.type) return (0, _index.cloneElementWithRef)(child, (child) => ({ ...child.props, htmlFor: child.props.htmlFor || inputId, id: child.props.id || labelId, })); if (child.type === _StatusMessage.StatusMessage) return (0, _index.cloneElementWithRef)(child, (child) => ({ ...child.props, id: child.props.id || messageId, })); if ( isInput(child) || child.type === _InputWithDecorations.InputWithDecorations || child.type === _index.InputWithIcon ) return handleCloningInputs(child, { labelId, inputId, messageId, }); return child; }), [children, inputId, labelId, messageId], ); }; const useSetup = (children) => { let idPrefix = (0, _index.useId)(); let labelId; let inputId; let messageId; let hasLabel = false; let hasSelect = false; let findInputId = (child) => { if (!_react.isValidElement(child)) return; if (child.type === _ComboBox.ComboBox) return child.props.inputProps?.id || `${idPrefix}--input`; if (child.type !== _Select.Select) return child.props.id || `${idPrefix}--input`; }; _react.Children.forEach(children, (child) => { if (!_react.isValidElement(child)) return; if (child.type === _Label.Label || 'label' === child.type) { hasLabel = true; labelId || (labelId = child.props.id || `${idPrefix}--label`); } if (child.type === _StatusMessage.StatusMessage) messageId || (messageId = child.props.id || `${idPrefix}--message`); if ( child.type === _InputWithDecorations.InputWithDecorations || child.type === _index.InputWithIcon ) _react.Children.forEach(child.props.children, (child) => { if (isInput(child)) inputId || (inputId = findInputId(child)); }); else if (isInput(child)) inputId || (inputId = findInputId(child)); if (child.type === _Select.Select) hasSelect = true; }); return { labelId: hasSelect ? labelId : void 0, inputId: hasLabel && !hasSelect ? inputId : void 0, messageId, }; }; const handleCloningInputs = (child, { labelId, inputId, messageId }) => { let inputProps = (props = {}) => { let ariaDescribedBy = [props['aria-describedby'], messageId] .filter(Boolean) .join(' '); return { ...props, ...(child.type !== _Select.Select && { id: props.id || inputId, }), 'aria-describedby': ariaDescribedBy?.trim() || void 0, }; }; let cloneInput = (child) => { if (child.type === _ComboBox.ComboBox) return (0, _index.cloneElementWithRef)(child, (child) => ({ inputProps: inputProps(child.props.inputProps), })); if (child.type === _Select.Select) return (0, _index.cloneElementWithRef)(child, (child) => ({ triggerProps: { 'aria-labelledby': labelId, ...inputProps(child.props.triggerProps), }, })); return (0, _index.cloneElementWithRef)(child, (child) => inputProps(child.props), ); }; if ( child.type === _InputWithDecorations.InputWithDecorations || child.type === _index.InputWithIcon ) return (0, _index.cloneElementWithRef)(child, (child) => ({ children: _react.Children.map(child.props.children, (child) => { if (_react.isValidElement(child) && isInput(child)) return cloneInput(child); return child; }), })); return cloneInput(child); }; const isInput = (child) => _react.isValidElement(child) && ('input' === child.type || 'textarea' === child.type || 'select' === child.type || child.type === _Input.Input || child.type === _Textarea.Textarea || child.type === _InputWithDecorations.InputWithDecorations.Input || child.type === _Select.Select || child.type === _ComboBox.ComboBox);