diff --git a/packages/calcite-components/src/components/alert/alert.e2e.ts b/packages/calcite-components/src/components/alert/alert.e2e.ts index 788decdbf68..9670e157f9a 100644 --- a/packages/calcite-components/src/components/alert/alert.e2e.ts +++ b/packages/calcite-components/src/components/alert/alert.e2e.ts @@ -50,8 +50,8 @@ describe("calcite-alert", () => { ${alertContent} `); const element = await page.find("calcite-alert"); - const close = await page.find("calcite-alert >>> .alert-close"); - const icon = await page.find("calcite-alert >>> .alert-icon"); + const close = await page.find(`calcite-alert >>> .${CSS.close}`); + const icon = await page.find(`calcite-alert >>> .${CSS.icon}`); expect(element).toEqualAttribute("kind", "brand"); expect(close).not.toBeNull(); expect(icon).toBeNull(); @@ -65,7 +65,7 @@ describe("calcite-alert", () => { `); const element = await page.find("calcite-alert"); - const icon = await page.find("calcite-alert >>> .alert-icon"); + const icon = await page.find(`calcite-alert >>> .${CSS.icon}`); expect(element).toEqualAttribute("kind", "warning"); expect(element).toEqualAttribute("auto-close-duration", "fast"); @@ -80,8 +80,8 @@ describe("calcite-alert", () => { `); const element = await page.find("calcite-alert"); - const close = await page.find("calcite-alert >>> .alert-close"); - const icon = await page.find("calcite-alert >>> .alert-icon"); + const close = await page.find(`calcite-alert >>> .${CSS.close}`); + const icon = await page.find(`calcite-alert >>> .${CSS.icon}`); expect(element).toHaveAttribute(HYDRATED_ATTR); expect(close).not.toBeNull(); expect(icon).not.toBeNull(); @@ -129,7 +129,7 @@ describe("calcite-alert", () => { const alert1 = await page.find("#alert-1"); const button1 = await page.find("#button-1"); - const alertClose1 = await page.find("#alert-1 >>> .alert-close"); + const alertClose1 = await page.find(`#alert-1 >>> .${CSS.close}`); expect(await alert1.isVisible()).not.toBe(true); @@ -166,8 +166,8 @@ describe("calcite-alert", () => { const button1 = await page.find("#button-1"); const button2 = await page.find("#button-2"); const button3 = await page.find("#button-3"); - const alertClose1 = await page.find("#alert-1 >>> .alert-close"); - const alertClose2 = await page.find("#alert-2 >>> .alert-close"); + const alertClose1 = await page.find(`#alert-1 >>> .${CSS.close}`); + const alertClose2 = await page.find(`#alert-2 >>> .${CSS.close}`); await button1.click(); await page.waitForTimeout(animationDurationInMs); @@ -192,8 +192,8 @@ describe("calcite-alert", () => { ${alertContent} `); - const container = await page.find("calcite-alert >>> .container"); - expect(container).toHaveClass("bottom"); + const container = await page.find(`calcite-alert >>> .${CSS.container}`); + expect(container).toHaveClass(CSS.containerBottom); }); it("correctly assigns a requested placement class", async () => { @@ -203,9 +203,9 @@ describe("calcite-alert", () => { ${alertContent} `); - const container = await page.find("calcite-alert >>> .container"); - expect(container).not.toHaveClass("bottom"); - expect(container).toHaveClass("top-end"); + const container = await page.find(`calcite-alert >>> .${CSS.container}`); + expect(container).not.toHaveClass(CSS.containerBottom); + expect(container).toHaveClass(CSS.containerTopEnd); }); describe("CSS properties for light/dark modes", () => { @@ -249,7 +249,7 @@ describe("calcite-alert", () => { it("should render alert dismiss progress bar with default value tied to light mode", async () => { page = await newE2EPage({ html: alertSnippet }); await page.waitForTimeout(animationDurationInMs); - alertDismissProgressBar = await page.find("calcite-alert[open] >>> .alert-dismiss-progress"); + alertDismissProgressBar = await page.find(`calcite-alert[open] >>> .${CSS.dismissProgress}`); progressBarStyles = await alertDismissProgressBar.getComputedStyle(":after"); expect(await progressBarStyles.getPropertyValue("background-color")).toEqual("rgba(255, 255, 255, 0.8)"); }); @@ -261,7 +261,7 @@ describe("calcite-alert", () => { html: `
${alertSnippet}
`, }); await page.waitForTimeout(animationDurationInMs); - alertDismissProgressBar = await page.find("calcite-alert[open] >>> .alert-dismiss-progress"); + alertDismissProgressBar = await page.find(`calcite-alert[open] >>> .${CSS.dismissProgress}`); progressBarStyles = await alertDismissProgressBar.getComputedStyle(":after"); expect(await progressBarStyles.getPropertyValue("background-color")).toEqual("rgba(43, 43, 43, 0.8)"); }); @@ -279,7 +279,7 @@ describe("calcite-alert", () => {
${alertSnippet}
`, }); await page.waitForTimeout(animationDurationInMs); - alertDismissProgressBar = await page.find("calcite-alert[open] >>> .alert-dismiss-progress"); + alertDismissProgressBar = await page.find(`calcite-alert[open] >>> .${CSS.dismissProgress}`); progressBarStyles = await alertDismissProgressBar.getComputedStyle(":after"); expect(await progressBarStyles.getPropertyValue("background-color")).toEqual(overrideStyle); }); diff --git a/packages/calcite-components/src/components/alert/alert.scss b/packages/calcite-components/src/components/alert/alert.scss index c1990797076..26e29bd72a5 100644 --- a/packages/calcite-components/src/components/alert/alert.scss +++ b/packages/calcite-components/src/components/alert/alert.scss @@ -6,11 +6,170 @@ * @prop --calcite-alert-width: Specifies the width of the component. */ +$border-style: 1px solid var(--calcite-ui-border-3); + +:host { + --calcite-alert-edge-distance: theme("spacing.8"); + @apply block; +} + +.container { + @apply bg-foreground-1 + box-border + fixed + flex + flex-wrap + items-center + justify-center + mx-auto + my-0 + opacity-0 + pointer-events-none + shadow-2 + text-start + w-full + z-toast; + + container: responsive-container / inline-size; + border-radius: var(--calcite-border-radius); + border-block-start: 0 solid transparent; + border-inline: $border-style; + border-block-end: $border-style; + inline-size: var(--calcite-alert-width); + max-inline-size: calc(100% - (var(--calcite-alert-edge-distance) * 2)); + transition: var(--calcite-internal-animation-timing-slow) $easing-function, + opacity var(--calcite-internal-animation-timing-slow) $easing-function, + all var(--calcite-animation-timing) ease-in-out; + + &--bottom, + &--top { + inset-inline-end: 0; + inset-inline-start: 0; + } + &[class*="bottom"] { + transform: translate3d(0, var(--calcite-alert-edge-distance), 0); + inset-block-end: var(--calcite-alert-edge-distance); + } + &[class*="top"] { + transform: translate3d(0, calc(-1 * var(--calcite-alert-edge-distance)), 0); + inset-block-start: var(--calcite-alert-edge-distance); + } + &[class*="start"] { + inset-inline-start: var(--calcite-alert-edge-distance); + inset-inline-end: auto; + } + &[class*="end"] { + inset-inline-end: var(--calcite-alert-edge-distance); + inset-inline-start: auto; + } +} + +.content { + @apply box-border flex flex-auto flex-col transition-default; + padding-block: var(--calcite-alert-spacing-token-small); + padding-inline: var(--calcite-alert-spacing-token-large) var(--calcite-alert-spacing-token-small); +} + +.icon { + @apply flex flex-col items-center justify-start p-0; + margin-block-end: var(--calcite-alert-spacing-token-large); + margin-inline-end: auto; +} + +.close { + @apply bg-transparent border-none cursor-pointer flex items-start justify-end outline-none self-start text-color-3; + -webkit-appearance: none; + padding: var(--calcite-alert-spacing-token-large); + + @apply focus-base; + &:focus { + @apply focus-inset; + } + + &:hover, + &:focus { + @apply bg-foreground-2 text-color-1; + } + + &:active { + @apply bg-foreground-3; + } +} + +.queue-count { + @apply text-color-2 + bg-foreground-1 + transition-default + invisible + flex + cursor-default + items-center + justify-around + self-stretch + overflow-hidden + text-center + font-medium + opacity-0; + border-inline: 0 solid transparent; + border-start-end-radius: 0; + + &--active { + @apply visible opacity-100; + } +} + +.dismiss-progress { + @apply absolute + block + w-full + overflow-hidden; + inset-inline: 0; + inset-block-start: -2px; + block-size: 2px; + border-radius: var(--calcite-border-radius) var(--calcite-border-radius) 0 0; + &:after { + @apply absolute + top-0 + block; + block-size: 2px; + content: ""; + background-color: var(--calcite-alert-dismiss-progress-background); + inset-inline-end: 0; + } +} + +.actions-end { + @apply flex self-stretch; +} + +.text-container { + @apply flex flex-1 min-w-0 flex-col break-words; +} + +.content-container { + @apply flex flex-1; +} + +.footer { + @apply flex justify-end order-1 pt-px relative w-full; + block-size: var(--calcite-alert-footer-height); + + &:before { + content: ""; + @apply absolute top-0; + inset-inline: var(--calcite-alert-footer-divider-gap); + border-block-start: $border-style; + } +} + // scale variables :host([scale="s"]) { --calcite-alert-width: 40em; --calcite-alert-spacing-token-small: theme("spacing.2"); --calcite-alert-spacing-token-large: theme("spacing.3"); + --calcite-alert-footer-height: theme("height.8"); + --calcite-alert-footer-divider-gap: theme("spacing[0.5]"); + @include slotted("title", "*") { @apply text-n1-wrap; } @@ -20,22 +179,21 @@ @include slotted("link", "*") { @apply text-n2-wrap; } - .alert-queue-count { + .queue-count { @apply mx-2; } .container { --calcite-alert-min-height: 3.5rem; } - .alert-close { - // specific padding for close button to align with calcite-action small-scale spacing - @apply p-2; - } } :host([scale="m"]) { --calcite-alert-width: 50em; --calcite-alert-spacing-token-small: theme("spacing.3"); --calcite-alert-spacing-token-large: theme("spacing.4"); + --calcite-alert-footer-height: theme("height.12"); + --calcite-alert-footer-divider-gap: theme("spacing.1"); + @include slotted("title", "*") { @apply text-0-wrap; } @@ -45,7 +203,7 @@ @include slotted("link", "*") { @apply text-n1-wrap; } - .alert-queue-count { + .queue-count { @apply mx-3; } .container { @@ -57,6 +215,9 @@ --calcite-alert-width: 60em; --calcite-alert-spacing-token-small: theme("spacing.4"); --calcite-alert-spacing-token-large: theme("spacing.5"); + --calcite-alert-footer-height: theme("height.16"); + --calcite-alert-footer-divider-gap: theme("spacing.2"); + @include slotted("title", "*") { @apply text-1-wrap mb-1; } @@ -66,7 +227,7 @@ @include slotted("link", "*") { @apply text-0-wrap; } - .alert-queue-count { + .queue-count { @apply mx-4; } .container { @@ -74,76 +235,9 @@ } } -:host { - --calcite-alert-edge-distance: theme("spacing.8"); - @apply block; - .container { - @apply shadow-2 - bg-foreground-1 - pointer-events-none - fixed - my-0 - mx-auto - flex - items-center - justify-center - opacity-0 - z-toast; - border-radius: var(--calcite-border-radius); - border-block-start: 0px solid transparent; - border-inline: 1px solid var(--calcite-ui-border-3); - border-block-end: 1px solid var(--calcite-ui-border-3); - min-block-size: var(--calcite-alert-min-height); - inline-size: var(--calcite-alert-width); - max-inline-size: calc(100% - (var(--calcite-alert-edge-distance) * 2 + 2px)); - max-block-size: 0; - transition: var(--calcite-internal-animation-timing-slow) $easing-function, - opacity var(--calcite-internal-animation-timing-slow) $easing-function, - all var(--calcite-animation-timing) ease-in-out; - &.bottom, - &.top { - inset-inline-end: 0; - inset-inline-start: 0; - } - &[class*="bottom"] { - transform: translate3d(0, var(--calcite-alert-edge-distance), 0); - inset-block-end: var(--calcite-alert-edge-distance); - } - &[class*="top"] { - transform: translate3d(0, calc(-1 * var(--calcite-alert-edge-distance)), 0); - inset-block-start: var(--calcite-alert-edge-distance); - } - &[class*="-start"] { - inset-inline-start: var(--calcite-alert-edge-distance); - inset-inline-end: auto; - } - &[class*="-end"] { - inset-inline-end: var(--calcite-alert-edge-distance); - inset-inline-start: auto; - } - } -} - -@include calciteHydratedHidden(); - -.container { - @apply flex - w-full - items-center - justify-center; -} - -// focus styles -.alert-close { - @apply focus-base; - &:focus { - @apply focus-inset; - } -} - :host([open]) { - .container:not(.queued) { - @apply max-h-full border-t-2 opacity-100; + .container:not(.container--queued) { + @apply border-t-2 opacity-100; pointer-events: initial; &[class*="bottom"] { transform: translate3d(0, calc(-1 * var(--calcite-alert-edge-distance)), inherit); @@ -154,6 +248,10 @@ } } +:host([auto-close]) > .queue-count { + border-inline-end: 0 solid transparent; +} + @include slotted("title", "*") { @apply text-0-wrap text-color-1 @@ -173,114 +271,6 @@ @apply text-color-link inline-flex; } -@mixin alert-element-base() { - @apply transition-default; - padding-block: var(--calcite-alert-spacing-token-small); - padding-inline: var(--calcite-alert-spacing-token-large); - flex: 0 0 auto; -} - -.alert-content { - @include alert-element-base; - @apply bg-foreground-1 break-words flex flex-col; - flex: 1 1 0; - min-inline-size: 0; - padding-block: var(--calcite-alert-spacing-token-small); - padding-inline: 0 var(--calcite-alert-spacing-token-small); - border-radius: var(--calcite-border-radius); - - &:first-of-type:not(:only-child) { - padding-inline-start: var(--calcite-alert-spacing-token-large); - } - &:only-child { - padding: var(--calcite-alert-spacing-token-small); - } -} - -.alert-icon { - @include alert-element-base; - @apply bg-foreground-1 - flex - items-center - self-stretch - py-0; - border-start-start-radius: var(--calcite-border-radius); - border-end-start-radius: var(--calcite-border-radius); -} - -.alert-close { - @include alert-element-base; - @apply bg-foreground-1 - text-color-3 - cursor-pointer - self-stretch - overflow-hidden - border-none - py-0 - outline-none; - border-end-end-radius: var(--calcite-border-radius); - border-start-end-radius: var(--calcite-border-radius); - - &:hover, - &:focus { - @apply text-color-1 bg-foreground-2; - } - - &:open { - @apply bg-foreground-3; - } -} - -.alert-queue-count { - @apply text-color-2 - bg-foreground-1 - transition-default - invisible - flex - cursor-default - items-center - justify-around - self-stretch - overflow-hidden - text-center - font-medium - opacity-0; - border-inline: 0px solid transparent; - border-start-end-radius: 0; - - &.active { - @apply visible opacity-100; - } -} - -:host([auto-close]) > .alert-queue-count { - border-inline-end: 0px solid transparent; -} - -.alert-dismiss-progress { - @apply absolute - block - w-full - overflow-hidden; - inset-inline: 0; - inset-block-start: -2px; - block-size: 2px; - border-radius: var(--calcite-border-radius) var(--calcite-border-radius) 0 0; - &:after { - @apply absolute - top-0 - block; - block-size: 2px; - content: ""; - background-color: var(--calcite-alert-dismiss-progress-background); - inset-inline-end: 0; - } -} - -.actions-end { - @apply flex self-stretch; -} - $alertKinds: "brand" var(--calcite-ui-brand), "info" var(--calcite-ui-info), "danger" var(--calcite-ui-danger), "success" var(--calcite-ui-success), "warning" var(--calcite-ui-warning); @@ -292,7 +282,7 @@ $alertKinds: "brand" var(--calcite-ui-brand), "info" var(--calcite-ui-info), "da .container { border-block-start-color: $kind; - & .alert-icon { + & .icon { color: $kind; } } @@ -305,10 +295,10 @@ $alertDurations: "fast" 6000ms, "medium" 10000ms, "slow" 14000ms; $name: nth($alertDuration, 1); $duration: nth($alertDuration, 2); - :host([auto-close-duration="#{$name}"]) .alert-dismiss-progress:after { + :host([auto-close-duration="#{$name}"]) .dismiss-progress:after { animation: dismissProgress $duration ease-out; } - :host(:hover[auto-close-duration="#{$name}"]) .alert-dismiss-progress:after { + :host(:hover[auto-close-duration="#{$name}"]) .dismiss-progress:after { animation-play-state: paused; } } @@ -325,9 +315,46 @@ $alertDurations: "fast" 6000ms, "medium" 10000ms, "slow" 14000ms; /** * Conditional styles for when Alert is slotted in Shell */ +.container--slotted-in-shell { + @apply absolute; +} -.container.slotted-in-shell { - position: absolute; +@container responsive-container (min-width: #{$breakpoint-width-xs}) { + .content { + @apply flex-row; + } + + .close { + @apply items-center self-stretch; + } + + .icon { + @apply justify-center; + margin-inline-end: 0; + margin-block: 0; + padding-inline-end: var(--calcite-alert-spacing-token-large); + } +} + +@container responsive-container (min-width: #{$breakpoint-width-sm}) { + .close { + @apply self-stretch; + } + + .footer { + @apply self-stretch w-auto; + order: initial; + block-size: inherit; + + &:before { + content: none; + } + } + + .icon { + padding-inline: var(--calcite-alert-spacing-token-large) 0; + } } @include base-component(); +@include calciteHydratedHidden(); diff --git a/packages/calcite-components/src/components/alert/alert.stories.ts b/packages/calcite-components/src/components/alert/alert.stories.ts index 3ee99ae940f..d5a640687d2 100644 --- a/packages/calcite-components/src/components/alert/alert.stories.ts +++ b/packages/calcite-components/src/components/alert/alert.stories.ts @@ -1,9 +1,11 @@ import { select } from "@storybook/addon-knobs"; import { boolean, iconNames, storyFilters } from "../../../.storybook/helpers"; -import { modesDarkDefault } from "../../../.storybook/utils"; +import { createBreakpointStories, modesDarkDefault } from "../../../.storybook/utils"; import { html } from "../../../support/formatting"; import readme from "./readme.md"; +const openAlertScreenshotDelay = 1000; + export default { title: "Components/Alert", parameters: { @@ -218,3 +220,121 @@ export const autoClosableRetainsCloseButton_TestOnly = (): string => html` Take action `; + +// we use individual stories since we can't display multiple open alerts at the same time + +const breakpointsStoryTemplate = html` + + +
title
+
message
+ + +
+ +
title
+
message
+ + +
+ +`; + +export const breakpointsXsmallScaleS_TestOnly = (): string => + createBreakpointStories(breakpointsStoryTemplate, { breakpoint: "xsmall", scale: "s" }); + +breakpointsXsmallScaleS_TestOnly.parameters = { + chromatic: { delay: openAlertScreenshotDelay }, +}; + +export const breakpointsSmallScaleS_TestOnly = (): string => + createBreakpointStories(breakpointsStoryTemplate, { breakpoint: "small", scale: "s" }); + +breakpointsSmallScaleS_TestOnly.parameters = { + chromatic: { delay: openAlertScreenshotDelay }, +}; + +export const breakpointsMediumScaleS_TestOnly = (): string => + createBreakpointStories(breakpointsStoryTemplate, { breakpoint: "medium", scale: "s" }); + +breakpointsMediumScaleS_TestOnly.parameters = { + chromatic: { delay: openAlertScreenshotDelay }, +}; + +export const breakpointsLargeScaleS_TestOnly = (): string => + createBreakpointStories(breakpointsStoryTemplate, { breakpoint: "large", scale: "s" }); + +breakpointsLargeScaleS_TestOnly.parameters = { + chromatic: { delay: openAlertScreenshotDelay }, +}; + +export const breakpointsXsmallScaleM_TestOnly = (): string => + createBreakpointStories(breakpointsStoryTemplate, { breakpoint: "xsmall", scale: "m" }); + +breakpointsXsmallScaleM_TestOnly.parameters = { + chromatic: { delay: openAlertScreenshotDelay }, +}; + +export const breakpointsSmallScaleM_TestOnly = (): string => + createBreakpointStories(breakpointsStoryTemplate, { breakpoint: "small", scale: "m" }); + +breakpointsSmallScaleM_TestOnly.parameters = { + chromatic: { delay: openAlertScreenshotDelay }, +}; + +export const breakpointsMediumScaleM_TestOnly = (): string => + createBreakpointStories(breakpointsStoryTemplate, { breakpoint: "medium", scale: "m" }); + +breakpointsMediumScaleM_TestOnly.parameters = { + chromatic: { delay: openAlertScreenshotDelay }, +}; + +export const breakpointsLargeScaleM_TestOnly = (): string => + createBreakpointStories(breakpointsStoryTemplate, { breakpoint: "large", scale: "m" }); + +breakpointsLargeScaleM_TestOnly.parameters = { + chromatic: { delay: openAlertScreenshotDelay }, +}; + +export const breakpointsXsmallScaleL_TestOnly = (): string => + createBreakpointStories(breakpointsStoryTemplate, { breakpoint: "xsmall", scale: "l" }); + +breakpointsXsmallScaleL_TestOnly.parameters = { + chromatic: { delay: openAlertScreenshotDelay }, +}; + +export const breakpointsSmallScaleL_TestOnly = (): string => + createBreakpointStories(breakpointsStoryTemplate, { breakpoint: "small", scale: "l" }); + +breakpointsSmallScaleL_TestOnly.parameters = { + chromatic: { delay: openAlertScreenshotDelay }, +}; + +export const breakpointsMediumScaleL_TestOnly = (): string => + createBreakpointStories(breakpointsStoryTemplate, { breakpoint: "medium", scale: "l" }); + +breakpointsMediumScaleL_TestOnly.parameters = { + chromatic: { delay: openAlertScreenshotDelay }, +}; + +export const breakpointsLargeScaleL_TestOnly = (): string => + createBreakpointStories(breakpointsStoryTemplate, { breakpoint: "large", scale: "l" }); + +breakpointsLargeScaleL_TestOnly.parameters = { + chromatic: { delay: openAlertScreenshotDelay }, +}; diff --git a/packages/calcite-components/src/components/alert/alert.tsx b/packages/calcite-components/src/components/alert/alert.tsx index bb596463e71..d199c063f3f 100644 --- a/packages/calcite-components/src/components/alert/alert.tsx +++ b/packages/calcite-components/src/components/alert/alert.tsx @@ -44,6 +44,8 @@ import { KindIcons } from "../resources"; import { AlertMessages } from "./assets/alert/t9n"; import { AlertDuration, Sync, Unregister } from "./interfaces"; import { CSS, DURATIONS, SLOTS } from "./resources"; +import { Breakpoints, getBreakpoints } from "../../utils/responsive"; +import { createObserver } from "../../utils/observers"; /** * Alerts are meant to provide a way to communicate urgent or important information to users, frequently as a result of an action they took in your app. Alerts are positioned @@ -147,12 +149,6 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen */ @Prop({ mutable: true }) slottedInShell: boolean; - @Watch("icon") - @Watch("kind") - updateRequestedIcon(): void { - this.requestedIcon = setRequestedIcon(KindIcons, this.icon, this.kind); - } - @Watch("autoCloseDuration") updateDuration(): void { if (this.autoClose && this.autoCloseTimeoutId) { @@ -177,12 +173,15 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen if (open && !this.queued) { this.calciteInternalAlertRegister.emit(); } + if (this.transitionEl) { + this.resizeObserver?.observe(this.transitionEl); + } } async componentWillLoad(): Promise { setUpLoadableComponent(this); - this.requestedIcon = setRequestedIcon(KindIcons, this.icon, this.kind); - await setUpMessages(this); + const [, breakpoints] = await Promise.all([setUpMessages(this), getBreakpoints()]); + this.breakpoints = breakpoints; if (this.open) { onToggleOpenCloseComponent(this); } @@ -190,6 +189,7 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen componentDidLoad(): void { setComponentLoaded(this); + this.resizeObserver?.observe(this.transitionEl); } disconnectedCallback(): void { @@ -203,51 +203,25 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen disconnectLocalized(this); disconnectMessages(this); this.slottedInShell = false; + this.resizeObserver?.disconnect(); } render(): VNode { - const { hasEndActions } = this; - const closeButton = ( - - ); - numberStringFormatter.numberFormatOptions = { locale: this.effectiveLocale, numberingSystem: this.numberingSystem, signDisplay: "always", }; - const queueNumber = this.queueLength > 2 ? this.queueLength - 1 : 1; - const queueText = numberStringFormatter.numberFormatter.format(queueNumber); - - const queueCount = ( -
1 ? "active " : ""}alert-queue-count`}> - - {queueText} - -
- ); - - const { open, autoClose, label, placement, queued, requestedIcon, iconFlipRtl } = this; + const { hasEndActions } = this; + const { open, autoClose, responsiveContainerWidth, label, placement, queued } = this; const role = autoClose ? "alert" : "alertdialog"; + const widthBreakpoints = this.breakpoints.width; + const lessThanSmall = responsiveContainerWidth < widthBreakpoints.small; + const greaterOrEqualThanSmall = responsiveContainerWidth >= widthBreakpoints.small; const hidden = !open; - - const slotNode = ( - - ); + const effectiveIcon = setRequestedIcon(KindIcons, this.icon, this.kind); + const hasQueuedAlerts = this.queueLength > 1; return (
- {requestedIcon ? ( -
- +
+ {effectiveIcon && greaterOrEqualThanSmall ? this.renderIcon(effectiveIcon) : null} +
+ {effectiveIcon && lessThanSmall ? this.renderIcon(effectiveIcon) : null} +
+ + + +
- ) : null} -
- - -
-