diff --git a/apps/web-twig-demo/assets/scripts/toast-dynamic.ts b/apps/web-twig-demo/assets/scripts/toast-dynamic.ts new file mode 100644 index 0000000000..bab4eea434 --- /dev/null +++ b/apps/web-twig-demo/assets/scripts/toast-dynamic.ts @@ -0,0 +1,22 @@ +import { Toast } from '@lmc-eu/spirit-web/src/js/index.esm'; + +const addDynamicToast = (event, containerId) => { + const formElement = event.target.closest('form'); + const config = { + color: formElement.querySelector('#toast-color').value, + containerId, + content: formElement.querySelector('#toast-content').value, + hasIcon: formElement.querySelector('#toast-has-icon').checked, + id: `my-dynamic-toast-${Date.now()}`, + isDismissible: formElement.querySelector('#toast-is-dismissible').checked, + }; + + const toast = new Toast(null, config); + toast.show(); + console.log('Created dynamic toast with config:', config); +}; + +// Make it available in the global scope +window.addDynamicToast = addDynamicToast; + +export default addDynamicToast; diff --git a/apps/web-twig-demo/webpack.config.js b/apps/web-twig-demo/webpack.config.js index 7cc9dc1197..0fb34aa36b 100644 --- a/apps/web-twig-demo/webpack.config.js +++ b/apps/web-twig-demo/webpack.config.js @@ -25,6 +25,7 @@ Encore * and one CSS file (e.g. app.css) if your JavaScript imports CSS. */ .addEntry('app', './assets/app.ts') + .addEntry('toastDynamic', './assets/scripts/toast-dynamic.ts') .addEntry('fileUploaderImagePreview', './assets/scripts/file-uploader-image-preview.ts') .addEntry('fileUploaderMetaData', './assets/scripts/file-uploader-meta-data.ts') .addEntry('formValidations', './assets/scripts/form-validations.ts') diff --git a/packages/web-twig/src/Resources/components/Toast/README.md b/packages/web-twig/src/Resources/components/Toast/README.md index 65fcd97226..b57085091a 100644 --- a/packages/web-twig/src/Resources/components/Toast/README.md +++ b/packages/web-twig/src/Resources/components/Toast/README.md @@ -101,27 +101,41 @@ sorted from top to bottom for the `top` vertical alignment, and from bottom to t 👉 Please note the _actual_ order in the DOM is followed when users tab over the interface, no matter the _visual_ order of the toast queue. -#### Toast Queue Limitations +#### Collapsing + +The collapsible Toast queue is turned on by default and can hold up to 3 ToastBar components. +When the queue is full, the oldest ToastBar components are collapsed at the start of +the queue and are only accessible by closing the newer ones. -While the Toast queue becomes scrollable when it does not fit the screen, we recommend displaying only a few toasts at -once for several reasons: +#### Scrolling -⚠️ **We strongly discourage from displaying too many toasts at once as it may cause the page to be unusable, -especially on mobile screens. As of now, there is no automatic stacking of the toast queue items. It is the -responsibility of the developer to ensure that the Toast queue does not overflow the screen.** +By default, the Toast queue collapses when there are more than 3 ToastBars. To turn off this behavior and make the queue scrollable when it does not fit the screen, +set the `isCollapsible` prop to `false`. -⚠️ Please note that scrolling is only available on pointer-equipped devices (mouse, trackpad). Furthermore, scrolling is -only possible when the cursor is placed over the toast message boxes. This way the page content behind the toast -messages can remain accessible. +⚠️ Please note that scrolling is not available on iOS devices due to a limitation in the WebKit engine. 👉 Please note that the initial scroll position is always at the **top** of the queue. +```html + + + +``` + +#### Toast Queue Limitations + +👉 Please note only the _visible_ ToastBar components are scrollable. Collapsed items are not accessible until visible +items are dismissed. + +👉 For the sake of simplicity, the collapsible items limit cannot be configured at the moment. + ### API -| Name | Type | Default | Required | Description | -| ------------ | ----------------------------------------------------------- | -------- | -------- | --------------------------------------- | -| `alignmentX` | [[AlignmentX dictionary][dictionary-alignment] \| `object`] | `center` | ✕ | Horizontal alignment of the toast queue | -| `alignmentY` | [`top` \| `bottom` \| `object`] | `bottom` | ✕ | Vertical alignment of the toast queue | +| Name | Type | Default | Required | Description | +| --------------- | ----------------------------------------------------------- | -------- | -------- | ----------------------------------------------------------------- | +| `alignmentX` | [[AlignmentX dictionary][dictionary-alignment] \| `object`] | `center` | ✕ | Horizontal alignment of the toast queue | +| `alignmentY` | [`top` \| `bottom` \| `object`] | `bottom` | ✕ | Vertical alignment of the toast queue | +| `isCollapsible` | `bool` | `true` | ✕ | If true, Toast queue collapses if there are more than 3 ToastBars | On top of the API options, the components accept [additional attributes][readme-additional-attributes]. If you need more control over the styling of a component, you can use [style props][readme-style-props] @@ -184,7 +198,7 @@ to use the **inverted underlined** variant of the link (for all ToastBar colors) 👉 **Do not put any important actions** like "Undo" in the ToastBar component (unless there are other means to perform said action), as it is very hard (if not impossible) to reach for users with assistive technologies. Read more about -[Toast accessibility](#scott-o-hara-toast) at Scott O'Hara's blog. +[Toast accessibility][scott-o-hara-toast] at Scott O'Hara's blog. ### Colors @@ -199,9 +213,14 @@ For example: ``` -### Opening the ToastBar +### Basic Interactions -Use our JavaScript plugin to open a Toast **that is present in the DOM,** e.g.: +For basic use cases, you can simply place the ToastBar component inside the Toast container and show/hide it using our +JavaScript plugin. + +#### Showing the Static ToastBar + +Use our JavaScript plugin to show a Toast **that is present in the DOM,** e.g.: ```twig ``` @@ -229,12 +248,13 @@ To make the ToastBar dismissible, add the `isDismissible` prop along with a uniq | Name | Type | Default | Required | Description | | --------------- | ------------------------------------------------------------ | ---------- | -------- | -------------------------------------------------------------------- | -| `color` | [[Emotion Color dictionary][dictionary-color] \| `inverted`] | `inverted` | ✕ | Color variant | | `closeLabel` | `string` | `Close` | ✕ | Close label | +| `color` | [[Emotion Color dictionary][dictionary-color] \| `inverted`] | `inverted` | ✕ | Color variant | | `hasIcon` | `bool` | `false` \* | ✕ | If true, an icon is shown along the message | | `iconName` | `string` | `info` \* | ✕ | Name of a custom icon to be shown along the message | | `id` | `string` | — | ✕ | Optional ToastBar ID. Required when `isDismissible` is set to `true` | | `isDismissible` | `bool` | `false` | ✕ | If true, ToastBar can be dismissed by user | +| `isTemplate` | `bool` | `false` | ✕ | If true, ToastBar will be adjusted for rendering inside `