Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions config/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ const entries: Array<Entry> = [
path: "src/components/usa-banner/index.ts",
sizeLimit: "10 kB",
},
{
name: "components/usa-alert",
path: "src/components/usa-alert/index.ts",
sizeLimit: "3 kB",
},
{
name: "components/usa-link",
path: "src/components/usa-link/index.js",
Expand Down
230 changes: 230 additions & 0 deletions custom-elements.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
"path": "src/components/index.ts",
"declarations": [],
"exports": [
{
"kind": "js",
"name": "UsaAlert",
"declaration": {
"name": "UsaAlert",
"module": "src/components/index.ts"
}
},
{
"kind": "js",
"name": "UsaLink",
Expand All @@ -25,6 +33,228 @@
}
]
},
{
"kind": "javascript-module",
"path": "src/components/usa-alert/index.ts",
"declarations": [
{
"kind": "class",
"description": "",
"name": "UsaAlert",
"cssProperties": [
{
"description": "Override background color.",
"name": "--usa-alert-background-color"
},
{
"description": "Override left border color.",
"name": "--usa-alert-border-color"
},
{
"description": "Override icon color.",
"name": "--usa-alert-icon-color"
},
{
"description": "Override icon size.",
"name": "--usa-alert-icon-size"
},
{
"description": "Override horizontal padding.",
"name": "--usa-alert-padding-x"
},
{
"description": "Override vertical padding.",
"name": "--usa-alert-padding-y"
},
{
"description": "Override font family.",
"name": "--usa-alert-font-family"
},
{
"description": "Override text color.",
"name": "--usa-alert-text-color"
}
],
"slots": [
{
"description": "The alert heading (use an h-element: h2, h3, etc.).",
"name": "headline"
},
{
"description": "Default slot for alert body content.",
"name": ""
}
],
"members": [
{
"kind": "field",
"name": "status",
"privacy": "public",
"type": {
"text": "AlertStatus"
},
"default": "\"info\"",
"attribute": "status",
"reflects": true
},
{
"kind": "field",
"name": "slim",
"privacy": "public",
"type": {
"text": "boolean"
},
"default": "false",
"attribute": "slim",
"reflects": true
},
{
"kind": "field",
"name": "noIcon",
"privacy": "public",
"type": {
"text": "boolean"
},
"default": "false",
"attribute": "no-icon",
"reflects": true
},
{
"kind": "field",
"name": "closeable",
"privacy": "public",
"type": {
"text": "boolean"
},
"default": "false",
"attribute": "closeable",
"reflects": true
},
{
"kind": "field",
"name": "closeLabel",
"privacy": "public",
"type": {
"text": "string"
},
"default": "\"Close alert\"",
"attribute": "close-label"
},
{
"kind": "field",
"name": "_visible",
"privacy": "public",
"type": {
"text": "boolean"
},
"default": "true",
"attribute": "_visible"
},
{
"kind": "field",
"name": "#role",
"privacy": "private",
"type": {
"text": "string"
},
"readonly": true
},
{
"kind": "method",
"name": "_handleClose",
"privacy": "private"
}
],
"events": [
{
"name": "close",
"type": {
"text": "CustomEvent"
},
"description": "Dispatched when the close button is clicked."
}
],
"attributes": [
{
"type": {
"text": "AlertStatus"
},
"description": "Determines the icon and border/background color.",
"name": "status",
"default": "\"info\"",
"fieldName": "status",
"propName": "status"
},
{
"type": {
"text": "boolean"
},
"description": "Displays the slim variation (smaller icon, no heading).",
"name": "slim",
"default": "false",
"fieldName": "slim",
"propName": "slim"
},
{
"type": {
"text": "boolean"
},
"description": "Hides the status icon.",
"name": "no-icon",
"default": "false",
"fieldName": "noIcon",
"propName": "noIcon"
},
{
"type": {
"text": "boolean"
},
"description": "Shows a close button.",
"name": "closeable",
"default": "false",
"fieldName": "closeable",
"propName": "closeable"
},
{
"type": {
"text": "string"
},
"description": "Aria-label for the close button. Defaults to \"Close alert\".",
"name": "close-label",
"default": "\"Close alert\"",
"fieldName": "closeLabel",
"propName": "closeLabel"
},
{
"name": "_visible",
"type": {
"text": "boolean"
},
"default": "true",
"fieldName": "_visible",
"propName": "_visible"
}
],
"superclass": {
"name": "LitElement",
"package": "lit"
},
"tagName": "usa-alert",
"customElement": true,
"summary": "Displays important messages to the user with contextual status styling."
}
],
"exports": [
{
"kind": "js",
"name": "UsaAlert",
"declaration": {
"name": "UsaAlert",
"module": "src/components/usa-alert/index.ts"
}
}
]
},
{
"kind": "javascript-module",
"path": "src/components/usa-banner/index.ts",
Expand Down
3 changes: 2 additions & 1 deletion src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { UsaAlert } from "./usa-alert";
import { UsaLink } from "./usa-link";
import { UsaBanner } from "./usa-banner";

export { UsaLink, UsaBanner };
export { UsaAlert, UsaLink, UsaBanner };
136 changes: 136 additions & 0 deletions src/components/usa-alert/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { LitElement, html, css, unsafeCSS, nothing } from "lit";
import { classMap } from "lit/directives/class-map.js";

import styles from "./usa-alert.css";
import iconClose from "../../shared/icons/close.svg";
import { defineCustomElement } from "../../utils";

const VALID_STATUSES = [
"info",
"warning",
"error",
"success",
"emergency",
] as const;

type AlertStatus = (typeof VALID_STATUSES)[number];

/**
* @summary Displays important messages to the user with contextual status styling.
*
* @attribute {"info" | "warning" | "error" | "success" | "emergency"} status - Determines the icon and border/background color.
* @attribute {boolean} slim - Displays the slim variation (smaller icon, no heading).
* @attribute {boolean} no-icon - Hides the status icon.
* @attribute {boolean} closeable - Shows a close button.
* @attribute {string} close-label - Aria-label for the close button. Defaults to "Close alert".
*
* @cssprop --usa-alert-background-color - Override background color.
* @cssprop --usa-alert-border-color - Override left border color.
* @cssprop --usa-alert-icon-color - Override icon color.
* @cssprop --usa-alert-icon-size - Override icon size.
* @cssprop --usa-alert-padding-x - Override horizontal padding.
* @cssprop --usa-alert-padding-y - Override vertical padding.
* @cssprop --usa-alert-font-family - Override font family.
* @cssprop --usa-alert-text-color - Override text color.
*
* @slot headline - The alert heading (use an h-element: h2, h3, etc.).
* @slot - Default slot for alert body content.
*
* @fires usa-alert-close - Dispatched when the close button is clicked.
*
* @element usa-alert
*/
export class UsaAlert extends LitElement {
static properties = {
status: { type: String, reflect: true },
slim: { type: Boolean, reflect: true },
noIcon: { type: Boolean, attribute: "no-icon", reflect: true },
Comment thread
ethangardner marked this conversation as resolved.
closeable: { type: Boolean, reflect: true },
closeLabel: { type: String, attribute: "close-label" },
_visible: { state: true },
};

status!: AlertStatus;
slim!: boolean;
noIcon!: boolean;
closeable!: boolean;
closeLabel!: string;
_visible!: boolean;

constructor() {
super();
this.status = "info";
this.slim = false;
this.noIcon = false;
this.closeable = false;
this.closeLabel = "Close alert";
Comment thread
ethangardner marked this conversation as resolved.
this._visible = true;
}

get #role(): string {
if (
this.status === "error" ||
this.status === "emergency" ||
this.status === "warning"
) {
return "alert";
}
return "status";
}

private _handleClose() {
this.dispatchEvent(
new CustomEvent("usa-alert-close", { bubbles: true, composed: true }),
);
this._visible = false;
}

static styles = [
css`
:host {
--usa-icon-close: url("${unsafeCSS(iconClose)}");
}
`,
styles,
];

render() {
if (!this._visible) {
return nothing;
}

const status = VALID_STATUSES.includes(this.status) ? this.status : "info";

const classes = {
"usa-alert": true,
[`usa-alert--${status}`]: true,
"usa-alert--slim": this.slim,
"usa-alert--no-icon": this.noIcon,
};

return html`
<div class="${classMap(classes)}" role="${this.#role}">
<div class="usa-alert__body">
${!this.slim ? html`<slot name="headline"></slot>` : null}
<div class="usa-alert__text">
<slot></slot>
</div>
</div>
${this.closeable
? html`
<button
class="usa-alert__close"
type="button"
aria-label="${this.closeLabel}"
@click="${this._handleClose}"
>
<span class="usa-alert__close-icon"></span>
</button>
`
: null}
</div>
`;
}
}

defineCustomElement("usa-alert", UsaAlert);
Loading