@atlaskit/form
Version:
A form allows people to input information.
100 lines (99 loc) • 3.69 kB
JavaScript
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)));
};