Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(alert): dpo tokens #1905

Merged
merged 13 commits into from
Sep 26, 2024
Merged
6 changes: 6 additions & 0 deletions .changeset/short-maps-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@rhds/elements": minor
---
`<rh-alert>`: added new states: `info`, `neutral`, and `caution`, and deprecated
`note` (now an alias to `info`), `default` (now an alias to `neutral`), and
`error` (now an alias to `danger`).
5 changes: 5 additions & 0 deletions docs/elements/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
import '/assets/javascript/dsd-polyfill.js';
import '@lit-labs/ssr-client/lit-element-hydrate-support.js';
import 'element-internals-polyfill';
// include these, which are often internal to elements, to avoid SSR defer-hydration bugs
import '@rhds/elements/rh-icon/rh-icon.js';
import '@rhds/elements/rh-surface/rh-surface.js';
// load up the demo and picker
import '@rhds/elements/lib/elements/rh-context-picker/rh-context-picker.js';
import '@rhds/elements/lib/elements/rh-context-demo/rh-context-demo.js';
</script>

Expand Down
39 changes: 39 additions & 0 deletions elements/rh-alert/demo/deprecated-states.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<section id="alert-states">
<rh-alert state="error">
<h3 slot="header">Error - alias of Danger</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eleifend elit sed est
egestas, a sollicitudin mauris tincidunt.</p>
<rh-button slot="actions" variant="link" data-action="dismiss">Dismiss</rh-button>
<rh-button slot="actions" variant="link" data-action="confirm">Confirm</rh-button>
</rh-alert>

<rh-alert state="default">
<h3 slot="header">Default - alias of Neutral</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eleifend elit sed est
egestas, a sollicitudin mauris tincidunt.</p>
<rh-button slot="actions" variant="link" data-action="dismiss">Dismiss</rh-button>
<rh-button slot="actions" variant="link" data-action="confirm">Confirm</rh-button>
</rh-alert>

<rh-alert state="note">
<h3 slot="header">Note - alias of Info</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eleifend elit sed est
egestas, a sollicitudin mauris tincidunt.</p>
<rh-button slot="actions" variant="link" data-action="dismiss">Dismiss</rh-button>
<rh-button slot="actions" variant="link" data-action="confirm">Confirm</rh-button>
</rh-alert>
</section>

<style>
#alert-states {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, max(40vh, 40%)));
grid-auto-rows: min-content;
gap: var(--rh-space-lg, 16px);
}
</style>

<script type="module">
import '@rhds/elements/rh-alert/rh-alert.js';
import '@rhds/elements/rh-button/rh-button.js';
</script>
24 changes: 12 additions & 12 deletions elements/rh-alert/demo/states.html
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
<section id="alert-states">
<rh-alert state="default">
<h3 slot="header">Default</h3>
<rh-alert state="danger">
<h3 slot="header">Danger</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eleifend elit sed est
egestas, a sollicitudin mauris tincidunt.</p>
<rh-button slot="actions" variant="link" data-action="dismiss">Dismiss</rh-button>
<rh-button slot="actions" variant="link" data-action="confirm">Confirm</rh-button>
</rh-alert>

<rh-alert state="default">
<h3 slot="header">Default</h3>
<rh-alert state="warning">
<h3 slot="header">Warning</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eleifend elit sed est
egestas, a sollicitudin mauris tincidunt.</p>
<rh-button slot="actions" variant="link" data-action="dismiss">Dismiss</rh-button>
<rh-button slot="actions" variant="link" data-action="confirm">Confirm</rh-button>
</rh-alert>

<rh-alert state="info">
<h3 slot="header">Info</h3>
<rh-alert state="caution">
<h3 slot="header">Caution</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eleifend elit sed est
egestas, a sollicitudin mauris tincidunt.</p>
<rh-button slot="actions" variant="link" data-action="dismiss">Dismiss</rh-button>
<rh-button slot="actions" variant="link" data-action="confirm">Confirm</rh-button>
</rh-alert>

<rh-alert state="success">
<h3 slot="header">Success</h3>
<rh-alert state="neutral">
<h3 slot="header">Neutral</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eleifend elit sed est
egestas, a sollicitudin mauris tincidunt.</p>
<rh-button slot="actions" variant="link" data-action="dismiss">Dismiss</rh-button>
<rh-button slot="actions" variant="link" data-action="confirm">Confirm</rh-button>
</rh-alert>

<rh-alert state="warning">
<h3 slot="header">Warning</h3>
<rh-alert state="info">
<h3 slot="header">Info</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eleifend elit sed est
egestas, a sollicitudin mauris tincidunt.</p>
<rh-button slot="actions" variant="link" data-action="dismiss">Dismiss</rh-button>
<rh-button slot="actions" variant="link" data-action="confirm">Confirm</rh-button>
</rh-alert>

<rh-alert state="danger">
<h3 slot="header">Danger</h3>
<rh-alert state="success">
<h3 slot="header">Success</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eleifend elit sed est
egestas, a sollicitudin mauris tincidunt.</p>
<rh-button slot="actions" variant="link" data-action="dismiss">Dismiss</rh-button>
Expand Down
11 changes: 9 additions & 2 deletions elements/rh-alert/rh-alert.css
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ footer ::slotted(rh-button[variant='link' i]) {
}

#container.info {
--_border-color: var(--rh-color-status-note);
--_border-color: var(--rh-color-status-info);
--_icon-color: var(--rh-color-icon-status-info);
--_header-color: var(--rh-color-status-note);
--_header-color: var(--rh-color-status-info);
--_background-color: var(--rh-color-surface-status-info);
}

Expand All @@ -95,6 +95,13 @@ footer ::slotted(rh-button[variant='link' i]) {
--_background-color: var(--rh-color-surface-status-success);
}

#container.caution {
--_border-color: var(--rh-color-status-caution);
--_icon-color: var(--rh-color-icon-status-caution);
--_header-color: var(--rh-color-status-caution);
--_background-color: var(--rh-color-surface-status-caution);
}

#container.warning {
--_border-color: var(--rh-color-status-warning);
--_icon-color: var(--rh-color-icon-status-warning);
Expand Down
92 changes: 69 additions & 23 deletions elements/rh-alert/rh-alert.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SlotController } from '@patternfly/pfe-core/controllers/slot-controller.js';

import { type CSSResult, LitElement, html, render } from 'lit';
import { type CSSResult, LitElement, html, isServer, render } from 'lit';
import { customElement } from 'lit/decorators/custom-element.js';
import { property } from 'lit/decorators/property.js';
import { repeat } from 'lit/directives/repeat.js';
Expand All @@ -23,12 +23,12 @@ interface ToastOptions {
}

const ICONS = new Map(Object.entries({
default: 'notification-fill',
error: 'error-fill',
neutral: 'notification-fill',
success: 'check-circle-fill',
caution: 'warning-fill',
warning: 'warning-fill',
danger: 'error-fill',
info: 'information-fill',
note: 'information-fill',
}));

export class AlertCloseEvent extends Event {
Expand Down Expand Up @@ -129,20 +129,37 @@ export class RhAlert extends LitElement {
}

private get icon() {
return ICONS.get(this.state.toLowerCase()) ?? '';
const state = this.state.toLowerCase() as this['state'];
switch (state) {
case 'info': return ICONS.get('note');
case 'default': return ICONS.get('neutral');
case 'error': return ICONS.get('danger');
default: return ICONS.get(state);
}
}

/**
* Communicates the urgency of a message and is denoted by various styling configurations.
*
* - `default` - Indicates generic information or a message with no severity.
* - `neutral` - Indicates generic information or a message with no severity.
* - `danger` - Indicates a danger state, like an error that is blocking a user from completing a task.
* - `warning` - Indicates a warning state, like a non-blocking error that might need to be fixed.
* - `caution` - Indicates an action or notice which should immediately draw the attention
* - `info` - Indicates helpful information or a message with very little to no severity.
* - `success` - Indicates a success state, like if a process was completed without errors.
* - `warning` - Indicates a caution state, like a non-blocking error that might need to be fixed.
* - `danger` - Indicates a danger state, like an error that is blocking a user from completing a task.
*/
@property({ reflect: true })
state: 'default' | 'error' | 'success' | 'warning' | 'danger' | 'info' = 'default';
state:
| 'danger'
| 'warning'
| 'caution'
| 'neutral'
| 'info'
| 'success'
| 'note' // deprecated
| 'default' // deprecated
| 'error' = // deprecated
'neutral';

/**
* The alternate Inline alert style includes a border instead of a line which
Expand Down Expand Up @@ -171,27 +188,56 @@ export class RhAlert extends LitElement {
}
}

#aliasState(state: string) {
switch (state.toLowerCase()) {
// the first three are deprecated pre-DPO status names
case 'note': return 'info';
case 'default': return 'neutral';
case 'error': return 'danger';
// the following are DPO-approved status names
case 'danger':
case 'warning':
case 'caution':
case 'neutral':
case 'info':
case 'success':
return state as this['state'];
default:
return 'neutral';
}
}

override connectedCallback() {
super.connectedCallback();
if (!isServer) {
this.requestUpdate();
}
}

render() {
const hasActions = this.#slots.hasSlotted('actions');
const hasBody = this.#slots.hasSlotted(SlotController.default as unknown as string);
const { state, variant = '' } = this;
const _isServer = isServer && !this.hasUpdated;
const hasActions = _isServer || this.#slots.hasSlotted('actions');
const hasBody =
_isServer || this.#slots.hasSlotted(SlotController.default as unknown as string);
const { variant = '' } = this;
const state = this.#aliasState(this.state);
return html`
<rh-surface id="container"
class="${classMap({
hasBody,
on: true,
light: true,
[state]: true,
[variant]: !!variant,
})}"
role="alert"
aria-hidden="false"
color-palette="lightest">
class="${classMap({
hasBody,
on: true,
light: true,
[state]: true,
[variant]: !!variant,
})}"
role="alert"
aria-hidden="false"
color-palette="lightest">
<div id="left-column">
<rh-icon id="icon" set="ui" icon="${this.icon}"></rh-icon>
</div>
<div id="middle-column">
<header ?hidden="${this.#slots.isEmpty('header')}">
<header ?hidden="${!_isServer && this.#slots.isEmpty('header')}">
<div id="header">
<slot name="header"></slot>
</div>${!this.dismissable && this.variant !== 'toast' ? '' : html`
Expand Down
Loading