From 1602d4f20e826a07fdc97e5d5debba7d6e514b9c Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 6 Aug 2023 16:51:50 -0400 Subject: [PATCH 01/13] refactored modalStore to use contexts --- packages/skeleton/src/lib/index.ts | 8 ++- .../src/lib/utilities/Modal/Modal.svelte | 4 +- .../src/lib/utilities/Modal/stores.ts | 26 +++++++++- packages/skeleton/src/lib/utilities/index.ts | 14 +++++ .../components/DocsAppBar/DocsAppBar.svelte | 3 +- .../lib/modals/DocsSearch/DocsSearch.svelte | 3 +- .../modals/examples/ModalExampleEmbed.svelte | 4 +- .../modals/examples/ModalExampleForm.svelte | 3 +- .../modals/examples/ModalExampleImage.svelte | 4 +- .../modals/examples/ModalExampleList.svelte | 3 +- .../(inner)/utilities/modals/+page.svelte | 51 ++++++++++++------- sites/skeleton.dev/src/routes/+layout.svelte | 4 +- .../routes/home-partials/HomeSvelteKit.svelte | 3 +- 13 files changed, 96 insertions(+), 34 deletions(-) create mode 100644 packages/skeleton/src/lib/utilities/index.ts diff --git a/packages/skeleton/src/lib/index.ts b/packages/skeleton/src/lib/index.ts index 4fa8ef8f4..9d20c4dc9 100644 --- a/packages/skeleton/src/lib/index.ts +++ b/packages/skeleton/src/lib/index.ts @@ -13,15 +13,13 @@ export type { PopupSettings } from './utilities/Popup/types.js'; export type { Transition, TransitionParams } from './internal/transitions.js'; export type { CssClasses, SvelteEvent } from './types.js'; -// Stores --- - +// Utilities --- export { storeHighlightJs } from './utilities/CodeBlock/stores.js'; export { storePopup } from './utilities/Popup/popup.js'; export { drawerStore } from './utilities/Drawer/stores.js'; -export { modalStore } from './utilities/Modal/stores.js'; +export { getModalStore } from './utilities/Modal/stores.js'; export { toastStore } from './utilities/Toast/stores.js'; - -// Utilities --- +export { initializeStores } from './utilities/index.js'; // Data Table export { diff --git a/packages/skeleton/src/lib/utilities/Modal/Modal.svelte b/packages/skeleton/src/lib/utilities/Modal/Modal.svelte index fdb6648c8..ad9bdb91e 100644 --- a/packages/skeleton/src/lib/utilities/Modal/Modal.svelte +++ b/packages/skeleton/src/lib/utilities/Modal/Modal.svelte @@ -21,8 +21,8 @@ // Types import type { CssClasses, SvelteEvent } from '../../index.js'; - import { modalStore } from './stores.js'; import { focusTrap } from '../../actions/FocusTrap/focusTrap.js'; + import { getModalStore } from './stores.js'; import type { ModalComponent, ModalSettings } from './types.js'; // Props @@ -116,6 +116,8 @@ let currentComponent: ModalComponent | undefined; let registeredInteractionWithBackdrop = false; + const modalStore = getModalStore(); + // Modal Store Subscription modalStore.subscribe((modals: ModalSettings[]) => { if (!modals.length) return; diff --git a/packages/skeleton/src/lib/utilities/Modal/stores.ts b/packages/skeleton/src/lib/utilities/Modal/stores.ts index aa3d392fe..d1caf9844 100644 --- a/packages/skeleton/src/lib/utilities/Modal/stores.ts +++ b/packages/skeleton/src/lib/utilities/Modal/stores.ts @@ -2,7 +2,31 @@ import { writable } from 'svelte/store'; import type { ModalSettings } from './types.js'; +import { getContext, setContext } from 'svelte'; +const MODAL_STORE_KEY = 'modalStore'; + +/** + * Must be called inside of a `.svelte` file. + */ +export function getModalStore(): ModalStore { + const modalStore = getContext(MODAL_STORE_KEY); + + if (!modalStore) throw new Error('modalStore is not initialized. Please do the following things'); + + return modalStore; +} + +/** + * Initializes the modalStore + */ +export function initializeModalStore(): ModalStore { + const modalStore = modalService(); + + return setContext(MODAL_STORE_KEY, modalStore); +} + +type ModalStore = ReturnType; function modalService() { const { subscribe, set, update } = writable([]); return { @@ -25,5 +49,3 @@ function modalService() { clear: () => set([]) }; } - -export const modalStore = modalService(); diff --git a/packages/skeleton/src/lib/utilities/index.ts b/packages/skeleton/src/lib/utilities/index.ts new file mode 100644 index 000000000..b789be9b2 --- /dev/null +++ b/packages/skeleton/src/lib/utilities/index.ts @@ -0,0 +1,14 @@ +import { initializeModalStore } from './Modal/stores.js'; + +type Opts = { + modal: boolean; + toast: boolean; + drawer: boolean; + popup: boolean; + lightswitch: boolean; +}; +export function initializeStores(opts: Opts = { modal: true, toast: true, drawer: true, popup: true, lightswitch: true }) { + const modalStore = initializeModalStore(); + + return { modalStore }; +} diff --git a/sites/skeleton.dev/src/lib/components/DocsAppBar/DocsAppBar.svelte b/sites/skeleton.dev/src/lib/components/DocsAppBar/DocsAppBar.svelte index a2589f860..aab20de1d 100644 --- a/sites/skeleton.dev/src/lib/components/DocsAppBar/DocsAppBar.svelte +++ b/sites/skeleton.dev/src/lib/components/DocsAppBar/DocsAppBar.svelte @@ -11,7 +11,7 @@ import DocsIcon from '$lib/components/DocsIcon/DocsIcon.svelte'; // Components & Utilities - import { AppBar, LightSwitch, popup, modalStore } from '@skeletonlabs/skeleton'; + import { AppBar, LightSwitch, popup, getModalStore } from '@skeletonlabs/skeleton'; // Stores import { drawerStore } from '@skeletonlabs/skeleton'; @@ -19,6 +19,7 @@ // Local let isOsMac = false; + const modalStore = getModalStore(); // Set Search Keyboard Shortcut if (browser) { diff --git a/sites/skeleton.dev/src/lib/modals/DocsSearch/DocsSearch.svelte b/sites/skeleton.dev/src/lib/modals/DocsSearch/DocsSearch.svelte index aa644417a..17e433264 100644 --- a/sites/skeleton.dev/src/lib/modals/DocsSearch/DocsSearch.svelte +++ b/sites/skeleton.dev/src/lib/modals/DocsSearch/DocsSearch.svelte @@ -1,6 +1,6 @@ diff --git a/sites/skeleton.dev/src/lib/modals/examples/ModalExampleList.svelte b/sites/skeleton.dev/src/lib/modals/examples/ModalExampleList.svelte index e85eb7f4c..65d4f75e6 100644 --- a/sites/skeleton.dev/src/lib/modals/examples/ModalExampleList.svelte +++ b/sites/skeleton.dev/src/lib/modals/examples/ModalExampleList.svelte @@ -1,5 +1,5 @@ diff --git a/sites/skeleton.dev/src/lib/components/DocsSidebar/DocsSidebar.svelte b/sites/skeleton.dev/src/lib/components/DocsSidebar/DocsSidebar.svelte index 5aefb21e9..80f6fe34c 100644 --- a/sites/skeleton.dev/src/lib/components/DocsSidebar/DocsSidebar.svelte +++ b/sites/skeleton.dev/src/lib/components/DocsSidebar/DocsSidebar.svelte @@ -3,11 +3,12 @@ import DocsIcon from '$lib/components/DocsIcon/DocsIcon.svelte'; import { AppRail, AppRailTile, AppRailAnchor } from '@skeletonlabs/skeleton'; - import { drawerStore } from '@skeletonlabs/skeleton'; + import { getDrawerStore } from '@skeletonlabs/skeleton'; import { menuNavLinks } from '$lib/links'; // Local let currentRailCategory: keyof typeof menuNavLinks | undefined = undefined; + const drawerStore = getDrawerStore(); function onClickAnchor(): void { currentRailCategory = undefined; diff --git a/sites/skeleton.dev/src/routes/(inner)/utilities/drawers/+page.svelte b/sites/skeleton.dev/src/routes/(inner)/utilities/drawers/+page.svelte index 2d86c9b41..672fea8e0 100644 --- a/sites/skeleton.dev/src/routes/(inner)/utilities/drawers/+page.svelte +++ b/sites/skeleton.dev/src/routes/(inner)/utilities/drawers/+page.svelte @@ -8,14 +8,15 @@ import sveldDrawer from '@skeletonlabs/skeleton/utilities/Drawer/Drawer.svelte?raw&sveld'; // Drawer Utils - import { drawerStore, type DrawerSettings } from '@skeletonlabs/skeleton'; + import { getDrawerStore, type DrawerSettings } from '@skeletonlabs/skeleton'; + const drawerStore = getDrawerStore(); // Docs Shell const settings: DocsShellSettings = { feature: DocsFeature.Utility, name: 'Drawers', description: 'Displays an overlay panel that attaches to any side of the screen.', - imports: ['Drawer', 'drawerStore'], + imports: ['Drawer', 'getDrawerStore'], types: ['DrawerSettings'], source: 'utilities/Drawer', aria: 'https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/', @@ -79,6 +80,7 @@

Implement a single instance of the drawer component in your app's root layout above the App Shell (if present).

+ \n\n`} />
@@ -96,6 +98,7 @@

Drawer Store

Import this anywhere you wish to control the Drawer. Provides an interface to control the drawer component.

+

Open

Close

@@ -213,16 +216,5 @@ drawerStore.open(settings);

Skeleton does not provide a means to disable the backdrop's click to close feature, as this would be harmful to accessibility. View the ARIA APG guidelines to learn more about modal accessibility.

- - -
-

SvelteKit SSR Warning

-
-
-

There are known security risks when using Svelte writable stores within SvelteKit load functions.

- Details → -
-
-
From 0350fd73d775fab5ad0d450c638068c3364599a6 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 6 Aug 2023 17:55:27 -0400 Subject: [PATCH 06/13] simplify initializer --- packages/skeleton/src/lib/utilities/index.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/skeleton/src/lib/utilities/index.ts b/packages/skeleton/src/lib/utilities/index.ts index b07362137..b66e9579c 100644 --- a/packages/skeleton/src/lib/utilities/index.ts +++ b/packages/skeleton/src/lib/utilities/index.ts @@ -2,14 +2,7 @@ import { initializeModalStore } from './Modal/stores.js'; import { initializeToastStore } from './Toast/stores.js'; import { initializeDrawerStore } from './Drawer/stores.js'; -type Opts = { - modal: boolean; - toast: boolean; - drawer: boolean; - popup: boolean; - lightswitch: boolean; -}; -export function initializeStores(opts: Opts = { modal: true, toast: true, drawer: true, popup: true, lightswitch: true }) { +export function initializeStores() { const modalStore = initializeModalStore(); const toastStore = initializeToastStore(); const drawerStore = initializeDrawerStore(); From 51066e1b887fef7c6f1ac40ae9e8e48bdca72079 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 6 Aug 2023 18:02:13 -0400 Subject: [PATCH 07/13] changeset --- .changeset/kind-sheep-look.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/kind-sheep-look.md diff --git a/.changeset/kind-sheep-look.md b/.changeset/kind-sheep-look.md new file mode 100644 index 000000000..d352ea50f --- /dev/null +++ b/.changeset/kind-sheep-look.md @@ -0,0 +1,5 @@ +--- +"@skeletonlabs/skeleton": major +--- + +breaking: Refactored global stores to use contexts for `Toast`, `Drawer`, and `Modal` utilities From 11fb39f7de14d5420d66a30396ae768b57d3d19f Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 6 Aug 2023 18:14:12 -0400 Subject: [PATCH 08/13] added examples to jsdoc comment --- .../skeleton/src/lib/utilities/Drawer/stores.ts | 16 ++++++++++++++-- .../skeleton/src/lib/utilities/Modal/stores.ts | 16 ++++++++++++++-- .../skeleton/src/lib/utilities/Toast/stores.ts | 16 ++++++++++++++-- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/packages/skeleton/src/lib/utilities/Drawer/stores.ts b/packages/skeleton/src/lib/utilities/Drawer/stores.ts index 2c91400e5..b85a0dfb4 100644 --- a/packages/skeleton/src/lib/utilities/Drawer/stores.ts +++ b/packages/skeleton/src/lib/utilities/Drawer/stores.ts @@ -7,12 +7,24 @@ import type { DrawerSettings } from './types.js'; const DRAWER_STORE_KEY = 'drawerStore'; /** - * Retrieves the `drawerStore`. Must be called inside of a `.svelte` file. + * Retrieves the `drawerStore`. + * + * @example + * ```ts + * import { getDrawerStore } from "@skeletonlabs/skeleton"; + * + * const drawerStore = getDrawerStore(); + * + * drawerStore.open(); + * ``` */ export function getDrawerStore(): DrawerStore { const drawerStore = getContext(DRAWER_STORE_KEY); - if (!drawerStore) throw new Error('drawerStore is not initialized. Please do the following things'); + if (!drawerStore) + throw new Error( + 'drawerStore is not initialized. Please ensure that `initializeStores()` is invoked in the root layout file of this app!' + ); return drawerStore; } diff --git a/packages/skeleton/src/lib/utilities/Modal/stores.ts b/packages/skeleton/src/lib/utilities/Modal/stores.ts index 931ade02d..6cef05caf 100644 --- a/packages/skeleton/src/lib/utilities/Modal/stores.ts +++ b/packages/skeleton/src/lib/utilities/Modal/stores.ts @@ -7,12 +7,24 @@ import type { ModalSettings } from './types.js'; const MODAL_STORE_KEY = 'modalStore'; /** - * Retrieves the `modalStore`. Must be called inside of a `.svelte` file. + * Retrieves the `modalStore`. + * + * @example + * ```ts + * import { getmodalStore } from "@skeletonlabs/skeleton"; + * + * const modalStore = getModalStore(); + * + * modalStore.trigger({ type: "alert", title: "Welcome!" }); + * ``` */ export function getModalStore(): ModalStore { const modalStore = getContext(MODAL_STORE_KEY); - if (!modalStore) throw new Error('modalStore is not initialized. Please do the following things'); + if (!modalStore) + throw new Error( + 'modalStore is not initialized. Please ensure that `initializeStores()` is invoked in the root layout file of this app!' + ); return modalStore; } diff --git a/packages/skeleton/src/lib/utilities/Toast/stores.ts b/packages/skeleton/src/lib/utilities/Toast/stores.ts index ddfb52259..262dc7a74 100644 --- a/packages/skeleton/src/lib/utilities/Toast/stores.ts +++ b/packages/skeleton/src/lib/utilities/Toast/stores.ts @@ -9,12 +9,24 @@ const toastDefaults: ToastSettings = { message: 'Missing Toast Message', autohid const TOAST_STORE_KEY = 'toastStore'; /** - * Retrieves the `toastStore`. Must be called inside of a `.svelte` file. + * Retrieves the `toastStore`. + * + * @example + * ```ts + * import { getToastStore } from "@skeletonlabs/skeleton"; + * + * const toastStore = getToastStore(); + * + * toastStore.open({ message: "Welcome!" }); + * ``` */ export function getToastStore(): ToastStore { const toastStore = getContext(TOAST_STORE_KEY); - if (!toastStore) throw new Error('toastStore is not initialized. Please do the following things'); + if (!toastStore) + throw new Error( + 'toastStore is not initialized. Please ensure that `initializeStores()` is invoked in the root layout file of this app!' + ); return toastStore; } From 38558c6c6bb1248d8af7d963506ed5c700969e57 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 6 Aug 2023 18:19:24 -0400 Subject: [PATCH 09/13] docs for initializer --- packages/skeleton/src/lib/utilities/index.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/skeleton/src/lib/utilities/index.ts b/packages/skeleton/src/lib/utilities/index.ts index b66e9579c..b6b886b35 100644 --- a/packages/skeleton/src/lib/utilities/index.ts +++ b/packages/skeleton/src/lib/utilities/index.ts @@ -2,6 +2,23 @@ import { initializeModalStore } from './Modal/stores.js'; import { initializeToastStore } from './Toast/stores.js'; import { initializeDrawerStore } from './Drawer/stores.js'; +/** + * Used to initialize the stores for the `Modal`, `Toast`, and `Drawer` utilities. + * + * @example + * ```svelte + * + * + * + * + * + * + * ``` + */ export function initializeStores() { const modalStore = initializeModalStore(); const toastStore = initializeToastStore(); From e3756072837e6cc47d5fd3bf46babcea123f20d2 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 6 Aug 2023 18:52:12 -0400 Subject: [PATCH 10/13] fix test --- packages/skeleton/src/lib/utilities/Modal/Modal.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/skeleton/src/lib/utilities/Modal/Modal.test.ts b/packages/skeleton/src/lib/utilities/Modal/Modal.test.ts index a06d570b2..70a0659a4 100644 --- a/packages/skeleton/src/lib/utilities/Modal/Modal.test.ts +++ b/packages/skeleton/src/lib/utilities/Modal/Modal.test.ts @@ -1,7 +1,7 @@ import { render } from '@testing-library/svelte'; import { describe, it, expect } from 'vitest'; -import { modalStore } from '$lib/utilities/Modal/stores.js'; +import { getModalStore } from '$lib/utilities/Modal/stores.js'; import type { ModalSettings } from '$lib/utilities/Modal/types.js'; import Modal from '$lib/utilities/Modal/Modal.svelte'; @@ -27,6 +27,8 @@ const modalPrompt: ModalSettings = { }; describe('Modal.svelte', () => { + const modalStore = getModalStore(); + it('Renders modal alert', async () => { modalStore.trigger(modalAlert); const { getByTestId } = render(Modal); From d865a86cf4f005845bb40ff636110195ae8cc7e9 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 6 Aug 2023 18:52:57 -0400 Subject: [PATCH 11/13] update store --- .../src/routes/(inner)/components/input-chips/+page.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sites/skeleton.dev/src/routes/(inner)/components/input-chips/+page.svelte b/sites/skeleton.dev/src/routes/(inner)/components/input-chips/+page.svelte index d25169bd0..232fe3c88 100644 --- a/sites/skeleton.dev/src/routes/(inner)/components/input-chips/+page.svelte +++ b/sites/skeleton.dev/src/routes/(inner)/components/input-chips/+page.svelte @@ -3,7 +3,7 @@ import { DocsFeature, type DocsShellSettings } from '$lib/layouts/DocsShell/types'; import DocsPreview from '$lib/components/DocsPreview/DocsPreview.svelte'; // Components - import { CodeBlock, InputChip, toastStore } from '@skeletonlabs/skeleton'; + import { CodeBlock, InputChip, getToastStore } from '@skeletonlabs/skeleton'; // Sveld import sveldInputChip from '@skeletonlabs/skeleton/components/InputChip/InputChip.svelte?raw&sveld'; @@ -30,6 +30,7 @@ let emails = ['john@email.com', 'jane@email.com', 'sally@email.com']; let musicalGenres = ['rock', 'r&b', 'pop']; let musicalGenresWhitelist = ['rock', 'pop', 'hip-hop', 'metal', 'techno', 'r&b']; + const toastStore = getToastStore(); function isValidEmail(value: string): boolean { return value.includes('@') && value.includes('.'); From 0907f39d37f3582fd9a2b1ec61fa410bdd805a91 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Mon, 7 Aug 2023 13:03:40 -0400 Subject: [PATCH 12/13] store initializer now returns void --- packages/skeleton/src/lib/utilities/index.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/skeleton/src/lib/utilities/index.ts b/packages/skeleton/src/lib/utilities/index.ts index b6b886b35..588ef050b 100644 --- a/packages/skeleton/src/lib/utilities/index.ts +++ b/packages/skeleton/src/lib/utilities/index.ts @@ -20,9 +20,7 @@ import { initializeDrawerStore } from './Drawer/stores.js'; * ``` */ export function initializeStores() { - const modalStore = initializeModalStore(); - const toastStore = initializeToastStore(); - const drawerStore = initializeDrawerStore(); - - return { drawerStore, modalStore, toastStore }; + initializeModalStore(); + initializeToastStore(); + initializeDrawerStore(); } From 2eea63b3ad7cbfc11db512181bd84cf5d4d201ed Mon Sep 17 00:00:00 2001 From: endigo9740 Date: Wed, 9 Aug 2023 12:51:54 -0500 Subject: [PATCH 13/13] Minor doc edit for Drawer, Modal, Toast instruction --- .../(inner)/utilities/drawers/+page.svelte | 7 ++++++- .../(inner)/utilities/modals/+page.svelte | 17 +++++++---------- .../(inner)/utilities/toasts/+page.svelte | 8 +++++--- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/sites/skeleton.dev/src/routes/(inner)/utilities/drawers/+page.svelte b/sites/skeleton.dev/src/routes/(inner)/utilities/drawers/+page.svelte index 672fea8e0..735758282 100644 --- a/sites/skeleton.dev/src/routes/(inner)/utilities/drawers/+page.svelte +++ b/sites/skeleton.dev/src/routes/(inner)/utilities/drawers/+page.svelte @@ -79,9 +79,14 @@ -

Implement a single instance of the drawer component in your app's root layout above the App Shell (if present).

+ +

+ Implement the following in the root layout of your application. This is required only once when implementing Skeleton's Drawer, Modal, or Toast features, and will prevent known issues with SvelteKit SSR. +

+

Implement a single instance of the drawer component in your app's root layout, above the App Shell (if present).

\n\n`} /> +

We'll cover triggering this feature on-demand in the documentation below.

diff --git a/sites/skeleton.dev/src/routes/(inner)/utilities/modals/+page.svelte b/sites/skeleton.dev/src/routes/(inner)/utilities/modals/+page.svelte index e1a97b83e..c54355004 100644 --- a/sites/skeleton.dev/src/routes/(inner)/utilities/modals/+page.svelte +++ b/sites/skeleton.dev/src/routes/(inner)/utilities/modals/+page.svelte @@ -149,7 +149,10 @@ -

In your app's root layout, import the Modal component and the store initializer function.

+ +

+ Implement the following in the root layout of your application. This is required only once when implementing Skeleton's Drawer, Modal, or Toast features, and will prevent known issues with SvelteKit SSR. +

-

Add a single instance of the Modal component above the App Shell (if present).

- - - -`} - /> +

Implement a single instance of the modal component in your app's root layout, above the App Shell (if present).

+ \n\n`} /> +

We'll cover triggering this feature on-demand in the documentation below.

diff --git a/sites/skeleton.dev/src/routes/(inner)/utilities/toasts/+page.svelte b/sites/skeleton.dev/src/routes/(inner)/utilities/toasts/+page.svelte index 48b8c48d4..8fb449943 100644 --- a/sites/skeleton.dev/src/routes/(inner)/utilities/toasts/+page.svelte +++ b/sites/skeleton.dev/src/routes/(inner)/utilities/toasts/+page.svelte @@ -141,12 +141,14 @@ +

- Import and add a single instance of the Toast component in your app's root layout. Since this is in global scope it will be - possible to reuse this feature throughout your entire application. + Implement the following in the root layout of your application. This is required only once when implementing Skeleton's Drawer, Modal, or Toast features, and will prevent known issues with SvelteKit SSR.

- `} /> +

Implement a single instance of the toast component in your app's root layout, above the App Shell (if present).

+ \n\n`} /> +

We'll cover triggering this feature on-demand in the documentation below.