UNPKG

@atlaskit/form

Version:

A form allows people to input information.

100 lines (99 loc) • 3.69 kB
import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import React, { Children, isValidElement, useContext, useMemo, useState } from 'react'; import ExitingPersistence from '@atlaskit/motion/exiting-persistence'; import { fg } from '@atlaskit/platform-feature-flags/fg'; import { FormSubmitContext } from './form-submit-context'; import { MessageWrapperContext } from './message-context'; import MessageGroup from './message-group'; import messageMotion from './message-motion-capability'; /** * __Message wrapper __ * * A message wrapper is used to allow assistive technologies, like screen readers, to announce error or * valid messages. This must be loaded into the DOM before the * ErrorMessage, ValidMessage is loaded. Otherwise, assistive technologies * may not render the message. * */ export var MessageWrapper = function MessageWrapper(_ref) { var children = _ref.children; var contextValue = { isWrapper: true, hasMotionBoundary: false, transition: 'row' }; var shouldProvideMotionBoundary = fg('platform-dst-motion-uplift-input') && Children.toArray(children).every(messageMotion.isCapable); return /*#__PURE__*/React.createElement(MessageWrapperContext.Provider, { value: contextValue }, /*#__PURE__*/React.createElement("div", { "aria-live": "polite", "data-testid": "message-wrapper" }, shouldProvideMotionBoundary ? /*#__PURE__*/React.createElement(MotionMessages, null, children) : children)); }; var getChildKeys = function getChildKeys(children) { return Children.toArray(children).filter(isValidElement).map(function (child) { return child.key; }).filter(function (key) { return key !== null; }); }; var getTransition = function getTransition(previousKeys, currentKeys) { var previous = new Set(previousKeys); var current = new Set(currentKeys); var removedCount = previousKeys.filter(function (key) { return !current.has(key); }).length; var addedCount = currentKeys.filter(function (key) { return !previous.has(key); }).length; if (removedCount > 0 && addedCount > 0) { return 'instant'; } if (previousKeys.length === 0 && addedCount > 1) { return 'groupEnter'; } if (currentKeys.length === 0 && removedCount > 1) { return 'groupExit'; } return 'row'; }; var MotionMessages = function MotionMessages(_ref2) { var children = _ref2.children; var currentKeys = getChildKeys(children); var submitCount = useContext(FormSubmitContext); var _useState = useState(function () { return { keys: currentKeys, mode: 'row', submitCount: submitCount }; }), _useState2 = _slicedToArray(_useState, 2), transition = _useState2[0], setTransition = _useState2[1]; var hasKeyChange = currentKeys.length !== transition.keys.length || currentKeys.some(function (key, index) { return key !== transition.keys[index]; }); var isSubmitUpdate = submitCount !== transition.submitCount; if (hasKeyChange || isSubmitUpdate) { setTransition({ keys: currentKeys, mode: !hasKeyChange ? transition.mode : isSubmitUpdate ? 'instant' : getTransition(transition.keys, currentKeys), submitCount: submitCount }); } var motionContextValue = useMemo(function () { return { isWrapper: true, hasMotionBoundary: true, transition: transition.mode }; }, [transition.mode]); return /*#__PURE__*/React.createElement(MessageWrapperContext.Provider, { value: motionContextValue }, /*#__PURE__*/React.createElement(MessageGroup, { transition: transition.mode }, /*#__PURE__*/React.createElement(ExitingPersistence, { appear: true }, children))); };