import React, { Fragment, useMemo } from 'react'; import { InjectedIntlProps, injectIntl } from 'react-intl'; import { ErrorMessage, HelperMessage } from '@atlaskit/form'; import { ValidationError, FieldTypeError } from './types'; import { messages } from './messages'; // sidestep XSS issues function makeMarkup(fragment: Node, key?: string) { const { nodeName, nodeType, childNodes, textContent } = fragment; if (nodeType === Node.TEXT_NODE) { return {textContent}; } // NOTE: NodeList doesn't have .map const children: JSX.Element[] = []; childNodes.forEach((childNode, i) => { const markup = makeMarkup(childNode, String(i)); if (markup) { children.push(markup); } }); switch (nodeName) { case 'B': return {children}; case 'I': return {children}; case 'STRONG': return {children}; case 'EM': return {children}; case 'CODE': return {children}; } if (children.length === 1) { return {children[0]}; } if (children.length) { return {children}; } return null; } function Description({ description }: { description: string }) { const markup = useMemo(() => { const dom = new DOMParser().parseFromString(description, 'text/html'); return makeMarkup(dom); }, [description]); return {markup}; } const FieldMessages = function ({ error, description, intl, }: { error?: string; description?: string } & InjectedIntlProps) { if (!error && description) { return ; } switch (error) { case ValidationError.Required: return ( {intl.formatMessage(messages.required)} ); case ValidationError.Invalid: return ( {intl.formatMessage(messages.invalid)} ); case FieldTypeError.isMultipleAndRadio: return ( {intl.formatMessage(messages.isMultipleAndRadio)} ); default: return null; } }; export default injectIntl(FieldMessages);