diff --git a/package.json b/package.json index a86ad0a03c512d..fc1dd0c96461c7 100644 --- a/package.json +++ b/package.json @@ -174,6 +174,7 @@ "@types/react-dom": "17.0.15", "@types/react-is": "17.0.3", "@types/react-test-renderer": "17.0.2", + "@types/react-transition-group": "4.4.6", "@types/request-promise-native": "1.0.18", "@types/scheduler": "0.16.2", "@types/semver": "^6.2.0", diff --git a/packages/fluentui/react-northstar/src/components/Animation/Animation.tsx b/packages/fluentui/react-northstar/src/components/Animation/Animation.tsx index 109c22c5149bee..402e376b1ca5d4 100644 --- a/packages/fluentui/react-northstar/src/components/Animation/Animation.tsx +++ b/packages/fluentui/react-northstar/src/components/Animation/Animation.tsx @@ -195,6 +195,7 @@ export const Animation = React.forwardRef((props className={!isChildrenFunction ? cx(animationClasses, className, (child as any)?.props?.className) : ''} > {isChildrenFunction ? ( + // @ts-ignore - @types/react-transition-group doesn't actually include this API, nor is it documented ({ state }) => { const childWithClasses = (children as AnimationChildrenProp)({ classes: cx(animationClasses, className, (child as any)?.props?.className), diff --git a/packages/react-components/react-toast/.storybook/main.js b/packages/react-components/react-toast/.storybook/main.js new file mode 100644 index 00000000000000..26536b61b387f6 --- /dev/null +++ b/packages/react-components/react-toast/.storybook/main.js @@ -0,0 +1,14 @@ +const rootMain = require('../../../../.storybook/main'); + +module.exports = /** @type {Omit} */ ({ + ...rootMain, + stories: [...rootMain.stories, '../stories/**/*.stories.mdx', '../stories/**/index.stories.@(ts|tsx)'], + addons: [...rootMain.addons], + webpackFinal: (config, options) => { + const localConfig = { ...rootMain.webpackFinal(config, options) }; + + // add your own webpack tweaks if needed + + return localConfig; + }, +}); diff --git a/packages/react-components/react-toast/.storybook/preview.js b/packages/react-components/react-toast/.storybook/preview.js new file mode 100644 index 00000000000000..1939500a3d18c7 --- /dev/null +++ b/packages/react-components/react-toast/.storybook/preview.js @@ -0,0 +1,7 @@ +import * as rootPreview from '../../../../.storybook/preview'; + +/** @type {typeof rootPreview.decorators} */ +export const decorators = [...rootPreview.decorators]; + +/** @type {typeof rootPreview.parameters} */ +export const parameters = { ...rootPreview.parameters }; diff --git a/packages/react-components/react-toast/.storybook/tsconfig.json b/packages/react-components/react-toast/.storybook/tsconfig.json new file mode 100644 index 00000000000000..ea89218a3d916f --- /dev/null +++ b/packages/react-components/react-toast/.storybook/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "", + "allowJs": true, + "checkJs": true, + "types": ["static-assets", "environment", "storybook__addons"] + }, + "include": ["../stories/**/*.stories.ts", "../stories/**/*.stories.tsx", "*.js"] +} diff --git a/packages/react-components/react-toast/etc/react-toast.api.md b/packages/react-components/react-toast/etc/react-toast.api.md index e85599257dab54..54701f3fc974cb 100644 --- a/packages/react-components/react-toast/etc/react-toast.api.md +++ b/packages/react-components/react-toast/etc/react-toast.api.md @@ -4,6 +4,19 @@ ```ts +import * as React_2 from 'react'; + +// @public (undocumented) +export const Toaster: React_2.FC; + +// @public (undocumented) +export type ToastPosition = 'top-right' | 'top-center' | 'top-left' | 'bottom-right' | 'bottom-center' | 'bottom-left'; + +// @public (undocumented) +export function useToastController(): { + dispatchToast: (content: React_2.ReactNode, options?: ToastOptions | undefined) => void; +}; + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/react-components/react-toast/package.json b/packages/react-components/react-toast/package.json index 276520bb4d01a6..286619fde89cb7 100644 --- a/packages/react-components/react-toast/package.json +++ b/packages/react-components/react-toast/package.json @@ -21,7 +21,9 @@ "test": "jest --passWithNoTests", "test-ssr": "test-ssr ./stories/**/*.stories.tsx", "type-check": "tsc -b tsconfig.json", - "generate-api": "just-scripts generate-api" + "generate-api": "just-scripts generate-api", + "storybook": "start-storybook", + "start": "yarn storybook" }, "devDependencies": { "@fluentui/eslint-plugin": "*", @@ -31,7 +33,10 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { + "react-transition-group": "^4.4.1", "@fluentui/react-jsx-runtime": "9.0.0-alpha.2", + "@fluentui/react-portal": "^9.2.6", + "@fluentui/react-shared-contexts": "^9.3.3", "@fluentui/react-theme": "^9.1.7", "@fluentui/react-utilities": "^9.8.0", "@griffel/react": "^1.5.2", diff --git a/packages/react-components/react-toast/src/components/Timer/Timer.tsx b/packages/react-components/react-toast/src/components/Timer/Timer.tsx new file mode 100644 index 00000000000000..f98265da4ca1f5 --- /dev/null +++ b/packages/react-components/react-toast/src/components/Timer/Timer.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { useStyles } from './useTimerStyles.styles'; + +export const Timer: React.FC<{ + running: boolean; + timeout: number; + onTimeout: () => void; +}> = props => { + const styles = useStyles(); + const { running, timeout, onTimeout } = props; + const ref = React.useRef(null); + + React.useEffect(() => { + if (ref.current) { + const timerElement = ref.current; + timerElement.addEventListener('animationend', onTimeout); + return () => timerElement.removeEventListener('animationend', onTimeout); + } + }, [onTimeout]); + + const style: React.CSSProperties = { + animationDuration: `${timeout}ms`, + animationPlayState: running ? 'running' : 'paused', + }; + + if (timeout < 0) { + return null; + } + + return ; +}; diff --git a/packages/react-components/react-toast/src/components/Timer/index.ts b/packages/react-components/react-toast/src/components/Timer/index.ts new file mode 100644 index 00000000000000..e79e25f75ab3a2 --- /dev/null +++ b/packages/react-components/react-toast/src/components/Timer/index.ts @@ -0,0 +1 @@ +export * from './Timer'; diff --git a/packages/react-components/react-toast/src/components/Timer/useTimerStyles.styles.ts b/packages/react-components/react-toast/src/components/Timer/useTimerStyles.styles.ts new file mode 100644 index 00000000000000..aa90d34e0adbc2 --- /dev/null +++ b/packages/react-components/react-toast/src/components/Timer/useTimerStyles.styles.ts @@ -0,0 +1,14 @@ +import { makeStyles } from '@griffel/react'; + +export const useStyles = makeStyles({ + progress: { + animationName: { + from: { + opacity: 0, + }, + to: { + opacity: 0, + }, + }, + }, +}); diff --git a/packages/react-components/react-toast/src/components/Toast.tsx b/packages/react-components/react-toast/src/components/Toast.tsx new file mode 100644 index 00000000000000..3d29381e27d5ac --- /dev/null +++ b/packages/react-components/react-toast/src/components/Toast.tsx @@ -0,0 +1,106 @@ +/** + * ⚠️ This is temporary and WILL be removed + */ + +import * as React from 'react'; +import { Transition } from 'react-transition-group'; +import { useIsomorphicLayoutEffect } from '@fluentui/react-utilities'; +import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; +import { useToast, Toast as ToastProps } from '../state'; +import { Timer } from './Timer'; + +const useStyles = makeStyles({ + toast: { + ...shorthands.border('2px', 'dashed', 'red'), + ...shorthands.padding('4px'), + display: 'flex', + minHeight: '40px', + maxHeight: '40px', + minWidth: '200px', + maxWidth: '200px', + alignItems: 'center', + backgroundColor: 'white', + }, + + slide: { + animationDuration: '200ms, 400ms', + animationDelay: '0ms, 200ms', + animationName: [ + { + from: { + height: '0', + minHeight: '0', + maxHeight: '0', + opacity: 0, + }, + to: { + opacity: 0, + }, + }, + { + from: { + opacity: 0, + }, + to: { + opacity: 1, + }, + }, + ], + }, + + fadeOut: { + animationDuration: '400ms, 200ms', + animationDelay: '0ms, 400ms', + animationName: [ + { + from: { + opacity: 1, + }, + to: { + opacity: 0, + }, + }, + { + from: { + opacity: 0, + }, + to: { + opacity: 0, + height: 0, + maxHeight: 0, + minHeight: 0, + }, + }, + ], + }, +}); + +export const Toast: React.FC & { visible: boolean }> = props => { + const styles = useStyles(); + const { visible, children, close, remove, timeout } = props; + const { play, running } = useToast(); + const toastRef = React.useRef(null); + + // start the toast once it's fully in + useIsomorphicLayoutEffect(() => { + if (toastRef.current) { + const toast = toastRef.current; + toast.addEventListener('animationend', play, { + once: true, + }); + + return () => { + toast.removeEventListener('animationend', play); + }; + } + }, [play, toastRef]); + + return ( + +
+ {children} + +
+
+ ); +}; diff --git a/packages/react-components/react-toast/src/components/Toaster.tsx b/packages/react-components/react-toast/src/components/Toaster.tsx new file mode 100644 index 00000000000000..b387b043d05e3f --- /dev/null +++ b/packages/react-components/react-toast/src/components/Toaster.tsx @@ -0,0 +1,45 @@ +/** + * ⚠️ This is temporary and WILL be removed + */ + +import * as React from 'react'; +import { Portal } from '@fluentui/react-portal'; +import { useToaster, getPositionStyles } from '../state'; +import { Toast } from './Toast'; +import { makeStyles, mergeClasses } from '@griffel/react'; + +const useStyles = makeStyles({ + container: { + position: 'fixed', + }, +}); + +export const Toaster: React.FC = () => { + const { getToastsToRender, isToastVisible } = useToaster(); + + const styles = useStyles(); + + return ( + +
+ {getToastsToRender((position, toasts) => { + return ( +
+ {toasts.map(({ content, ...toastProps }) => { + return ( + + {content as React.ReactNode} + + ); + })} +
+ ); + })} +
+
+ ); +}; diff --git a/packages/react-components/react-toast/src/index.ts b/packages/react-components/react-toast/src/index.ts index aacbad0068e241..d5a5e178359dbc 100644 --- a/packages/react-components/react-toast/src/index.ts +++ b/packages/react-components/react-toast/src/index.ts @@ -1,2 +1,4 @@ -// TODO: replace with real exports -export {}; +export { Toaster } from './components/Toaster'; + +export { useToastController } from './state'; +export type { ToastPosition } from './state'; diff --git a/packages/react-components/react-toast/src/state/constants.ts b/packages/react-components/react-toast/src/state/constants.ts new file mode 100644 index 00000000000000..bfaa28528c6f38 --- /dev/null +++ b/packages/react-components/react-toast/src/state/constants.ts @@ -0,0 +1,3 @@ +export const EVENTS = { + show: 'fui-toast-show', +} as const; diff --git a/packages/react-components/react-toast/src/state/index.ts b/packages/react-components/react-toast/src/state/index.ts new file mode 100644 index 00000000000000..551edbd9f4763e --- /dev/null +++ b/packages/react-components/react-toast/src/state/index.ts @@ -0,0 +1,5 @@ +export * from './types'; +export * from './useToaster'; +export * from './useToast'; +export * from './useToastController'; +export { getPositionStyles } from './vanilla'; diff --git a/packages/react-components/react-toast/src/state/types.ts b/packages/react-components/react-toast/src/state/types.ts new file mode 100644 index 00000000000000..fa985d5925f797 --- /dev/null +++ b/packages/react-components/react-toast/src/state/types.ts @@ -0,0 +1,25 @@ +import { EVENTS } from './constants'; + +export type ToastId = string; + +export type ToastPosition = 'top-right' | 'top-center' | 'top-left' | 'bottom-right' | 'bottom-center' | 'bottom-left'; + +export interface ToastOptions { + toastId?: ToastId; + position?: ToastPosition; + content?: unknown; + timeout?: number; +} + +export interface Toast extends Required> { + close: () => void; + remove: () => void; +} + +export interface ToastEventMap { + [EVENTS.show]: CustomEvent; +} + +export type ToastEventListenerGeneric = (e: ToastEventMap[K]) => void; +export type ToastShowEventListener = ToastEventListenerGeneric; +export type ToastEventListener = ToastShowEventListener; diff --git a/packages/react-components/react-toast/src/state/useToast.ts b/packages/react-components/react-toast/src/state/useToast.ts new file mode 100644 index 00000000000000..2142da55df6fa7 --- /dev/null +++ b/packages/react-components/react-toast/src/state/useToast.ts @@ -0,0 +1,18 @@ +import * as React from 'react'; +import { Toast } from './vanilla/toast'; +import { useForceUpdate } from '@fluentui/react-utilities'; + +export function useToast() { + const forceRender = useForceUpdate(); + const [toast] = React.useState(() => { + const newToast = new Toast(); + newToast.onUpdate = forceRender; + return newToast; + }); + + return { + play: toast.play, + pause: toast.pause, + running: toast.running, + }; +} diff --git a/packages/react-components/react-toast/src/state/useToastController.ts b/packages/react-components/react-toast/src/state/useToastController.ts new file mode 100644 index 00000000000000..59af3fd3694389 --- /dev/null +++ b/packages/react-components/react-toast/src/state/useToastController.ts @@ -0,0 +1,21 @@ +import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts'; +import { dispatchToast as dispatchToastVanilla } from './vanilla/dispatchToast'; +import * as React from 'react'; +import { ToastOptions } from './types'; + +export function useToastController() { + const { targetDocument } = useFluent(); + + const dispatchToast = React.useCallback( + (content: React.ReactNode, options?: ToastOptions) => { + if (targetDocument) { + dispatchToastVanilla(content, options, targetDocument); + } + }, + [targetDocument], + ); + + return { + dispatchToast, + }; +} diff --git a/packages/react-components/react-toast/src/state/useToaster.ts b/packages/react-components/react-toast/src/state/useToaster.ts new file mode 100644 index 00000000000000..b467edef72afe4 --- /dev/null +++ b/packages/react-components/react-toast/src/state/useToaster.ts @@ -0,0 +1,54 @@ +import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts'; +import * as React from 'react'; +import { Toaster } from './vanilla/toaster'; +import { useForceUpdate } from '@fluentui/react-utilities'; +import { Toast, ToastId, ToastPosition } from './types'; + +export function useToaster() { + const { targetDocument } = useFluent(); + const forceRender = useForceUpdate(); + const [toaster] = React.useState(() => { + if (targetDocument) { + const newToaster = new Toaster(targetDocument); + newToaster.onUpdate = forceRender; + return newToaster; + } + }); + + const getToastsToRender = React.useCallback( + (cb: (position: ToastPosition, toasts: Toast[]) => T) => { + if (!toaster) { + return []; + } + + const toRender = new Map(); + const toasts = Array.from(toaster.toasts.values()); + + toasts.forEach(toast => { + const { position } = toast; + toRender.has(position) || toRender.set(position, []); + toRender.get(position)!.push(toast); + }); + + return Array.from(toRender, ([position, toastsToRender]) => { + if (position.startsWith('top')) { + toastsToRender.reverse(); + } + + return cb(position, toastsToRender); + }); + }, + [toaster], + ); + + return { + isToastVisible: (toastId: ToastId) => { + if (toaster) { + return toaster.isToastVisible(toastId); + } + + return false; + }, + getToastsToRender, + }; +} diff --git a/packages/react-components/react-toast/src/state/vanilla/dispatchToast.ts b/packages/react-components/react-toast/src/state/vanilla/dispatchToast.ts new file mode 100644 index 00000000000000..fa0f4e504a3ce3 --- /dev/null +++ b/packages/react-components/react-toast/src/state/vanilla/dispatchToast.ts @@ -0,0 +1,10 @@ +import { ToastOptions } from '../types'; +import { EVENTS } from '../constants'; + +let counter = 0; + +export function dispatchToast(content: unknown, options: ToastOptions = {}, targetDocument: Document) { + options.toastId ??= (counter++).toString(); + const event = new CustomEvent(EVENTS.show, { bubbles: false, cancelable: false, detail: { ...options, content } }); + targetDocument.dispatchEvent(event); +} diff --git a/packages/react-components/react-toast/src/state/vanilla/getPositionStyles.ts b/packages/react-components/react-toast/src/state/vanilla/getPositionStyles.ts new file mode 100644 index 00000000000000..96c06fc01bd466 --- /dev/null +++ b/packages/react-components/react-toast/src/state/vanilla/getPositionStyles.ts @@ -0,0 +1,44 @@ +import { ToastPosition } from '../types'; + +interface PositionStyles { + position: 'fixed'; + top?: number; + left?: number; + right?: number; + bottom?: number; +} + +export const getPositionStyles = (position: ToastPosition) => { + const positionStyles: PositionStyles = { + position: 'fixed', + }; + + switch (position) { + case 'top-left': + Object.assign(positionStyles, { + top: 0, + left: 0, + }); + break; + case 'top-right': + Object.assign(positionStyles, { + top: 0, + right: 0, + }); + break; + case 'bottom-left': + Object.assign(positionStyles, { + bottom: 0, + left: 0, + }); + break; + case 'bottom-right': + Object.assign(positionStyles, { + bottom: 0, + right: 0, + }); + break; + } + + return positionStyles; +}; diff --git a/packages/react-components/react-toast/src/state/vanilla/index.ts b/packages/react-components/react-toast/src/state/vanilla/index.ts new file mode 100644 index 00000000000000..671fab78b6b05e --- /dev/null +++ b/packages/react-components/react-toast/src/state/vanilla/index.ts @@ -0,0 +1,4 @@ +export * from './dispatchToast'; +export * from './toast'; +export * from './toaster'; +export * from './getPositionStyles'; diff --git a/packages/react-components/react-toast/src/state/vanilla/toast.ts b/packages/react-components/react-toast/src/state/vanilla/toast.ts new file mode 100644 index 00000000000000..544cca1479e6bc --- /dev/null +++ b/packages/react-components/react-toast/src/state/vanilla/toast.ts @@ -0,0 +1,13 @@ +// TODO convert to closure +export class Toast { + public running = false; + public onUpdate: () => void = () => null; + + public play() { + this.running = true; + } + + public pause() { + this.running = false; + } +} diff --git a/packages/react-components/react-toast/src/state/vanilla/toaster.ts b/packages/react-components/react-toast/src/state/vanilla/toaster.ts new file mode 100644 index 00000000000000..f4fe62a7c4ebc1 --- /dev/null +++ b/packages/react-components/react-toast/src/state/vanilla/toaster.ts @@ -0,0 +1,85 @@ +import { Toast, ToastEventListener, ToastEventListenerGeneric, ToastEventMap, ToastId, ToastOptions } from '../types'; +import { EVENTS } from '../constants'; + +// TODO convert to closure +export class Toaster { + public visibleToasts: Set; + public toasts: Map; + public onUpdate: () => void; + private targetDocument: Document; + + private listeners = new Map(); + + constructor(targetDocument: Document) { + this.toasts = new Map(); + this.visibleToasts = new Set(); + this.onUpdate = () => null; + this.targetDocument = targetDocument; + + this._initEvents(); + } + + public dispose() { + this.toasts.clear(); + for (const [event, callback] of this.listeners.entries()) { + this._removeEventListener(event, callback); + this.listeners.delete(event); + } + } + + public isToastVisible(toastId: ToastId) { + return this.visibleToasts.has(toastId); + } + + private _initEvents() { + const buildToast: ToastEventListener = e => this._buildToast(e.detail); + + this.listeners.set(EVENTS.show, buildToast); + + this._addEventListener(EVENTS.show, buildToast); + } + + private _addEventListener( + eventType: TEvent, + callback: ToastEventListenerGeneric, + ) { + this.targetDocument.addEventListener(eventType, callback as () => void); + } + + private _removeEventListener( + eventType: keyof ToastEventMap, + callback: ToastEventListenerGeneric, + ) { + this.targetDocument.removeEventListener(eventType, callback as () => void); + } + + private _buildToast(toastOptions: ToastOptions) { + const { toastId = '', position = 'bottom-right', timeout = 3000, content = '' } = toastOptions; + if (this.toasts.has(toastId)) { + return; + } + + const close = () => { + this.visibleToasts.delete(toastId); + this.onUpdate(); + }; + + const remove = () => { + this.toasts.delete(toastId); + this.onUpdate(); + }; + + const toast: Toast = { + position, + toastId, + timeout, + content, + close, + remove, + }; + + this.visibleToasts.add(toastId); + this.toasts.set(toastId, toast); + this.onUpdate(); + } +} diff --git a/packages/react-components/react-toast/src/testing/isConformant.ts b/packages/react-components/react-toast/src/testing/isConformant.ts new file mode 100644 index 00000000000000..a3d988f29a1728 --- /dev/null +++ b/packages/react-components/react-toast/src/testing/isConformant.ts @@ -0,0 +1,15 @@ +import { isConformant as baseIsConformant } from '@fluentui/react-conformance'; +import type { IsConformantOptions, TestObject } from '@fluentui/react-conformance'; +import griffelTests from '@fluentui/react-conformance-griffel'; + +export function isConformant( + testInfo: Omit, 'componentPath'> & { componentPath?: string }, +) { + const defaultOptions: Partial> = { + tsConfig: { configName: 'tsconfig.spec.json' }, + componentPath: require.main?.filename.replace('.test', ''), + extraTests: griffelTests as TestObject, + }; + + baseIsConformant(defaultOptions, testInfo); +} diff --git a/packages/react-components/react-toast/stories/Toast/CustomTimeout.stories.tsx b/packages/react-components/react-toast/stories/Toast/CustomTimeout.stories.tsx new file mode 100644 index 00000000000000..b23bd00f62cbdf --- /dev/null +++ b/packages/react-components/react-toast/stories/Toast/CustomTimeout.stories.tsx @@ -0,0 +1,14 @@ +import * as React from 'react'; +import { Toaster, useToastController } from '@fluentui/react-toast'; + +export const CustomTimeout = () => { + const { dispatchToast } = useToastController(); + const notify = () => dispatchToast('This is a toast', { timeout: 1000 }); + + return ( + <> + + + + ); +}; diff --git a/packages/react-components/react-toast/stories/Toast/Default.stories.tsx b/packages/react-components/react-toast/stories/Toast/Default.stories.tsx new file mode 100644 index 00000000000000..2e7061eca874f0 --- /dev/null +++ b/packages/react-components/react-toast/stories/Toast/Default.stories.tsx @@ -0,0 +1,14 @@ +import * as React from 'react'; +import { Toaster, useToastController } from '@fluentui/react-toast'; + +export const Default = () => { + const { dispatchToast } = useToastController(); + const notify = () => dispatchToast('This is a toast'); + + return ( + <> + + + + ); +}; diff --git a/packages/react-components/react-toast/stories/Toast/ToastPositions.stories.tsx b/packages/react-components/react-toast/stories/Toast/ToastPositions.stories.tsx new file mode 100644 index 00000000000000..b2a1380c29a9eb --- /dev/null +++ b/packages/react-components/react-toast/stories/Toast/ToastPositions.stories.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { Toaster, useToastController, ToastPosition } from '@fluentui/react-toast'; + +export const ToastPositions = () => { + const { dispatchToast } = useToastController(); + const notify = (position: ToastPosition) => dispatchToast('This is a toast', { position }); + + return ( + <> + + + + + + + ); +}; diff --git a/packages/react-components/react-toast/stories/Toast/index.stories.tsx b/packages/react-components/react-toast/stories/Toast/index.stories.tsx new file mode 100644 index 00000000000000..8ed02a592f3835 --- /dev/null +++ b/packages/react-components/react-toast/stories/Toast/index.stories.tsx @@ -0,0 +1,7 @@ +export { Default } from './Default.stories'; +export { CustomTimeout } from './CustomTimeout.stories'; +export { ToastPositions } from './ToastPositions.stories'; + +export default { + title: 'Preview Components/Toast', +}; diff --git a/packages/react-components/react-toast/tsconfig.json b/packages/react-components/react-toast/tsconfig.json index 12ca516af1c5b2..1941a041d46c19 100644 --- a/packages/react-components/react-toast/tsconfig.json +++ b/packages/react-components/react-toast/tsconfig.json @@ -17,6 +17,9 @@ }, { "path": "./tsconfig.spec.json" + }, + { + "path": "./.storybook/tsconfig.json" } ] } diff --git a/packages/react-components/react-toast/tsconfig.lib.json b/packages/react-components/react-toast/tsconfig.lib.json index b2da24eff1b32f..6f90cf95c005bd 100644 --- a/packages/react-components/react-toast/tsconfig.lib.json +++ b/packages/react-components/react-toast/tsconfig.lib.json @@ -9,6 +9,14 @@ "inlineSources": true, "types": ["static-assets", "environment"] }, - "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx"], + "exclude": [ + "./src/testing/**", + "**/*.spec.ts", + "**/*.spec.tsx", + "**/*.test.ts", + "**/*.test.tsx", + "**/*.stories.ts", + "**/*.stories.tsx" + ], "include": ["./src/**/*.ts", "./src/**/*.tsx"] } diff --git a/packages/react-components/react-toast/tsconfig.spec.json b/packages/react-components/react-toast/tsconfig.spec.json index 469fcba4d7ba75..911456fe4b4d91 100644 --- a/packages/react-components/react-toast/tsconfig.spec.json +++ b/packages/react-components/react-toast/tsconfig.spec.json @@ -5,5 +5,13 @@ "outDir": "dist", "types": ["jest", "node"] }, - "include": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx", "**/*.d.ts"] + "include": [ + "**/*.spec.ts", + "**/*.spec.tsx", + "**/*.test.ts", + "**/*.test.tsx", + "**/*.d.ts", + "./src/testing/**/*.ts", + "./src/testing/**/*.tsx" + ] } diff --git a/yarn.lock b/yarn.lock index 730a36ee10b92e..f06568ba3158c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5929,6 +5929,13 @@ dependencies: "@types/react" "^17" +"@types/react-transition-group@4.4.6": + version "4.4.6" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.6.tgz#18187bcda5281f8e10dfc48f0943e2fdf4f75e2e" + integrity sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew== + dependencies: + "@types/react" "*" + "@types/react-virtualized@^9.21.8": version "9.21.8" resolved "https://registry.yarnpkg.com/@types/react-virtualized/-/react-virtualized-9.21.8.tgz#dc0150a75fd6e42f33729886463ece04d03367ea"