Skip to content

Commit

Permalink
fix(toast): adds iconLabel to address accessibility (#4944)
Browse files Browse the repository at this point in the history
  • Loading branch information
caseyisonit authored Nov 22, 2024
1 parent b5ba59f commit 8121057
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 19 deletions.
2 changes: 1 addition & 1 deletion packages/icon/src/IconBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class IconBase extends SpectrumElement {
@state()
public spectrumVersion = 1;

@property()
@property({ reflect: true })
public label = '';

@property({ reflect: true })
Expand Down
65 changes: 52 additions & 13 deletions packages/toast/src/Toast.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2020 Adobe. All rights reserved.
Copyright 2024 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Expand Down Expand Up @@ -56,20 +56,32 @@ export class Toast extends FocusVisiblePolyfillMixin(SpectrumElement) {
return [toastStyles];
}

/**
* The `open` property indicates whether the toast is visible or hidden.
*
* @param {Boolean} open
*/
@property({ type: Boolean, reflect: true })
public open = false;

/**
* When a timeout is provided it represents the number of milliseconds from when
* When a timeout is provided, it represents the number of milliseconds from when
* the Toast was placed on the page before it will automatically dismiss itself.
*
* Accessibility concerns require that a Toast is available for at least 6000ms
* before being dismissed, so any timeout of less than 6000ms will be raised to
* that baseline. It is suggested that messages longer than 120 words should
* receive another 1000ms in their timeout for each additional 120 words in the
* message. E.G. 240 words = 7000ms, 360 words = 8000ms, etc.
* that baseline.
*
* It is suggested that messages longer than 120 words should receive an additional
* 1000ms in their timeout for each additional 120 words in the message.
*
* @param {Number} timeout
* For example, a message with 240 words should have a timeout of 7000ms,
* and a message with 360 words should have a timeout of 8000ms.
*
* @param {Number | null} timeout
* @default null
*/
//TODO(#4939): Align on the timeout minimum with design
@property({ type: Number })
public set timeout(timeout: number | null) {
const hasTimeout = typeof timeout !== null && (timeout as number) > 0;
Expand All @@ -88,10 +100,13 @@ export class Toast extends FocusVisiblePolyfillMixin(SpectrumElement) {
return this._timeout;
}

public _timeout: number | null = null;
private _timeout: number | null = null;

/**
* The variant applies specific styling when set to `negative`, `positive`, `info`, `error`, or `warning`.
*
* The variants `error` and `warning` are deprecated and should be replaced with `negative`.
*
* `variant` attribute is removed when not matching one of the above.
*
* @param {String} variant
Expand All @@ -102,6 +117,8 @@ export class Toast extends FocusVisiblePolyfillMixin(SpectrumElement) {
return;
}
const oldValue = this.variant;

// validate the variant is one of the allowed values else remove the attribute
if (toastVariants.includes(variant)) {
this.setAttribute('variant', variant);
this._variant = variant;
Expand All @@ -118,26 +135,48 @@ export class Toast extends FocusVisiblePolyfillMixin(SpectrumElement) {

private _variant: ToastVariants = '';

private renderIcon(variant: string): TemplateResult {
/**
* The `iconLabel` property is used to set the `label` attribute on the icon element. This is used to provide a text alternative for the icon to ensure accessibility.
*
* If the `iconLabel` property is not set, the icon will use the `variant` to dynamically set the `label`.
*
* @param {String} iconLabel
*/
@property({ type: String, attribute: 'icon-label' })
public iconLabel?: string;

//TODO(#4931): Address the deprecated variants or remove the flags
private renderIcon(
variant: ToastVariants,
iconLabel?: string
): TemplateResult {
switch (variant) {
case 'info':
return html`
<sp-icon-info
label="Information"
label=${iconLabel || 'Information'}
class="type"
></sp-icon-info>
`;
case 'negative':
case 'error': // deprecated
return html`
<sp-icon-alert
label=${iconLabel || 'Error'}
class="type"
></sp-icon-alert>
`;
case 'warning': // deprecated
return html`
<sp-icon-alert label="Error" class="type"></sp-icon-alert>
<sp-icon-alert
label=${iconLabel || 'Warning'}
class="type"
></sp-icon-alert>
`;
case 'positive':
case 'success': // deprecated
return html`
<sp-icon-checkmark-circle
label="Success"
label=${iconLabel || 'Success'}
class="type"
></sp-icon-checkmark-circle>
`;
Expand Down Expand Up @@ -205,7 +244,7 @@ export class Toast extends FocusVisiblePolyfillMixin(SpectrumElement) {

protected override render(): TemplateResult {
return html`
${this.renderIcon(this.variant)}
${this.renderIcon(this.variant, this.iconLabel)}
<div class="body" role="alert">
<div class="content">
<slot></slot>
Expand Down
24 changes: 24 additions & 0 deletions packages/toast/src/toast.css
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,27 @@ governing permissions and limitations under the License.
transition-delay: 0s;
visibility: visible;
}

:host([variant='error']),
:host([variant='warning']) {
background-color: var(
--highcontrast-toast-negative-background-color-default,
var(
--mod-toast-negative-background-color-default,
var(--spectrum-toast-negative-background-color-default)
)
);
}

:host([variant='negative']),
:host([variant='negative']) .closeButton:focus-visible:not(:active),
:host([variant='warning']),
:host([variant='warning']) .closeButton:focus-visible:not(:active) {
color: var(
--highcontrast-toast-negative-background-color-default,
var(
--mod-toast-negative-background-color-default,
var(--spectrum-toast-negative-background-color-default)
)
);
}
42 changes: 37 additions & 5 deletions packages/toast/stories/toast.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ const toast = ({
variant = '',
open = true,
content = '',
timeout = 0,
iconLabel = '',
}): TemplateResult => html`
<sp-toast
variant=${variant as
Expand All @@ -33,6 +35,8 @@ const toast = ({
| 'error'
| 'warning'}
?open=${open}
timeout=${ifDefined(timeout)}
.iconLabel=${iconLabel}
>
${content}
<sp-button
Expand Down Expand Up @@ -61,18 +65,40 @@ export default {
type: { summary: 'string' },
defaultValue: { summary: '' },
},
control: 'text',
},
open: {
name: 'open',
type: { name: 'boolean', required: false },
description: 'Whether the toast is open.',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: false },
},
},
variant: {
name: 'variant',
options: ['', 'negative', 'positive', 'info', 'error', 'warning'],
table: {
type: { summary: 'string' },
defaultValue: { summary: '' },
},
control: {
type: 'boolean',
type: 'select',
},
},
timeout: {
name: 'timeout',
type: { name: 'number', required: false },
table: {
type: { summary: 'number' },
defaultValue: { summary: null },
},
},
iconLabel: {
name: 'iconLabel',
type: { name: 'string', required: false },
table: {
type: { summary: 'string' },
defaultValue: { summary: '' },
},
},
},
Expand All @@ -82,23 +108,29 @@ interface Properties {
variant: '' | 'negative' | 'positive' | 'info' | 'error' | 'warning';
open: boolean;
content: string;
timeout: number;
iconLabel: string;
onClose: (event: Event) => void;
}

export const Default = ({
variant,
open,
content,
timeout,
iconLabel,
}: Properties): TemplateResult => {
return toast({ variant, open, content });
return toast({ variant, open, content, timeout, iconLabel });
};

const variantDemo = ({
variant,
open,
content,
timeout,
iconLabel,
}: Properties): TemplateResult => {
return toast({ variant, open, content });
return toast({ variant, open, content, timeout, iconLabel });
};

export const Positive = (args: Properties): TemplateResult =>
Expand Down

0 comments on commit 8121057

Please sign in to comment.