UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

359 lines (358 loc) 13 kB
"use strict"; 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