UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

438 lines (437 loc) 20.8 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; exports.getMessagesFromError = getMessagesFromError; exports.states = void 0; require("core-js/modules/web.dom-collections.iterator.js"); var _react = _interopRequireWildcard(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _FieldBlockContext = _interopRequireDefault(require("./FieldBlockContext")); var _Context = _interopRequireDefault(require("../DataContext/Context")); var _components = require("../../../components"); var _elements = require("../../../elements"); var _componentHelper = require("../../../shared/component-helper"); var _useId = _interopRequireDefault(require("../../../shared/helpers/useId")); var _HelpButtonInline = _interopRequireWildcard(require("../../../components/help-button/HelpButtonInline")); var _SubmitIndicator = _interopRequireDefault(require("../Form/SubmitIndicator/SubmitIndicator")); var _useSharedState = require("../../../shared/helpers/useSharedState"); var _useTranslation = _interopRequireDefault(require("../hooks/useTranslation")); var _utils = require("../utils"); var _useIItemNo = require("../Iterate/ItemNo/useIItemNo"); var _br; const _excluded = ["className", "forId", "layout", "layoutOptions", "composition", "label", "labelDescription", "labelDescriptionInline", "labelSuffix", "labelSrOnly", "help", "asFieldset", "required", "info", "warning", "error", "disableStatusSummary", "fieldState", "disabled", "width", "contentWidth", "labelHeight", "align", "labelSize", "contentClassName", "children"]; function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } 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 _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 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); } 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; } const states = exports.states = ['error', 'info', 'warning']; function FieldBlock(props) { var _props$id; const dataContext = (0, _react.useContext)(_Context.default); const fieldBlockContext = (0, _react.useContext)(_FieldBlockContext.default); const nestedFieldBlockContext = !(fieldBlockContext !== null && fieldBlockContext !== void 0 && fieldBlockContext.disableStatusSummary) ? fieldBlockContext : null; const id = (0, _useId.default)((_props$id = props.id) !== null && _props$id !== void 0 ? _props$id : props.forId); const sharedData = (0, _useSharedState.createSharedState)('field-block-props-' + id); const _Object$assign = Object.assign({}, sharedData.data, props), { className, forId, layout = 'vertical', layoutOptions, composition, label: labelProp, labelDescription, labelDescriptionInline, labelSuffix, labelSrOnly, help, asFieldset, required, info, warning, error, disableStatusSummary, fieldState, disabled, width, contentWidth, labelHeight, align, labelSize, contentClassName, children } = _Object$assign, rest = _objectWithoutProperties(_Object$assign, _excluded); const hasCustomWidth = /\d(rem)$/.test(String(width)); const hasCustomContentWidth = /\d(rem)$/.test(String(contentWidth)); const infoRef = (0, _react.useRef)(); const warningRef = (0, _react.useRef)(); const errorRef = (0, _react.useRef)(); const blockId = (0, _useId.default)(props.id); const [salt, forceUpdate] = (0, _react.useReducer)(() => ({}), {}); const mountedFieldsRef = (0, _react.useRef)(new Map()); const fieldStateRef = (0, _react.useRef)(null); const stateRecordRef = (0, _react.useRef)({}); const fieldStateIdsRef = (0, _react.useRef)(null); const contentsRef = (0, _react.useRef)(null); const hasInitiallyErrorPropRef = (0, _react.useRef)(Boolean(error)); const label = (0, _useIItemNo.useIterateItemNo)({ label: labelProp, labelSuffix, required }); const setInternalRecord = (0, _react.useCallback)(props => { const { stateId, identifier, type } = props; if (!stateRecordRef.current[identifier]) { stateRecordRef.current[identifier] = []; } fieldStateIdsRef.current = { error: null, warning: null, info: null }; const existingIndex = stateRecordRef.current[identifier].findIndex(item => { return item.stateId === stateId && item.type === type; }); if (existingIndex > -1) { stateRecordRef.current[identifier][existingIndex] = _objectSpread(_objectSpread({}, stateRecordRef.current[identifier][existingIndex]), props); } else { stateRecordRef.current[identifier].push(props); } }, []); const setBlockRecordNested = nestedFieldBlockContext === null || nestedFieldBlockContext === void 0 ? void 0 : nestedFieldBlockContext.setBlockRecord; const setBlockRecord = (0, _react.useCallback)(props => { if (setBlockRecordNested) { setBlockRecordNested(props); return; } setInternalRecord(props); forceUpdate(); }, [setBlockRecordNested, setInternalRecord]); const setFieldState = (0, _react.useCallback)((identifier, fieldState) => { if (fieldState !== fieldStateRef.current) { fieldStateRef.current = fieldState; forceUpdate(); } }, []); const showFieldError = (0, _react.useCallback)((identifier, show) => { if (nestedFieldBlockContext) { nestedFieldBlockContext.showFieldError(identifier, show); return; } if (stateRecordRef.current[identifier]) { stateRecordRef.current[identifier] = stateRecordRef.current[identifier].map(item => { if (item.showInitially) { return item; } return _objectSpread(_objectSpread({}, item), {}, { show }); }); forceUpdate(); } }, [nestedFieldBlockContext]); const statusContent = (0, _react.useMemo)(() => { if (typeof error !== 'undefined' || errorRef.current && !error) { errorRef.current = error; setInternalRecord({ identifier: blockId, showInitially: hasInitiallyErrorPropRef.current, type: 'error', content: error }); } if (typeof warning !== 'undefined' || warningRef.current !== warning) { warningRef.current = warning; setInternalRecord({ identifier: blockId, showInitially: true, type: 'warning', content: warning }); } if (typeof info !== 'undefined' || infoRef.current !== info) { infoRef.current = info; setInternalRecord({ identifier: blockId, showInitially: true, type: 'info', content: info }); } const statesWithMessages = Object.entries(stateRecordRef.current).flatMap(_ref => { let [identifier, states] = _ref; return states.map(props => { return _objectSpread({ identifier }, props); }); }).reduce((acc, cur) => { const existing = acc.find(item => { return item.type === cur.type; }); const messages = getMessagesFromError(cur).map(message => { return _objectSpread(_objectSpread({}, cur), {}, { message }); }); if (existing) { existing.messages.push(...messages); } else { acc.push(_objectSpread(_objectSpread({}, cur), {}, { content: undefined, messages })); } return acc; }, []); return states.reduce((acc, type) => { const id = `${props.id || forId || blockId}-form-status--${type}`; acc[type] = { id, label, state: type === 'warning' ? 'warn' : type, width_element: contentsRef, no_animation: process.env.NODE_ENV === 'test' ? true : typeof globalThis !== 'undefined' ? globalThis.IS_TEST === true : false }; const found = statesWithMessages.find(item => { return item.type === type; }); if (found !== null && found !== void 0 && found.messages) { const messages = found.messages.map(msg => { if (msg.type === 'error') { if (!msg.showInitially && !msg.show) { msg.message = null; } } return msg; }).filter(_ref2 => { let { message } = _ref2; return message; }).reduce((acc, msg, i, arr) => { const existingIndex = arr.findIndex(item => { return (0, _componentHelper.convertJsxToString)(item.message) === (0, _componentHelper.convertJsxToString)(msg.message); }); if (existingIndex === i) { acc.push(msg); } return acc; }, []); if (messages.length > 0) { acc[type] = _objectSpread(_objectSpread({}, acc[type]), {}, { children: _react.default.createElement(CombineMessages, { type: type, messages: messages }) }); fieldStateIdsRef.current[type] = id; } else { fieldStateIdsRef.current[type] = undefined; } } return acc; }, salt); }, [error, warning, info, salt, setInternalRecord, blockId, props.id, forId, label]); (0, _react.useEffect)(() => { if (!nestedFieldBlockContext) { showFieldError(blockId, Boolean(error)); } }, [error, blockId, showFieldError, nestedFieldBlockContext]); (0, _react.useEffect)(() => () => { mountedFieldsRef.current = new Map(); stateRecordRef.current = {}; }, []); const mainClasses = (0, _classnames.default)('dnb-forms-field-block', className, composition && `dnb-forms-field-block__composition dnb-forms-field-block__composition--${composition === true ? 'horizontal' : composition}`, width && `dnb-forms-field-block--width-${hasCustomWidth ? 'custom' : width}`, contentWidth && `dnb-forms-field-block--content-width-${hasCustomContentWidth ? 'custom' : contentWidth}`, labelHeight && `dnb-forms-field-block--label-height-${labelHeight}`); const gridClasses = `dnb-forms-field-block__grid dnb-forms-field-block--layout-${layout}`; const enableFieldset = useEnableFieldset({ label, asFieldset, children, nestedFieldBlockContext }); const labelProps = { id: `${id}-label`, className: 'dnb-forms-field-block__label', element: enableFieldset ? 'legend' : 'label', forId: enableFieldset ? undefined : forId, srOnly: labelSrOnly, space: 0, size: labelSize, disabled }; const mainStyle = (0, _react.useMemo)(() => { var _lO$minWidth, _lO$maxWidth; const style = {}; if (hasCustomWidth) { style['--dnb-forms-field-block-width'] = width; } if (hasCustomContentWidth) { style['--dnb-forms-field-block-content-width'] = contentWidth; } const lO = layoutOptions || {}; const min = getFieldWidth((_lO$minWidth = lO.minWidth) !== null && _lO$minWidth !== void 0 ? _lO$minWidth : lO.width); const max = getFieldWidth((_lO$maxWidth = lO.maxWidth) !== null && _lO$maxWidth !== void 0 ? _lO$maxWidth : lO.width); if (typeof min === 'string') { style['--dnb-forms-field-block-layout-width-min'] = min; } if (typeof max === 'string') { style['--dnb-forms-field-block-layout-width-max'] = max; } return style; }, [contentWidth, hasCustomContentWidth, hasCustomWidth, layoutOptions, width]); if (dataContext !== null && dataContext !== void 0 && dataContext.prerenderFieldProps) { return null; } const hasLabelDescription = isFragment(labelDescription) ? fragmentHasChildren(labelDescription) && !fragmentHasOnlyUndefinedChildren(labelDescription) : labelDescription; const hasHelp = (help === null || help === void 0 ? void 0 : help.title) || (help === null || help === void 0 ? void 0 : help.content); return _react.default.createElement(_FieldBlockContext.default.Provider, { value: { setBlockRecord, setFieldState, showFieldError, hasErrorProp: Boolean(error), fieldStateIdsRef, mountedFieldsRef, composition, disableStatusSummary } }, _react.default.createElement(_components.Space, _extends({ element: enableFieldset ? 'fieldset' : 'div', style: mainStyle, className: mainClasses }, rest), _react.default.createElement("div", { className: gridClasses }, (label || labelDescription || hasHelp) && _react.default.createElement(_components.FormLabel, labelProps, _react.default.createElement("span", null, label && _react.default.createElement("span", { className: "dnb-forms-field-block__label__content" }, label), hasHelp && _react.default.createElement(_HelpButtonInline.default, { contentId: `${id}-help`, help: help }), hasLabelDescription && !labelDescriptionInline && (_br || (_br = _react.default.createElement("br", null))), hasLabelDescription && _react.default.createElement("span", { className: "dnb-forms-field-block__label__description" }, labelDescription))), hasHelp && _react.default.createElement(_HelpButtonInline.HelpButtonInlineContent, { contentId: `${id}-help`, className: "dnb-forms-field-block__help", help: help, breakout: layout === 'vertical' && !(nestedFieldBlockContext !== null && nestedFieldBlockContext !== void 0 && nestedFieldBlockContext.composition), outset: layout !== 'horizontal' }), _react.default.createElement("div", { className: 'dnb-forms-field-block__status' + (contentWidth && contentWidth !== 'small' && contentWidth !== 'medium' && !(parseFloat(contentWidth) <= 11) ? ` dnb-forms-field-block__contents--width-${hasCustomContentWidth ? 'custom' : contentWidth}` : "") }, _react.default.createElement(_components.FormStatus, statusContent === null || statusContent === void 0 ? void 0 : statusContent.error), _react.default.createElement(_components.FormStatus, statusContent === null || statusContent === void 0 ? void 0 : statusContent.warning), _react.default.createElement(_components.FormStatus, statusContent === null || statusContent === void 0 ? void 0 : statusContent.info)), _react.default.createElement("div", { className: (0, _classnames.default)('dnb-forms-field-block__contents', contentClassName, contentWidth && `dnb-forms-field-block__contents--width-${hasCustomContentWidth ? 'custom' : contentWidth}`, align && `dnb-forms-field-block__contents--align-${align}`), ref: contentsRef }, children), _react.default.createElement(_SubmitIndicator.default, { state: fieldState !== null && fieldState !== void 0 ? fieldState : fieldStateRef.current, className: "dnb-forms-field-block__indicator dnb-forms-submit-indicator--inline-wrap" })))); } function useEnableFieldset(_ref3) { let { label, asFieldset, children, nestedFieldBlockContext } = _ref3; return (0, _react.useMemo)(() => { if (asFieldset === false) { return false; } let result = asFieldset; if (label && !result && !nestedFieldBlockContext) { let count = 0; (0, _componentHelper.findElementInChildren)(children, child => { var _child$props, _child$type; if (child !== null && child !== void 0 && (_child$props = child.props) !== null && _child$props !== void 0 && _child$props.label || (child === null || child === void 0 ? void 0 : (_child$type = child.type) === null || _child$type === void 0 ? void 0 : _child$type['_formElement']) === true) { count++; } if (count > 1) { return result = true; } }); } return Boolean(result); }, [asFieldset, children, label, nestedFieldBlockContext]); } function CombineMessages(_ref4) { let { type, messages } = _ref4; const translations = (0, _useTranslation.default)().Field; if (messages.length === 1) { return _react.default.createElement(_react.default.Fragment, null, messages[0].message); } return _react.default.createElement(_react.default.Fragment, null, type === 'error' ? translations.errorSummary : translations.stateSummary, _react.default.createElement(_elements.Ul, null, messages.map((_ref5, i) => { let { message } = _ref5; return _react.default.createElement(_elements.Li, { key: i }, message); }))); } function getMessage(error) { if (error instanceof _utils.FormError) { var _error$formattedMessa; return (_error$formattedMessa = error.formattedMessage) !== null && _error$formattedMessa !== void 0 ? _error$formattedMessa : error.message; } return error.message; } function getMessagesFromError(item) { const { content } = item; if (content instanceof _utils.FormError && Array.isArray(content.errors)) { return content.errors.map(content => { return getMessage(content); }); } if (Array.isArray(content)) { return content.map(content => { return content instanceof _utils.FormError || content instanceof Error ? getMessage(content) : content; }); } if (content instanceof _utils.FormError || content instanceof Error) { return [getMessage(content)]; } return [(_react.default.isValidElement(content) ? content : content === null || content === void 0 ? void 0 : content.toString()) || content]; } function isFragment(fragment) { return _react.default.isValidElement(fragment) && fragment.type === _react.default.Fragment; } function fragmentHasChildren(fragment) { return _react.default.isValidElement(fragment) && _react.default.Children.count(fragment.props.children) > 0; } function fragmentHasOnlyUndefinedChildren(fragment) { const isUndefined = child => child === undefined; return _react.default.isValidElement(fragment) && _react.default.Children.toArray(fragment.props.children).every(isUndefined); } FieldBlock._supportsSpacingProps = true; var _default = exports.default = FieldBlock; function getFieldWidth(width) { switch (width) { case 'small': return 'var(--forms-field-width--small)'; case 'medium': return 'var(--forms-field-width--medium)'; case 'large': return 'var(--forms-field-width--large)'; } return width; } //# sourceMappingURL=FieldBlock.js.map