@itwin/itwinui-react
Version:
A react component library for iTwinUI
162 lines (161 loc) • 5.74 kB
JavaScript
;
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);