Skip to content

Commit

Permalink
fixup! Feat(web-twig): Make Toast work with dynamic collapsible queue…
Browse files Browse the repository at this point in the history
… and dynamic ToastBars #DS-1223
  • Loading branch information
crishpeen committed Apr 30, 2024
1 parent 2ac4bf2 commit 87a55f2
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 74 deletions.
30 changes: 17 additions & 13 deletions packages/web-twig/src/Resources/components/Icon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,36 @@ Without lexer:
}} %}{% endembed %}
```

## Render as symbol
## Render as Symbol

If you need to prerender the icon as a symbol, you can use the `isSymbol` prop:
If you need to prerender the icon as a [symbol][mdn-symbol], you can use the `isSymbol` prop:

```html
<Icon name="warning" isSymbol />
```

The ID of the symbol will be the same as the `name` prop and the whole element will be hidden.
The ID of the symbol will be the same as the `name` prop and the whole SVG element will be hidden.

👉 Even though the `svg` only includes the `symbol` element, the `svg` still takes some space in browser,
so you might want to hide it using either wrapping element with `hidden` attribute or use CSS.

## API

| Name | Type | Default | Required | Description |
| ------------ | -------- | ------- | -------- | ------------------------------------------------------------------------------------ |
| `ariaHidden` | `bool` | `true` || If true, icon is hidden from a11y API |
| `boxSize` | `number` | `24` || Size of the icon |
| `isReusable` | `bool` | `true` || Enables reusability of SVG icons |
| `isSymbol` | `bool` | `false` || If the element should be rendered as a symbol with the name used in the ID attribute |
| `name` | `string` ||| Name of the icon, case sensitive |
| `title` | `string` | `null` || Optional title to display on hover |
| Name | Type | Default | Required | Description |
| ------------ | -------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `ariaHidden` | `bool` | `true` || If true, icon is hidden from a11y API |
| `boxSize` | `number` | `24` || Size of the icon |
| `isReusable` | `bool` | `true` || Enables reusability of SVG icons |
| `isSymbol` | `bool` | `false` || If true, the element will be rendered as SVG symbol with the name assigned to the ID attribute, other not needed props are skipped |
| `name` | `string` ||| Name of the icon, case sensitive |
| `title` | `string` | `null` || Optional title to display on hover |

Get the list of `name` options in the [Icon package][icon-package] or your source of icons.

Also, UNSAFE styling props are available, see the [Escape hatches][escape-hatches]
section in README to learn how and when to use them.

[inlinesvg-docs]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web-twig/docs/inlineSVG.md
[icon-package]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/icons
[escape-hatches]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web-twig/README.md#escape-hatches
[icon-package]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/icons
[inlinesvg-docs]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web-twig/docs/inlineSVG.md
[mdn-symbol]: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Icon name="warning" />
<Icon name="warning" title="This is warning!" />
<Icon name="warning" title="This is warning!" boxSize="32" />
<Icon name="info" title="This is info!" boxSize="64" isSymbol />
<Icon name="info" title="This is info!" isSymbol />
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</path>
<title>
This is warning!
</title></svg> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
</title></svg> <svg xmlns="http://www.w3.org/2000/svg">
<symbol id="info" viewbox="0 0 24 24">
<path d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM13 17H11V11H13V17ZM13 9H11V7H13V9Z" fill="currentColor">
</path>
Expand Down
55 changes: 30 additions & 25 deletions packages/web-twig/src/Resources/components/Toast/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,15 @@ 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.

#### 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.

#### Scrolling

By default, the Toast queue collapsed if there is more ToastBars. To make it scrollable when it does not fit 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 not available on iOS devices due to a limitation in the WebKit engine.
Expand All @@ -116,12 +122,6 @@ set the `isCollapsible` prop to `false`.
</Toast>
```

#### 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.

#### Toast Queue Limitations

👉 Please note only the _visible_ ToastBar components are scrollable. Collapsed items are not accessible until visible
Expand All @@ -131,11 +131,11 @@ items are dismissed.

### 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 |
| `isCollapsible` | `bool` | `true` || If true, Toast Queue would collapse if two many ToastBars shown |
| 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]
Expand Down Expand Up @@ -254,7 +254,7 @@ To make the ToastBar dismissible, add the `isDismissible` prop along with a uniq
| `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 render to be used inside the `<template>` |
| `isTemplate` | `bool` | `false` || If true, ToastBar will be adjusted for rendering inside `<template>` |
| `isOpen` | `bool` | `true` || If true, ToastBar is visible |

(\*) For each emotion color, a default icon is defined.
Expand All @@ -279,23 +279,26 @@ and [escape hatches][readme-escape-hatches].
### Creating Dynamic ToastBars

To create ToastBar components dynamically, make sure to add the ToastBar template inside the [`<template>`][mdn-template] tag.
The `<template>` tag must be inserted anywhere inside the Toast container. Our JavaScript Toast plugin will then pick up
The `<template>` tag must be inserted anywhere inside the Toast container. Our [JavaScript Toast plugin][web-toast-js-plugin] will then pick up
the template and apply it on any toasts to be shown to the user, using the configuration provided.
The template `ToastBar` has to have the `isTemplate` prop set.

⚠️ In order to make the dynamic ToastBar icons work, you need to include the SVG sprites in your project. You
can use the `Icon` component with `isSymbol` prop. Otherwise, the icons will not be displayed as the JS plugin
does not render the icons by itself, it just sets the `use` tag with the correct `xlink:href` attribute.
Also, do not forget to set the `hidden` attribute on the wrapping element to hide the icons from the screen.

```twig
<Icon name="check-plain" isSymbol />
<Icon name="danger" isSymbol />
<Icon name="info" isSymbol />
<Icon name="warning" isSymbol />
<div hidden>
<Icon name="check-plain" isSymbol />
<Icon name="danger" isSymbol />
<Icon name="info" isSymbol />
<Icon name="warning" isSymbol />
</div>
<Toast id="toast-example">
<template data-spirit-snippet="item">
<ToastBar color="inverted" id="template-toast" isTemplate hasIcon isDismissible isOpen="{{ false }}" />
<ToastBar color="inverted" id="template-toast" isTemplate hasIcon isDismissible isOpen={ false } />
</template>
</Toast>
```
Expand Down Expand Up @@ -332,15 +335,17 @@ Or feel free to write controlling scripts yourself.

👉 Check the [component's docs in the web package][web-js-api] to see the full documentation and API of the plugin.

[web-toast]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web/src/scss/components/Toast
[web-readme]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/README.md
[web-js-api]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/src/scss/components/Toast/README.md#javascript-api
[mdn-role-log]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/log_role
[mdn-aria-live]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-live
[dictionary-alignment]: https://github.com/lmc-eu/spirit-design-system/blob/main/docs/DICTIONARIES.md#alignment
[dictionary-color]: https://github.com/lmc-eu/spirit-design-system/blob/main/docs/DICTIONARIES.md#color
[icon-package]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/icons
[mdn-aria-live]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-live
[mdn-role-log]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/log_role
[mdn-template]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template
[readme-additional-attributes]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-twig/README.md#additional-attributes
[readme-escape-hatches]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-twig/README.md#escape-hatches
[readme-style-props]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-twig/README.md#style-props
[scott-o-hara-toast]: https://www.scottohara.me/blog/2019/07/08/a-toast-to-a11y-toasts.html
[icon-package]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/icons
[web-js-api]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/src/scss/components/Toast/README.md#javascript-api
[web-readme]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/README.md
[web-toast-js-plugin]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web/src/scss/components/Toast#javascript-plugin-api
[web-toast]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web/src/scss/components/Toast
16 changes: 8 additions & 8 deletions packages/web-twig/src/Resources/components/Toast/ToastBar.twig
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@
>
<div class="{{ _boxClassName }}">
<div class="{{ _contentClassName }}">
{% if (_hasIcon or _iconName) and _isTemplate is same as(true) %}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" aria-hidden="true" data-spirit-populate-field="icon">
<use xlink:href="#" />
</svg>
{% else %}
{% if _hasIcon or _iconName %}
<Icon boxSize="20" name="{{ _iconNameValue }}" isReusable="{{ false }}" />
{% if _hasIcon or _iconName %}
{% if _isTemplate %}
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true" data-spirit-populate-field="icon">
<use xlink:href="#" />
</svg>
{% else %}
<Icon boxSize="20" name="{{ _iconNameValue }}" isReusable={ false } />
{% endif %}
{% endif %}
<div class="{{ _messageClassName }}" data-spirit-populate-field="message">
Expand All @@ -68,7 +68,7 @@
size="small"
isSquare
>
<Icon isReusable="{{ false }}" name="close" />
<Icon isReusable={ false } name="close" />
<VisuallyHidden>{{ _closeLabel }}</VisuallyHidden>
</Button>
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
</ToastBar>

<!-- Render in success color with matching icon and close button -->
<ToastBar color="success" isDismissible>
<ToastBar color="success" id="toast-dismiss" isDismissible>
Dismissible message with success color
</ToastBar>

<!-- Render as template -->
<ToastBar color="inverted" id="template-toast" isTemplate hasIcon isDismissible isOpen="{{ false }}" />
<ToastBar isTemplate />

<!-- Render as template with props -->
<ToastBar color="inverted" id="template-toast" isTemplate hasIcon isDismissible isOpen={ false } />

<!-- Render with all props -->
<ToastBar
Expand All @@ -26,7 +29,24 @@
id="my-toast"
iconName="download"
isDismissible
isOpen="{{ false }}"
isOpen={ false }
UNSAFE_className="custom-class"
UNSAFE_style="outline: 5px solid blue; outline-offset: -5px;"
>
Dismissible message with custom icon and action
<Link href="#" color="inverted" isUnderlined>Action</Link>
</ToastBar>

<!-- Render as template with all props -->
<ToastBar
color="success"
closeLabel="Dismiss"
hasIcon
id="my-toast-template"
iconName="download"
isDismissible
isOpen={ false }
isTemplate
UNSAFE_className="custom-class"
UNSAFE_style="outline: 5px solid blue; outline-offset: -5px;"
>
Expand Down

0 comments on commit 87a55f2

Please sign in to comment.