@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
359 lines (358 loc) • 13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.countOptions = countOptions;
exports.default = void 0;
exports.makeOptions = makeOptions;
exports.mapOptions = mapOptions;
var _react = _interopRequireWildcard(require("react"));
var _clsx = _interopRequireDefault(require("clsx"));
var _componentHelper = require("../../../../shared/component-helper.js");
var _index = require("../../../../components/index.js");
var _index2 = _interopRequireDefault(require("../Option/index.js"));
var _index3 = require("../../hooks/index.js");
var _useFieldProps = require("../../hooks/useFieldProps.js");
var _utils = require("../../../../components/flex/utils.js");
var _index4 = _interopRequireDefault(require("../../FieldBlock/index.js"));
var _useDataValue = _interopRequireDefault(require("../../hooks/useDataValue.js"));
var _withComponentMarkers = _interopRequireDefault(require("../../../../shared/helpers/withComponentMarkers.js"));
var _jsxRuntime = require("react/jsx-runtime");
var _em, _em2;
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function Selection(props) {
var _props$autocompletePr;
const clearValue = (0, _react.useMemo)(() => `clear-option-${(0, _componentHelper.makeUniqueId)()}`, []);
const {
id,
className,
variant = 'dropdown',
layout = 'vertical',
optionsLayout = 'vertical',
placeholder,
value,
info,
warning,
error,
hasError,
disabled,
size,
emptyValue,
width,
htmlAttributes,
setHasFocus,
handleChange,
setDisplayValue,
transformSelection,
data,
groups,
dataPath,
children,
additionalArgs,
autocompleteProps,
dropdownProps
} = (0, _index3.useFieldProps)(props);
const {
getValueByPath
} = (0, _useDataValue.default)();
let dataList = data;
if (dataPath) {
dataList = getValueByPath(dataPath);
}
const hasRenderPropChildren = typeof children === 'function';
const renderedChildren = (0, _react.useMemo)(() => {
return resolveChildren(children, value, dataList);
}, [children, dataList, value]);
const handleDrawerListChange = (0, _react.useCallback)(({
data,
value
}) => {
const selectedKey = typeof data === 'object' && data ? data.selectedKey : value;
handleChange === null || handleChange === void 0 || handleChange(!selectedKey || selectedKey === clearValue ? emptyValue : selectedKey, {
data
});
}, [handleChange, emptyValue, clearValue]);
const onChangeHandler = (0, _react.useCallback)(({
value
}) => {
handleChange === null || handleChange === void 0 || handleChange(value === undefined ? emptyValue : value);
}, [handleChange, emptyValue]);
const handleShow = (0, _react.useCallback)(({
data
}) => {
setHasFocus(true, typeof data === 'object' && data ? data.selectedKey : undefined);
}, [setHasFocus]);
const handleHide = (0, _react.useCallback)(({
data
}) => {
setHasFocus(false, typeof data === 'object' && data ? data.selectedKey : undefined);
}, [setHasFocus]);
const cn = (0, _clsx.default)(`dnb-forms-field-selection dnb-forms-field-selection__variant--${variant} dnb-forms-field-selection--layout-${layout} dnb-forms-field-selection--options-layout--${optionsLayout}`, className);
const fieldBlockProps = {
forId: id,
className: cn,
disableStatusSummary: true,
...(0, _utils.pickSpacingProps)(props)
};
const onType = props === null || props === void 0 || (_props$autocompletePr = props.autocompleteProps) === null || _props$autocompletePr === void 0 ? void 0 : _props$autocompletePr.onType;
const onTypeAutocompleteHandler = (0, _react.useCallback)(event => {
if (typeof onType === 'function') {
const {
value
} = event;
onType({
...event,
...additionalArgs,
value: value === '' ? emptyValue : value
});
}
}, [additionalArgs, emptyValue, onType]);
switch (variant) {
case 'radio':
case 'button':
{
const Component = variant === 'radio' ? _index.Radio : _index.ToggleButton;
const items = renderRadioItems({
id,
value,
variant,
info,
warning,
htmlAttributes,
children: renderedChildren,
dataList: hasRenderPropChildren ? undefined : dataList,
hasError,
iterateOverItems: ({
value: v,
label
}) => {
if (v === value) {
setDisplayValue(label);
}
}
});
const additionalFieldBlockProps = {
asFieldset: hasRenderPropChildren || _react.default.Children.count(items) > 1,
fieldsetRole: variant === 'radio' ? 'radiogroup' : 'group'
};
if (!size) {
additionalFieldBlockProps.labelHeight = 'small';
}
if (width) {
additionalFieldBlockProps.contentWidth = width;
}
return (0, _jsxRuntime.jsx)(_index4.default, {
...fieldBlockProps,
...additionalFieldBlockProps,
children: (0, _jsxRuntime.jsx)(Component.Group, {
size: size,
className: cn,
layoutDirection: optionsLayout === 'horizontal' ? 'row' : 'column',
disabled: disabled,
onChange: onChangeHandler,
value: String(value !== null && value !== void 0 ? value : ''),
children: items
})
});
}
case 'autocomplete':
case 'dropdown':
{
var _data$find;
const data = renderDropdownItems(hasRenderPropChildren ? undefined : dataList, transformSelection).concat(makeOptions(renderedChildren, transformSelection)).filter(Boolean);
const displayValue = (_data$find = data.find(item => item.selectedKey === value)) === null || _data$find === void 0 ? void 0 : _data$find.content;
setDisplayValue(displayValue);
const sharedProps = {
id,
listClass: 'dnb-forms-field-selection__list',
portalClass: 'dnb-forms-field-selection__portal',
title: placeholder,
value: String(value !== null && value !== void 0 ? value : ''),
status: hasError || (0, _useFieldProps.checkForError)([error, info, warning]) ? 'error' : undefined,
disabled,
...htmlAttributes,
data,
groups,
size,
onChange: handleDrawerListChange,
onOpen: handleShow,
onClose: handleHide,
stretch: true
};
const specificFieldBlockProps = {
contentWidth: width !== null && width !== void 0 ? width : 'large'
};
return (0, _jsxRuntime.jsx)(_index4.default, {
...fieldBlockProps,
...specificFieldBlockProps,
children: variant === 'autocomplete' ? (0, _jsxRuntime.jsx)(_index.Autocomplete, {
...sharedProps,
...autocompleteProps,
value: autocompleteProps !== null && autocompleteProps !== void 0 && autocompleteProps.preventSelection ? undefined : value,
onType: onTypeAutocompleteHandler,
data: !props.data && !props.dataPath && (autocompleteProps === null || autocompleteProps === void 0 ? void 0 : autocompleteProps.mode) === 'async' ? undefined : data,
selectAll: true
}) : (0, _jsxRuntime.jsx)(_index.Dropdown, {
...sharedProps,
...dropdownProps
})
});
}
}
}
function resolveChildren(children, value, options) {
if (typeof children === 'function') {
return children({
value,
options
});
}
return children;
}
function renderRadioItems({
id,
value: valueProp,
variant,
info,
warning,
htmlAttributes,
children,
dataList,
hasError,
iterateOverItems
}) {
const optionsCount = countOptions(children) + ((dataList === null || dataList === void 0 ? void 0 : dataList.length) || 0);
const createOption = (props, i) => {
const {
value,
title,
children,
error,
help,
size,
...rest
} = props;
const label = title !== null && title !== void 0 ? title : children;
const suffix = help ? (0, _jsxRuntime.jsx)(_index.HelpButton, {
size: "small",
title: (0, _componentHelper.convertJsxToString)(help.title),
children: help.content
}) : undefined;
iterateOverItems === null || iterateOverItems === void 0 || iterateOverItems({
value,
label
});
const Component = variant === 'radio' ? _index.Radio : _index.ToggleButton;
return (0, _jsxRuntime.jsx)(Component, {
id: optionsCount === 1 ? id : undefined,
label: variant === 'radio' ? label : undefined,
text: variant === 'button' ? label : undefined,
role: "radio",
value: String(value !== null && value !== void 0 ? value : valueProp) || undefined,
status: hasError || (0, _useFieldProps.checkForError)([error, info, warning]) ? 'error' : undefined,
suffix: suffix,
size: size,
...htmlAttributes,
...rest
}, `option-${i}-${id}`);
};
return [...(dataList || []).map((props, i) => {
return createOption(props, i);
}), ...(mapOptions(children, {
createOption
}) || [])].filter(Boolean);
}
function countOptions(children) {
let count = 0;
_react.default.Children.forEach(children, child => {
if (_react.default.isValidElement(child)) {
if (child.type === _index2.default) {
count++;
} else if (child.props.children) {
count += countOptions(child.props.children);
}
}
});
return count;
}
function mapOptions(children, {
createOption
}) {
return _react.default.Children.map(children, (child, i) => {
if (_react.default.isValidElement(child)) {
if (child.type === _index2.default) {
return createOption(child.props, i);
}
if (child.props.children) {
const nestedChildren = mapOptions(child.props.children, {
createOption
});
return _react.default.createElement(child.type, child.props, nestedChildren);
}
}
return child;
});
}
function makeOptions(children, transformSelection) {
return _react.default.Children.map(children, child => {
var _child;
if (((_child = child) === null || _child === void 0 || (_child = _child['props']) === null || _child === void 0 || (_child = _child.children) === null || _child === void 0 ? void 0 : _child.type) === _index2.default) {
child = child['props'].children;
}
if (_react.default.isValidElement(child) && child.type === _index2.default) {
var _ref, _props$title, _props$value;
const props = child.props;
const title = (_ref = (_props$title = props.title) !== null && _props$title !== void 0 ? _props$title : props.children) !== null && _ref !== void 0 ? _ref : _em || (_em = (0, _jsxRuntime.jsx)("em", {
children: "Untitled"
}));
const content = props.text ? [title, props.text] : title;
const selectedValue = transformSelection ? transformSelection(props) : undefined;
const selectedKey = String((_props$value = props.value) !== null && _props$value !== void 0 ? _props$value : '');
const disabled = props.disabled;
const style = props.style;
const groupIndex = props.groupIndex;
return {
selectedKey,
selectedValue,
content,
disabled,
style,
groupIndex
};
}
if (child) {
return {
content: child
};
}
return undefined;
});
}
function renderDropdownItems(data, transformSelection) {
return (data === null || data === void 0 ? void 0 : data.map(props => {
const {
value,
title,
text,
disabled,
style,
...rest
} = props;
return {
selectedKey: value,
content: (text ? [title, text] : title) || _em2 || (_em2 = (0, _jsxRuntime.jsx)("em", {
children: "Untitled"
})),
selectedValue: transformSelection ? transformSelection(props) : undefined,
disabled,
style,
...rest
};
})) || [];
}
(0, _withComponentMarkers.default)(Selection, {
_supportsSpacingProps: true
});
var _default = exports.default = Selection;
//# sourceMappingURL=Selection.js.map