From 79078a3a71207cbdba1decaf21988aa18792cd32 Mon Sep 17 00:00:00 2001 From: Evgeny Alaev Date: Thu, 16 May 2024 23:31:49 +0300 Subject: [PATCH] feat(Toaster): add ToasterSingletonNew --- .../Toaster/ToasterSingletonNew.tsx | 57 +++++++++++++++++++ .../Toaster/__stories__/Toaster.stories.tsx | 34 +++++++++++ 2 files changed, 91 insertions(+) create mode 100644 src/components/Toaster/ToasterSingletonNew.tsx diff --git a/src/components/Toaster/ToasterSingletonNew.tsx b/src/components/Toaster/ToasterSingletonNew.tsx new file mode 100644 index 0000000000..9ac26c8ce6 --- /dev/null +++ b/src/components/Toaster/ToasterSingletonNew.tsx @@ -0,0 +1,57 @@ +import React from 'react'; + +import {ToasterProvider} from './Provider/ToasterProvider'; +import {ToasterComponent} from './ToasterComponent/ToasterComponent'; +import type {ToastProps, ToasterPublicMethods} from './types'; + +const TOASTER_NEW_KEY: unique symbol = Symbol('Toaster new instance key'); + +declare global { + interface Window { + [TOASTER_NEW_KEY]: ToasterSingletonNew; + } +} + +export class ToasterSingletonNew { + private componentAPI: null | ToasterPublicMethods = null; + + constructor() { + if (window[TOASTER_NEW_KEY] instanceof ToasterSingletonNew) { + return window[TOASTER_NEW_KEY]; + } + + window[TOASTER_NEW_KEY] = this; + } + + add = (options: ToastProps) => { + this.componentAPI?.add(options); + }; + + remove = (name: string) => { + this.componentAPI?.remove(name); + }; + + removeAll = () => { + this.componentAPI?.removeAll(); + }; + + update = (name: string, overrideOptions: Partial) => { + this.componentAPI?.update(name, overrideOptions); + }; + + has = (name: string) => { + return this.componentAPI?.has(name) ?? false; + }; + + render = () => { + return ( + { + this.componentAPI = api; + }} + > + + + ); + }; +} diff --git a/src/components/Toaster/__stories__/Toaster.stories.tsx b/src/components/Toaster/__stories__/Toaster.stories.tsx index 4403a62a94..29a71c7665 100644 --- a/src/components/Toaster/__stories__/Toaster.stories.tsx +++ b/src/components/Toaster/__stories__/Toaster.stories.tsx @@ -2,9 +2,12 @@ import React from 'react'; import type {Meta, StoryObj} from '@storybook/react'; +import {Button} from '../../Button'; import type {ButtonView} from '../../Button'; +import {useTheme} from '../../theme'; import {ToasterProvider} from '../Provider/ToasterProvider'; import {Toast} from '../Toast/Toast'; +import {ToasterSingletonNew} from '../ToasterSingletonNew'; import {ToasterDemo} from './ToasterShowcase'; @@ -93,3 +96,34 @@ export const Default: Story = { args: {}, render: (props) => , }; + +const toasterSingletonNew1 = new ToasterSingletonNew(); + +const ToastContent = () => { + const theme = useTheme(); + return `Current theme: ${theme}`; +}; + +let index = 0; + +const someFnOutsideReact = () => { + const toasterSingletonNew2 = new ToasterSingletonNew(); + toasterSingletonNew2.add({ + name: `id-${index++}`, + theme: 'info', + title: 'Hey, toaster!', + content: , + }); +}; + +export const NewSingleton: Story = { + args: {}, + render: () => { + return ( + + + {toasterSingletonNew1.render()} + + ); + }, +};