- )
- }
-}
-
-Alert.propTypes = {
- /** @ignore Forwarded Ref */
- forwardedRef: refShape,
- /** Style of the alert */
- type: PropTypes.oneOf(['success', 'error', 'warning']).isRequired,
- /** Content of the alert */
- children: PropTypes.node.isRequired,
- /** If this function is defined, a close icon will appear and this function will be called when alert is closed. */
- onClose: PropTypes.func,
- /** Time in ms to auto close the alert */
- autoClose: PropTypes.number,
- /** Set focus to the first focusable element inside alert, which should be the "action" when available or the "close" button */
- focusOnOpen: PropTypes.bool,
- /** If this object is defined, an action button will appear on the right side of the alert. */
- action: PropTypes.shape({
- onClick: PropTypes.func.isRequired,
- label: PropTypes.node.isRequired,
- }),
- /** Defines the title used for hover and accessibility feedback **/
- closeIconLabel: PropTypes.string,
-}
-
-export default withForwardedRef(Alert)
diff --git a/react/components/Alert/index.tsx b/react/components/Alert/index.tsx
new file mode 100755
index 000000000..c27e236b5
--- /dev/null
+++ b/react/components/Alert/index.tsx
@@ -0,0 +1,151 @@
+import React, { useEffect, useRef } from 'react'
+import PropTypes from 'prop-types'
+
+import SuccessIcon from '../icon/Success'
+import FailureIcon from '../icon/Failure'
+import WarningIcon from '../icon/Warning'
+import CloseIcon from '../icon/Close'
+import Button from '../Button'
+import { withForwardedRef, refShape } from '../../modules/withForwardedRef'
+
+type AlertType = 'success' | 'error' | 'warning'
+
+const propTypes = {
+ /** @ignore Forwarded Ref */
+ forwardedRef: refShape,
+ /** Style of the alert */
+ type: PropTypes.oneOf(['success', 'error', 'warning']).isRequired,
+ /** Content of the alert */
+ children: PropTypes.node.isRequired,
+ /** If this function is defined, a close icon will appear and this function will be called when alert is closed. */
+ onClose: PropTypes.func,
+ /** Time in ms to auto close the alert */
+ autoClose: PropTypes.number,
+ /** Set focus to the first focusable element inside alert, which should be the "action" when available or the "close" button */
+ focusOnOpen: PropTypes.bool,
+ /** If this object is defined, an action button will appear on the right side of the alert. */
+ action: PropTypes.shape({
+ onClick: PropTypes.func.isRequired,
+ label: PropTypes.node.isRequired,
+ }),
+ /** Defines the title used for hover and accessibility feedback **/
+ closeIconLabel: PropTypes.string,
+}
+
+export type AlertProps = PropTypes.InferProps
+
+const Alert: React.FunctionComponent = ({
+ type,
+ onClose,
+ action,
+ forwardedRef,
+ closeIconLabel = 'Close',
+ autoClose,
+ focusOnOpen,
+ children,
+}) => {
+ const firstElementRef = useRef(null)
+
+ useEffect(() => {
+ let timeout: NodeJS.Timeout | undefined
+
+ if (autoClose && onClose) {
+ timeout = setTimeout(onClose, autoClose)
+ }
+
+ if (focusOnOpen) {
+ firstElementRef.current && firstElementRef.current.focus()
+ }
+
+ return () => {
+ if (timeout) {
+ clearTimeout(timeout)
+ }
+ }
+ }, [autoClose, focusOnOpen, onClose])
+
+ const innerVerticalPadding = 'pv3'
+ let classes = 'ph5 pv4 br2 '
+ let showIcon = false
+ let Icon: React.ElementType = 'div'
+ let color = 'c-on-base'
+ const handleActionClick = (action && action.onClick) || undefined
+ const displayAction = action && action.onClick && action.label
+
+ switch (type) {
+ case 'success': {
+ showIcon = true
+ classes += 'bg-success--faded '
+ Icon = SuccessIcon
+ color = 'c-success'
+ break
+ }
+ case 'error': {
+ showIcon = true
+ classes += 'bg-danger--faded '
+ Icon = FailureIcon
+ color = 'c-danger'
+ break
+ }
+ default:
+ case 'warning': {
+ showIcon = true
+ classes += 'bg-warning--faded '
+ Icon = WarningIcon
+ color = 'c-warning'
+ break
+ }
+ }
+
+ return (
+