import React from 'react'; import {ExtractProps, createContainer} from '@workday/canvas-kit-react/common'; import {mergeStyles} from '@workday/canvas-kit-react/layout'; import {Popup} from '@workday/canvas-kit-react/popup'; import {createStencil, px2rem} from '@workday/canvas-kit-styling'; import {base, system} from '@workday/canvas-tokens-web'; import {ToastBody} from './ToastBody'; import {ToastCloseIcon} from './ToastCloseIcon'; import {ToastIcon} from './ToastIcon'; import {ToastLink} from './ToastLink'; import {ToastMessage} from './ToastMessage'; import {useToastModel} from './hooks/useToastModel'; export interface ToastProps extends Omit, 'model'> {} /** * 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: string, id: string): React.HtmlHTMLAttributes => { 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: { display: 'flex', flexDirection: 'row', width: px2rem(360), paddingBlock: system.legacy.padding.sm, paddingInline: `${system.legacy.padding.md} ${system.legacy.padding.xl}`, gap: base.legacy.size150, borderRadius: system.legacy.shape.xl, border: `${px2rem(1)} solid ${system.color.border.default}`, boxShadow: system.depth[5], '@media (forced-colors: active)': { outline: `${px2rem(1)} solid CanvasText`, }, variant: { alt: { border: `${px2rem(1)} solid ${system.sana.color.border.elevated}`, }, tonal: {}, }, }, }); /** * 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) => ( * * * * Your workbook was successfully processed. * Custom Link * * * * ); *``` */ 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 * * Your workbook was successfully processed. * Custom Link * * ``` */ 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, variant, ...elemProps}, _, model) => { return ( {children} ); });