UNPKG

@workday/canvas-kit-react

Version:

The parent module that contains all Workday Canvas Kit React components

101 lines (100 loc) 4.2 kB
import React from 'react'; import { createContainer } from '@workday/canvas-kit-react/common'; import { Popup } from '@workday/canvas-kit-react/popup'; import { ToastCloseIcon } from './ToastCloseIcon'; import { ToastIcon } from './ToastIcon'; import { ToastMessage } from './ToastMessage'; import { ToastLink } from './ToastLink'; import { ToastBody } from './ToastBody'; import { useToastModel } from './hooks/useToastModel'; import { calc, createStencil } from '@workday/canvas-kit-styling'; import { system } from '@workday/canvas-tokens-web'; import { mergeStyles } from '@workday/canvas-kit-react/layout'; /** * The function helps set the correct aria attributes based on the mode * @param mode Defines what aria attributes will be added to the main container * @param id Used to tie the Toast to Toast.Message for screen readers */ const getAriaAttributes = (mode, id) => { switch (mode) { case 'dialog': return { 'aria-describedby': id, // This is added by Popup.Card, so overwriting to remove it 'aria-labelledby': undefined, role: 'dialog', }; case 'alert': return { role: 'alert', 'aria-live': 'assertive', 'aria-atomic': true, }; case 'status': return { role: 'status', 'aria-live': 'polite', 'aria-atomic': true, }; default: { return {}; } } }; const toastStencil = createStencil({ base: { name: "d5h46a", styles: "box-sizing:border-box;display:flex;flex-direction:row;width:calc(calc(var(--cnvs-sys-space-x20) * 4) + var(--cnvs-sys-space-x10));padding:var(--cnvs-sys-space-zero);gap:var(--cnvs-sys-space-x1);" } }, "toast-55513d"); /** * Toast is a compound component that has different modes based on its contents. The modes add the proper aria attributes for accessibility * * ```tsx * import { Toast } from "@workday/canvas-kit-react/toast"; * * const MyToast = (props: CardProps) => ( * <Toast mode="dialog" aria-label="notifcation"> * <Toast.Icon icon={checkIcon} color={colors.greenApple400} /> * <Toast.Body> * <Toast.Message>Your workbook was successfully processed.</Toast.Message> * <Toast.Link href="#hreflink">Custom Link</Toast.Link> * </Toast.Body> * <Toast.CloseIcon aria-label="Close" onClick={handleClose} /> * </Toast> * ); *``` */ export const Toast = createContainer('div')({ displayName: 'Toast', modelHook: useToastModel, subComponents: { /** * `Toast.Body` should container `Toast.Message` and `Toast.Link`. This ensures proper styling and spacing between elements. * * ```tsx * <Toast.Body> * <Toast.Message>Your workbook was successfully processed.</Toast.Message> * <Toast.Link href="#hreflink">Custom Link</Toast.Link> * </Toast.Body> * ``` */ Body: ToastBody, /** * `Toast.CloseIcon` renders a {@link PopupCloseIcon}. You can pass an `onClick` when used with `Popper` to dismiss the `Toast`. */ CloseIcon: ToastCloseIcon, /** * `ToastIcon` renders a `SystemIcon` where you have access to all styling properties from `SystemIcon`. */ Icon: ToastIcon, /** * `Toast.Message` renders our `Subtext` component where you can style however way you'd like with style properties. * This component also has an `id` so that when the `Toast` has a prop of `mode="dialog"` the message is read out by screen readers by adding an `aria-describedby` on the main `Toast` component. */ Message: ToastMessage, /** * `Toast.Link` renders our `Hyperlink` component. If you need to link to more information, use this component. */ Link: ToastLink, }, })(({ children, ...elemProps }, _, model) => { return (React.createElement(Popup.Card, { ...getAriaAttributes(model.state.mode, model.state.id), ...mergeStyles(elemProps, toastStencil()) }, children)); });