diff --git a/packages/web-react/src/components/Toast/__tests__/ToastBarLink.test.tsx b/packages/web-react/src/components/Toast/__tests__/ToastBarLink.test.tsx
index 118033bac1..4053bcf35c 100644
--- a/packages/web-react/src/components/Toast/__tests__/ToastBarLink.test.tsx
+++ b/packages/web-react/src/components/Toast/__tests__/ToastBarLink.test.tsx
@@ -11,14 +11,14 @@ describe('ToastBarLink', () => {
restPropsTest(ToastBarLink, 'a');
beforeEach(() => {
- render(Example action );
+ render(Example action );
});
it('should render with correct href', () => {
const element = screen.getByRole('link');
expect(element).toBeInTheDocument();
- expect(element).toHaveAttribute('href', 'example-href');
+ expect(element).toHaveAttribute('href', '#example-href');
});
it('should render children', () => {
diff --git a/packages/web/src/js/Toast.ts b/packages/web/src/js/Toast.ts
index 0527fcabfe..66d9d8916b 100644
--- a/packages/web/src/js/Toast.ts
+++ b/packages/web/src/js/Toast.ts
@@ -40,6 +40,7 @@ const SELECTOR_ICON_ELEMENT = `[${ATTRIBUTE_DATA_POPULATE_FIELD}="icon"]`;
const SELECTOR_CLOSE_BUTTON_ELEMENT = `[${ATTRIBUTE_DATA_POPULATE_FIELD}="close-button"]`;
const SELECTOR_DISMISS_TRIGGER_ELEMENT = `[${ATTRIBUTE_DATA_DISMISS}="${NAME}"]`;
const SELECTOR_MESSAGE_ELEMENT = `[${ATTRIBUTE_DATA_POPULATE_FIELD}="message"]`;
+const SELECTOR_LINK_ELEMENT = `[${ATTRIBUTE_DATA_POPULATE_FIELD}="link"]`;
// Keep in sync with transitions in `scss/Toast/_theme.scss`.
export const PROPERTY_NAME_SLOWEST_TRANSITION = {
@@ -54,8 +55,9 @@ type Config = {
autoCloseInterval: number;
color: Color;
containerId: string;
- content: HTMLElement | string;
enableAutoClose: boolean;
+ message: HTMLElement | string;
+ link: HTMLElement | string;
hasIcon: boolean;
iconName: string;
id: string;
@@ -180,8 +182,8 @@ class Toast extends BaseComponent {
}
const config = this.config as Config;
- if (!config.content) {
- warning(false, 'Toast content is required, nothing given.');
+ if (!config.message) {
+ warning(false, 'Toast message is required, nothing given.');
return null;
}
@@ -190,6 +192,7 @@ class Toast extends BaseComponent {
const iconElement = template.querySelector(SELECTOR_ICON_ELEMENT) as HTMLElement;
const closeButtonElement = template.querySelector(SELECTOR_CLOSE_BUTTON_ELEMENT) as HTMLElement;
const messageElement = template.querySelector(SELECTOR_MESSAGE_ELEMENT) as HTMLElement;
+ const linkElement = template.querySelector(SELECTOR_LINK_ELEMENT) as HTMLElement;
itemElement!.setAttribute('id', config.id);
itemElement!.setAttribute('data-spirit-color', config.color);
@@ -197,7 +200,10 @@ class Toast extends BaseComponent {
this.updateOrRemoveIcon(iconElement);
this.updateOrRemoveCloseButton(closeButtonElement);
- messageElement!.innerHTML = typeof config.content === 'string' ? config.content : config.content.outerHTML;
+ messageElement!.innerHTML = typeof config.message === 'string' ? config.message : config.message.outerHTML;
+
+ linkElement!.setAttribute('href', '#');
+ linkElement!.innerHTML = typeof config.link === 'string' ? config.link : config.link.outerHTML;
return itemElement;
}
diff --git a/packages/web/src/scss/components/Toast/README.md b/packages/web/src/scss/components/Toast/README.md
index d3f5b20769..4b98bcf4e0 100644
--- a/packages/web/src/scss/components/Toast/README.md
+++ b/packages/web/src/scss/components/Toast/README.md
@@ -6,6 +6,8 @@ Toast is a composition of a few subcomponents:
- [Toast](#toast)
- [ToastBar](#toastbar)
+ - [ToastBarMessage](#toastbarmessage)
+ - [ToastBarLink](#toastbarlink)
## JavaScript Plugin
@@ -164,8 +166,10 @@ Minimum example:
```html
@@ -178,41 +182,43 @@ An icon can be added to the ToastBar component:
```html
```
-### Action Link
+### ToastBar Components
+
+The content of `ToastBar` can be assembled from the following subcomponents:
+
+#### ToastBarMessage
-An action link can be added to the ToastBar component:
+`ToastBarMessage` is a subcomponent designated for the main message in `ToastBar`.
+
+Usage example:
```html
-
Message with action
+
Message with action
```
-#### API
-
-| Name | Type | Default | Required | Description |
-| ---------- | -------- | ------- | -------- | ------------------------------ |
-| `children` | `string` | — | ✓ | Content of the ToastBarMessage |
-
#### ToastBarLink
-`ToastBarLink` is a component designated to create an action link within `ToastBar`.
+`ToastBarLink` is a subcomponent designated to create an action link within `ToastBar`.
Usage example:
@@ -221,7 +227,7 @@ Usage example:
-
Message with action
+
Message with action
Action
@@ -229,16 +235,6 @@ Usage example:
```
-#### API
-
-| Name | Type | Default | Required | Description |
-| -------------- | ------------------------------------------------ | ---------- | -------- | ------------------------------ |
-| `children` | `string` | — | ✓ | Content of the ToastBarLink |
-| `color` | [Action Link Color dictionary][dictionary-color] | `inverted` | ✕ | Color of the link |
-| `href` | `string` | — | ✕ | ToastBarLink's href attribute |
-| `isDisabled` | `bool` | `false` | ✕ | Whether is the link disabled |
-| `isUnderlined` | `bool` | `true` | ✕ | Whether is the link underlined |
-
👉 **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.
@@ -253,8 +249,10 @@ For example:
```html
@@ -290,7 +288,7 @@ button:
```html
-
+
-
+
-
-
+
svg:first-child) {
+.ToastBar__container:has(> svg:first-child) {
display: grid;
grid-template-columns: auto 1fr;
column-gap: theme.$bar-content-gap;
}
-.ToastBar:is(.ToastBar--dismissible, :has([data-spirit-dismiss='toast'])) .ToastBar__content {
+.ToastBar:is(.ToastBar--dismissible, :has([data-spirit-dismiss='toast'])) .ToastBar__container {
align-self: center; // 4.
}
-.ToastBar__container {
+.ToastBar__content {
@include typography.generate(theme.$bar-typography);
display: flex;
@@ -66,14 +66,12 @@
gap: theme.$bar-message-gap-y theme.$bar-message-gap-x;
}
-.ToastBar__container > :is(a, button):last-child {
+.ToastBar__link {
font-weight: 400;
}
// stylelint-disable-next-line selector-max-specificity -- Specificity is needed to precisely target the action.
-.ToastBar:is(.ToastBar--dismissible, :has([data-spirit-dismiss='toast']))
- .ToastBar__container
- > :is(a, button):last-child {
+.ToastBar:is(.ToastBar--dismissible, :has([data-spirit-dismiss='toast'])) .ToastBar__link {
margin-inline-end: theme.$bar-action-margin-inline-end; // 6.
}
diff --git a/packages/web/src/scss/components/Toast/dynamic-toast.mjs b/packages/web/src/scss/components/Toast/dynamic-toast.mjs
index 773fc621b8..b0d0a1ba4f 100644
--- a/packages/web/src/scss/components/Toast/dynamic-toast.mjs
+++ b/packages/web/src/scss/components/Toast/dynamic-toast.mjs
@@ -6,8 +6,9 @@ export const addDynamicToast = (event, containerId) => {
containerId,
autoCloseInterval: formElement.querySelector('#toast-auto-close-interval').value,
color: formElement.querySelector('#toast-color').value,
- content: formElement.querySelector('#toast-content').value,
enableAutoClose: formElement.querySelector('#toast-enable-auto-close').checked,
+ message: formElement.querySelector('#toast-message').value,
+ link: formElement.querySelector('#toast-link').value,
hasIcon: formElement.querySelector('#toast-has-icon').checked,
id: `my-dynamic-toast-${Date.now()}`,
isDismissible: formElement.querySelector('#toast-is-dismissible').checked,
diff --git a/packages/web/src/scss/components/Toast/index.html b/packages/web/src/scss/components/Toast/index.html
index 0de0ff5e08..4fe7897c1c 100644
--- a/packages/web/src/scss/components/Toast/index.html
+++ b/packages/web/src/scss/components/Toast/index.html
@@ -26,12 +26,12 @@ Static Toast
-
+
-
- I was hidden and you exposed me!
+
+
I was hidden and you exposed me!
Dynamic Toast Queue
-
Message
-
+
Message
+
+
Can contain HTML.
+
+
+
Link
+
Can contain HTML.
@@ -245,11 +250,14 @@
Dynamic Toast Queue