diff --git a/.changeset/big-jars-pump.md b/.changeset/big-jars-pump.md new file mode 100644 index 00000000000..779df0cba77 --- /dev/null +++ b/.changeset/big-jars-pump.md @@ -0,0 +1,82 @@ +--- +`@spectrum-css/inlinealert`: major +--- + +#### S2 migration in-line alert + +This migrates the `in-line alert` component to Spectrum 2. Custom properties have been updated and added per the design specification. + +Subtle and bold treatments have been added for each badge variant. + +To use the subtle treatment, you will need to apply the `spectrum-InLineAlert--subtle` class: + +```html +
+
+ Info variant with subtle fill + +
+
This is an alert.
+
+``` + +To use the bold treatment (which is reserved for high-attention alerts only), you will need to apply the `spectrum-InLineAlert--bold` class: + +```html +
+
+ Info variant with bold fill + +
+
This is an alert.
+
+``` + +Because subtle and bold treatments draw a similar level of attention you should choose only one to use consistently within a single product. + +##### New mods + +`--mod-inlinealert-border-and-icon-color-neutral` +`--mod-inlinealert-min-spacing-header-to-icon` +`--mod-inlinealert-spacing-content-link-button` +`--mod-inlinealert-spacing-header-content` + +##### Removed mods + +`--mod-inlinealert-spacing-header-content-button` +`--mod-inlinealert-spacing-header-to-icon` + +##### New custom properties + +`--spectrum-inlinealert-min-spacing-header-to-icon` +`--spectrum-inlinealert-spacing-content-link-button` +`--spectrum-inlinealert-spacing-header-content` + +##### Removed custom properties + +`--spectrum-inlinealert-spacing-header-content-button` +`--spectrum-inlinealert-spacing-header-to-icon` diff --git a/components/inlinealert/dist/metadata.json b/components/inlinealert/dist/metadata.json index bd5894d28c9..81ebe4df638 100644 --- a/components/inlinealert/dist/metadata.json +++ b/components/inlinealert/dist/metadata.json @@ -2,27 +2,33 @@ "sourceFile": "index.css", "selectors": [ ".spectrum-InLineAlert", - ".spectrum-InLineAlert--info", - ".spectrum-InLineAlert--info .spectrum-InLineAlert-icon", - ".spectrum-InLineAlert--negative", - ".spectrum-InLineAlert--negative .spectrum-InLineAlert-icon", - ".spectrum-InLineAlert--notice", - ".spectrum-InLineAlert--notice .spectrum-InLineAlert-icon", - ".spectrum-InLineAlert--positive", - ".spectrum-InLineAlert--positive .spectrum-InLineAlert-icon", ".spectrum-InLineAlert-content", ".spectrum-InLineAlert-footer", ".spectrum-InLineAlert-footer:empty", ".spectrum-InLineAlert-header", - ".spectrum-InLineAlert-icon" + ".spectrum-InLineAlert-icon", + ".spectrum-InLineAlert.spectrum-InLineAlert--bold", + ".spectrum-InLineAlert.spectrum-InLineAlert--bold:not(.spectrum-InLineAlert--subtle, .spectrum-InLineAlert--notice)", + ".spectrum-InLineAlert.spectrum-InLineAlert--info", + ".spectrum-InLineAlert.spectrum-InLineAlert--info.spectrum-InLineAlert--bold", + ".spectrum-InLineAlert.spectrum-InLineAlert--info.spectrum-InLineAlert--subtle", + ".spectrum-InLineAlert.spectrum-InLineAlert--negative", + ".spectrum-InLineAlert.spectrum-InLineAlert--negative.spectrum-InLineAlert--bold", + ".spectrum-InLineAlert.spectrum-InLineAlert--negative.spectrum-InLineAlert--subtle", + ".spectrum-InLineAlert.spectrum-InLineAlert--neutral", + ".spectrum-InLineAlert.spectrum-InLineAlert--neutral.spectrum-InLineAlert--bold", + ".spectrum-InLineAlert.spectrum-InLineAlert--neutral.spectrum-InLineAlert--subtle", + ".spectrum-InLineAlert.spectrum-InLineAlert--notice", + ".spectrum-InLineAlert.spectrum-InLineAlert--notice.spectrum-InLineAlert--bold", + ".spectrum-InLineAlert.spectrum-InLineAlert--notice.spectrum-InLineAlert--subtle", + ".spectrum-InLineAlert.spectrum-InLineAlert--positive", + ".spectrum-InLineAlert.spectrum-InLineAlert--positive.spectrum-InLineAlert--bold", + ".spectrum-InLineAlert.spectrum-InLineAlert--positive.spectrum-InLineAlert--subtle", + ".spectrum-InLineAlert.spectrum-InLineAlert--subtle" ], "modifiers": [ "--mod-inlinealert-background-color", "--mod-inlinealert-border-and-icon-color", - "--mod-inlinealert-border-and-icon-color-info", - "--mod-inlinealert-border-and-icon-color-negative", - "--mod-inlinealert-border-and-icon-color-notice", - "--mod-inlinealert-border-and-icon-color-positive", "--mod-inlinealert-border-radius", "--mod-inlinealert-border-width", "--mod-inlinealert-content-color", @@ -40,18 +46,15 @@ "--mod-inlinealert-heading-line-height", "--mod-inlinealert-icon-size", "--mod-inlinealert-min-inline-size", + "--mod-inlinealert-min-spacing-header-to-icon", + "--mod-inlinealert-spacing-content-link-button", "--mod-inlinealert-spacing-edge-to-text", - "--mod-inlinealert-spacing-header-content-button", - "--mod-inlinealert-spacing-header-to-icon" + "--mod-inlinealert-spacing-header-content" ], "component": [ "--spectrum-in-line-alert-minimum-width", "--spectrum-inlinealert-background-color", "--spectrum-inlinealert-border-and-icon-color", - "--spectrum-inlinealert-border-and-icon-color-info", - "--spectrum-inlinealert-border-and-icon-color-negative", - "--spectrum-inlinealert-border-and-icon-color-notice", - "--spectrum-inlinealert-border-and-icon-color-positive", "--spectrum-inlinealert-border-radius", "--spectrum-inlinealert-border-width", "--spectrum-inlinealert-content-color", @@ -69,12 +72,14 @@ "--spectrum-inlinealert-heading-line-height", "--spectrum-inlinealert-icon-size", "--spectrum-inlinealert-min-inline-size", + "--spectrum-inlinealert-min-spacing-header-to-icon", + "--spectrum-inlinealert-spacing-content-link-button", "--spectrum-inlinealert-spacing-edge-to-text", - "--spectrum-inlinealert-spacing-header-content-button", - "--spectrum-inlinealert-spacing-header-to-icon" + "--spectrum-inlinealert-spacing-header-content" ], "global": [ "--spectrum-background-layer-2-color", + "--spectrum-black", "--spectrum-body-color", "--spectrum-body-line-height", "--spectrum-body-sans-serif-font-style", @@ -82,26 +87,39 @@ "--spectrum-body-size-s", "--spectrum-border-width-200", "--spectrum-component-height-50", - "--spectrum-corner-radius-100", + "--spectrum-corner-radius-700", "--spectrum-heading-color", "--spectrum-heading-line-height", "--spectrum-heading-sans-serif-font-style", "--spectrum-heading-sans-serif-font-weight", "--spectrum-heading-size-xxs", + "--spectrum-informative-background-color-default", + "--spectrum-informative-subtle-background-color-default", "--spectrum-informative-visual-color", + "--spectrum-negative-background-color-default", + "--spectrum-negative-subtle-background-color-default", "--spectrum-negative-visual-color", + "--spectrum-neutral-background-color-default", + "--spectrum-neutral-subtle-background-color-default", "--spectrum-neutral-visual-color", + "--spectrum-notice-background-color-default", + "--spectrum-notice-subtle-background-color-default", "--spectrum-notice-visual-color", + "--spectrum-positive-background-color-default", + "--spectrum-positive-subtle-background-color-default", "--spectrum-positive-visual-color", "--spectrum-sans-font-family-stack", + "--spectrum-spacing-100", + "--spectrum-spacing-200", "--spectrum-spacing-300", - "--spectrum-spacing-400", + "--spectrum-white", "--spectrum-workflow-icon-size-100" ], "passthroughs": [], "high-contrast": [ "--highcontrast-inlinealert-background-color", "--highcontrast-inlinealert-border-and-icon-color", + "--highcontrast-inlinealert-border-width", "--highcontrast-inlinealert-content-color", "--highcontrast-inlinealert-header-color" ] diff --git a/components/inlinealert/index.css b/components/inlinealert/index.css index ad548bab5eb..662a89ebb4e 100644 --- a/components/inlinealert/index.css +++ b/components/inlinealert/index.css @@ -1,5 +1,5 @@ /*! - * Copyright 2024 Adobe. All rights reserved. + * Copyright 2025 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 @@ -27,26 +27,105 @@ /* Size */ --spectrum-inlinealert-border-width: var(--spectrum-border-width-200); - --spectrum-inlinealert-border-radius: var(--spectrum-corner-radius-100); + --spectrum-inlinealert-border-radius: var(--spectrum-corner-radius-700); --spectrum-inlinealert-icon-size: var(--spectrum-workflow-icon-size-100); --spectrum-inlinealert-min-inline-size: var(--spectrum-in-line-alert-minimum-width); --spectrum-inlinealert-header-min-block-size: var(--spectrum-component-height-50); /* Spacing */ - --spectrum-inlinealert-spacing-edge-to-text: var(--spectrum-spacing-400); - --spectrum-inlinealert-spacing-header-to-icon: var(--spectrum-spacing-400); - --spectrum-inlinealert-spacing-header-content-button: var(--spectrum-spacing-300); + --spectrum-inlinealert-spacing-edge-to-text: var(--spectrum-spacing-300); + --spectrum-inlinealert-min-spacing-header-to-icon: var(--spectrum-spacing-100); + --spectrum-inlinealert-spacing-header-content: var(--spectrum-spacing-100); + --spectrum-inlinealert-spacing-content-link-button: var(--spectrum-spacing-200); /* Color */ --spectrum-inlinealert-background-color: var(--spectrum-background-layer-2-color); --spectrum-inlinealert-border-and-icon-color: var(--spectrum-neutral-visual-color); --spectrum-inlinealert-header-color: var(--spectrum-heading-color); --spectrum-inlinealert-content-color: var(--spectrum-body-color); - --spectrum-inlinealert-border-and-icon-color-info: var(--spectrum-informative-visual-color); - --spectrum-inlinealert-border-and-icon-color-positive: var(--spectrum-positive-visual-color); - --spectrum-inlinealert-border-and-icon-color-notice: var(--spectrum-notice-visual-color); - --spectrum-inlinealert-border-and-icon-color-negative: var(--spectrum-negative-visual-color); + &.spectrum-InLineAlert--subtle { + --spectrum-inlinealert-border-width: 0px; + } + + &.spectrum-InLineAlert--bold { + --spectrum-inlinealert-border-width: 0px; + } + + &.spectrum-InLineAlert--bold:not(.spectrum-InLineAlert--subtle, .spectrum-InLineAlert--notice) { + --spectrum-inlinealert-header-color: var(--spectrum-white); + --spectrum-inlinealert-content-color: var(--spectrum-white); + --spectrum-inlinealert-border-and-icon-color: var(--spectrum-white); + } + + &.spectrum-InLineAlert--info { + --spectrum-inlinealert-border-and-icon-color: var(--spectrum-informative-visual-color); + + &.spectrum-InLineAlert--subtle { + --spectrum-inlinealert-background-color: var(--spectrum-informative-subtle-background-color-default); + --spectrum-inlinealert-border-and-icon-color: var(--spectrum-informative-visual-color); + } + + &.spectrum-InLineAlert--bold { + --spectrum-inlinealert-background-color: var(--spectrum-informative-background-color-default); + } + } + + &.spectrum-InLineAlert--notice { + --spectrum-inlinealert-border-and-icon-color: var(--spectrum-notice-visual-color); + + &.spectrum-InLineAlert--subtle { + --spectrum-inlinealert-background-color: var(--spectrum-notice-subtle-background-color-default); + --spectrum-inlinealert-border-and-icon-color: var(--spectrum-notice-visual-color); + } + + &.spectrum-InLineAlert--bold { + --spectrum-inlinealert-background-color: var(--spectrum-notice-background-color-default); + --spectrum-inlinealert-border-and-icon-color: var(--spectrum-black); + } + } + + &.spectrum-InLineAlert--positive { + --spectrum-inlinealert-border-and-icon-color: var(--spectrum-positive-visual-color); + + &.spectrum-InLineAlert--subtle { + --spectrum-inlinealert-background-color: var(--spectrum-positive-subtle-background-color-default); + --spectrum-inlinealert-border-and-icon-color: var(--spectrum-positive-visual-color); + } + + &.spectrum-InLineAlert--bold { + --spectrum-inlinealert-background-color: var(--spectrum-positive-background-color-default); + } + } + + &.spectrum-InLineAlert--negative { + --spectrum-inlinealert-border-and-icon-color: var(--spectrum-negative-visual-color); + + &.spectrum-InLineAlert--subtle { + --spectrum-inlinealert-background-color: var(--spectrum-negative-subtle-background-color-default); + --spectrum-inlinealert-border-and-icon-color: var(--spectrum-negative-visual-color); + } + + &.spectrum-InLineAlert--bold { + --spectrum-inlinealert-background-color: var(--spectrum-negative-background-color-default); + } + } + + &.spectrum-InLineAlert--neutral { + --spectrum-inlinealert-border-and-icon-color: var(--spectrum-neutral-visual-color); + + &.spectrum-InLineAlert--subtle { + --spectrum-inlinealert-background-color: var(--spectrum-neutral-subtle-background-color-default); + --spectrum-inlinealert-border-and-icon-color: var(--spectrum-neutral-visual-color); + } + + &.spectrum-InLineAlert--bold { + --spectrum-inlinealert-background-color: var(--spectrum-neutral-background-color-default); + } + } +} + +.spectrum-InLineAlert { position: relative; display: inline-block; @@ -56,8 +135,7 @@ padding-block: var(--mod-inlinealert-spacing-edge-to-text, var(--spectrum-inlinealert-spacing-edge-to-text)); padding-inline: var(--mod-inlinealert-spacing-edge-to-text, var(--spectrum-inlinealert-spacing-edge-to-text)); - border-block-width: var(--mod-inlinealert-border-width, var(--spectrum-inlinealert-border-width)); - border-inline-width: var(--mod-inlinealert-border-width, var(--spectrum-inlinealert-border-width)); + border-width: var(--highcontrast-inlinealert-border-width, var(--mod-inlinealert-border-width, var(--spectrum-inlinealert-border-width))); border-style: solid; border-radius: var(--mod-inlinealert-border-radius, var(--spectrum-inlinealert-border-radius)); @@ -65,27 +143,19 @@ border-color: var(--highcontrast-inlinealert-border-and-icon-color, var(--mod-inlinealert-border-and-icon-color, var(--spectrum-inlinealert-border-and-icon-color))); } -@media (forced-colors: active) { - .spectrum-InLineAlert { - --highcontrast-inlinealert-background-color: Background; - --highcontrast-inlinealert-header-color: CanvasText; - --highcontrast-inlinealert-content-color: CanvasText; - --highcontrast-inlinealert-border-and-icon-color: ButtonBorder; - } -} - .spectrum-InLineAlert-icon { inline-size: var(--mod-inlinealert-icon-size, var(--spectrum-inlinealert-icon-size)); block-size: var(--mod-inlinealert-icon-size, var(--spectrum-inlinealert-icon-size)); + flex-shrink: 0; + color: var(--highcontrast-inlinealert-border-and-icon-color, var(--spectrum-inlinealert-border-and-icon-color)); } .spectrum-InLineAlert-header { display: flex; - align-items: center; justify-content: space-between; - /* Minimum space between header and icon */ - gap: var(--mod-inlinealert-spacing-header-to-icon, var(--spectrum-inlinealert-spacing-header-to-icon)); + gap: var(--mod-inlinealert-min-spacing-header-to-icon, var(--spectrum-inlinealert-min-spacing-header-to-icon)); + margin-block-end: var(--mod-inlinealert-spacing-header-content, var(--spectrum-inlinealert-spacing-header-content)); font-weight: var(--mod-inlinealert-heading-font-weight, var(--spectrum-inlinealert-heading-font-weight)); font-family: var(--mod-inlinealert-heading-font-family, var(--spectrum-inlinealert-heading-font-family)); @@ -100,8 +170,10 @@ } .spectrum-InLineAlert-content { - display: block; - margin-block-start: var(--mod-inlinealert-spacing-header-content-button, var(--spectrum-inlinealert-spacing-header-content-button)); + display: flex; + justify-content: space-between; + gap: var(--mod-inlinealert-min-spacing-header-to-icon, var(--spectrum-inlinealert-min-spacing-header-to-icon)); + margin-block-end: 0; margin-inline-start: 0; margin-inline-end: 0; @@ -120,42 +192,25 @@ .spectrum-InLineAlert-footer { display: flex; - justify-content: flex-end; - margin-block-start: var(--mod-inlinealert-spacing-header-content-button, var(--spectrum-inlinealert-spacing-header-content-button)); + justify-content: flex-start; + margin-block-start: var(--mod-inlinealert-spacing-content-link-button, var(--spectrum-inlinealert-spacing-content-link-button)); &:empty { display: none; } } -.spectrum-InLineAlert--info { - border-color: var(--highcontrast-inlinealert-border-and-icon-color, var(--mod-inlinealert-border-and-icon-color-info, var(--spectrum-inlinealert-border-and-icon-color-info))); - - .spectrum-InLineAlert-icon { - color: var(--highcontrast-inlinealert-border-and-icon-color, var(--mod-inlinealert-border-and-icon-color-info, var(--spectrum-inlinealert-border-and-icon-color-info))); - } -} - -.spectrum-InLineAlert--notice { - border-color: var(--highcontrast-inlinealert-border-and-icon-color, var(--mod-inlinealert-border-and-icon-color-notice, var(--spectrum-inlinealert-border-and-icon-color-notice))); - - .spectrum-InLineAlert-icon { - color: var(--highcontrast-inlinealert-border-and-icon-color, var(--mod-inlinealert-border-and-icon-color-notice, var(--spectrum-inlinealert-border-and-icon-color-notice))); - } -} - -.spectrum-InLineAlert--positive { - border-color: var(--highcontrast-inlinealert-border-and-icon-color, var(--mod-inlinealert-border-and-icon-color-positive, var(--spectrum-inlinealert-border-and-icon-color-positive))); - - .spectrum-InLineAlert-icon { - color: var(--highcontrast-inlinealert-border-and-icon-color, var(--mod-inlinealert-border-and-icon-color-positive, var(--spectrum-inlinealert-border-and-icon-color-positive))); - } -} +@media (forced-colors: active) { + .spectrum-InLineAlert { + --highcontrast-inlinealert-header-color: CanvasText; + --highcontrast-inlinealert-content-color: CanvasText; + --highcontrast-inlinealert-border-and-icon-color: CanvasText; -.spectrum-InLineAlert--negative { - border-color: var(--highcontrast-inlinealert-border-and-icon-color, var(--mod-inlinealert-border-and-icon-color-negative, var(--spectrum-inlinealert-border-and-icon-color-negative))); + --highcontrast-inlinealert-background-color: Canvas; - .spectrum-InLineAlert-icon { - color: var(--highcontrast-inlinealert-border-and-icon-color, var(--mod-inlinealert-border-and-icon-color-negative, var(--spectrum-inlinealert-border-and-icon-color-negative))); + &.spectrum-InLineAlert--subtle, + &.spectrum-InLineAlert--bold { + --highcontrast-inlinealert-border-width: var(--spectrum-border-width-200); + } } } diff --git a/components/inlinealert/stories/inlinealert.stories.js b/components/inlinealert/stories/inlinealert.stories.js index 6ed4d7c5f18..4fed7dc1fc7 100644 --- a/components/inlinealert/stories/inlinealert.stories.js +++ b/components/inlinealert/stories/inlinealert.stories.js @@ -2,10 +2,12 @@ import { disableDefaultModes } from "@spectrum-css/preview/modes"; import metadata from "../dist/metadata.json"; import packageJson from "../package.json"; import { InlineAlertGroup } from "./inlinealert.test.js"; -import { Template } from "./template.js"; +import { AlertsWithStyleOptions } from "./template.js"; /** * In-line alerts display a non-modal message associated with objects in a view. These are often used in form validation, providing a place to aggregate feedback related to multiple fields. + * + * In-line alerts have five different variants: neutral (default), informative, positive, notice, and negative. Each variant is available with three fill styles (treatment): border (default), subtle, and bold. */ export default { title: "In-line alert", @@ -20,19 +22,29 @@ export default { category: "Content", }, control: { type: "text" }, + if: { arg: "withoutHeader", truthy: false }, }, text: { - name: "Text", + name: "Body text", type: { name: "string", required: true }, table: { type: { summary: "string" }, disable: false, - category: "Component", + category: "Content", }, control: { type: "text" }, }, + withoutHeader: { + name: "Without header", + type: { name: "boolean" }, + table: { + type: { summary: "boolean" }, + category: "Component", + }, + control: "boolean", + }, variant: { - name: "Variants", + name: "Variant", type: { name: "string" }, table: { type: { summary: "string" }, @@ -41,8 +53,29 @@ export default { options: ["neutral", "info", "positive", "notice", "negative"], control: "select", }, + treatment: { + name: "Treatment", + type: { name: "string" }, + table: { + type: { summary: "string" }, + category: "Component", + }, + options: ["border", "subtle", "bold"], + control: "select", + }, isClosable: { name: "Closable", + description: "An optional close button rendered below the alert text and link (if enabled).", + type: { name: "boolean" }, + table: { + type: { summary: "boolean" }, + category: "Advanced", + }, + control: "boolean", + }, + hasLink: { + name: "Link", + description: "An optional link rendered below the alert text.", type: { name: "boolean" }, table: { type: { summary: "boolean" }, @@ -53,10 +86,13 @@ export default { }, args: { rootClass: "spectrum-InLineAlert", - headerText: "Neutral in-line alert header", + headerText: "In-line alert header", text: "This is an alert.", + withoutHeader: false, variant: "neutral", + treatment: "border", isClosable: false, + hasLink: false, }, parameters: { design: { @@ -74,13 +110,23 @@ export default { export const Default = InlineAlertGroup.bind({}); Default.args = {}; +/** + * In-line alerts may be rendered without a header. Combine this strategy with any variant. + */ +export const WithoutHeader = InlineAlertGroup.bind({}); +WithoutHeader.args = { + withoutHeader: true, +}; +WithoutHeader.parameters = { + chromatic: { disableSnapshot: true }, +}; +WithoutHeader.tags = ["!dev"]; + // ********* DOCS ONLY ********* // /** * The informative variant uses the informative semantic color (blue) and has an "information" icon to help those with color vision deficiency discern the message tone. This should be used when the message needs to call extra attention, as compared to the neutral variant. - * - * _Spectrum for Adobe Express uses a different icon. Use the SX_Info_18_S.svg icon in the Express workflow icon set._ */ -export const Informative = Template.bind({}); +export const Informative = AlertsWithStyleOptions.bind({}); Informative.args = { variant: "info", headerText: "Info in-line alert header", @@ -92,10 +138,8 @@ Informative.tags = ["!dev"]; /** * A negative variant uses the negative semantic color (red) and has an "alert" icon to help those with color vision deficiency to discern the message tone. Negative variants are used to show an error or failure, or to convey something that needs to be immediately acknowledged or addressed. - * - * _Spectrum for Adobe Express uses a different icon. Use the SX_Alert_18_S.svg icon in the Express workflow icon set._ */ -export const Negative = Template.bind({}); +export const Negative = AlertsWithStyleOptions.bind({}); Negative.args = { variant: "negative", headerText: "Negative in-line alert header", @@ -105,12 +149,23 @@ Negative.parameters = { }; Negative.tags = ["!dev"]; +/** + * Neutral (default) variant alerts may also use the subtle and bold treatments available to other variants. + */ +export const Neutral = AlertsWithStyleOptions.bind({}); +Neutral.args = { + variant: "neutral", + headerText: "Neutral in-line alert header", +}; +Neutral.parameters = { + chromatic: { disableSnapshot: true }, +}; +Neutral.tags = ["!dev"]; + /** * The positive variant uses the positive semantic color (green) and has a "checkmark" icon to help those with color vision deficiency discern the message tone. This variant should be used to inform someone of a successful function or result of an action they took. - * - * _Spectrum for Adobe Express uses a different icon. Use the SX_CheckmarkCircle_18_S.svg icon in the Express workflow icon set._ */ -export const Positive = Template.bind({}); +export const Positive = AlertsWithStyleOptions.bind({}); Positive.args = { variant: "positive", headerText: "Positive in-line alert header", @@ -122,10 +177,8 @@ Positive.tags = ["!dev"]; /** * To warn about a situation that may need to be addressed soon, use the notice variant. It utilizes the notice semantic color (orange) and has an "alert" icon to help those with color vision deficiency to discern the message tone. - * - * _Spectrum for Adobe Express uses a different icon. Use the SX_Alert_18_S.svg icon in the Express workflow icon set._ */ -export const Notice = Template.bind({}); +export const Notice = AlertsWithStyleOptions.bind({}); Notice.args = { variant: "notice", headerText: "Notice in-line alert header", @@ -137,19 +190,44 @@ Notice.tags = ["!dev"]; /** * An in-line alert with a close button in the footer. Combine this strategy with any variant. - * - * _Spectrum for Adobe Express uses a different icon. Use the SX_Alert_18_S.svg icon in the Express workflow icon set._ */ -export const Closable = Template.bind({}); -Closable.args = { +export const WithFooterClosable = AlertsWithStyleOptions.bind({}); +WithFooterClosable.args = { variant: "negative", isClosable: true, - headerText: "Incorrect payment information - error", + text: "Incorrect payment information - error", +}; +WithFooterClosable.parameters = { + chromatic: { disableSnapshot: true }, +}; +WithFooterClosable.tags = ["!dev"]; + +/** + * An in-line alert with a link in the footer. Combine this strategy with any variant. + */ +export const WithFooterLink = AlertsWithStyleOptions.bind({}); +WithFooterLink.args = { + hasLink: true, + text: "Click the link", +}; +WithFooterLink.parameters = { + chromatic: { disableSnapshot: true }, +}; +WithFooterLink.tags = ["!dev"]; + +/** + * An in-line alert with a link and close button in the footer. Combine this strategy with any variant. + */ +export const WithFooterLinkAndClosable = AlertsWithStyleOptions.bind({}); +WithFooterLinkAndClosable.args = { + hasLink: true, + isClosable: true, + text: "Click the link or close the alert", }; -Closable.parameters = { +WithFooterLinkAndClosable.parameters = { chromatic: { disableSnapshot: true }, }; -Closable.tags = ["!dev"]; +WithFooterLinkAndClosable.tags = ["!dev"]; // ********* VRT ONLY ********* // export const WithForcedColors = InlineAlertGroup.bind({}); diff --git a/components/inlinealert/stories/inlinealert.test.js b/components/inlinealert/stories/inlinealert.test.js index 4f74e3bad08..4aa070b4a6f 100644 --- a/components/inlinealert/stories/inlinealert.test.js +++ b/components/inlinealert/stories/inlinealert.test.js @@ -12,6 +12,7 @@ export const InlineAlertGroup = Variants({ })), { testHeading: "Truncation", + variant: "info", headerText: "In-line alert header announcing something very long and in-line", text: "This is a very urgent alert with a lot of context, so the text has to wrap.", customStyles: {"max-width": "400px"} @@ -22,5 +23,58 @@ export const InlineAlertGroup = Variants({ testHeading: "Closable", isClosable: true, }, + { + testHeading: "Without header", + withoutHeader: true, + }, + { + testHeading: "Link", + hasLink: true, + }, + { + testHeading: "Link + closable", + isClosable: true, + hasLink: true, + }, + { + testHeading: "Subtle", + treatment: "subtle", + }, + { + testHeading: "Bold", + treatment: "bold", + }, + { + testHeading: "Subtle + closable", + treatment: "subtle", + isClosable: true, + }, + { + testHeading: "Subtle + link + closable", + treatment: "subtle", + isClosable: true, + hasLink: true, + }, + { + testHeading: "Bold + closable", + treatment: "bold", + isClosable: true, + }, + { + testHeading: "Subtle + link", + treatment: "subtle", + hasLink: true, + }, + { + testHeading: "Bold + link", + treatment: "bold", + hasLink: true, + }, + { + testHeading: "Bold + link + closable", + treatment: "bold", + isClosable: true, + hasLink: true, + }, ], }); diff --git a/components/inlinealert/stories/template.js b/components/inlinealert/stories/template.js index f5439cf8c4d..c2233414253 100644 --- a/components/inlinealert/stories/template.js +++ b/components/inlinealert/stories/template.js @@ -1,8 +1,10 @@ import { Template as Button } from "@spectrum-css/button/stories/template.js"; import { Template as Icon } from "@spectrum-css/icon/stories/template.js"; +import { Template as Link } from "@spectrum-css/link/stories/template.js"; import { html, nothing } from "lit"; import { classMap } from "lit/directives/class-map.js"; import { styleMap } from "lit/directives/style-map.js"; +import { Container } from "@spectrum-css/preview/decorators"; import "../index.css"; @@ -12,21 +14,26 @@ export const Template = ({ customStyles = {}, headerText, text, + withoutHeader = false, variant = "neutral", + treatment = "border", isClosable = false, + hasLink = false, } = {}, context = {}) => { let iconName; switch (variant) { case "info": - iconName = "Info"; + iconName = "InfoCircle"; break; case "positive": iconName = "CheckmarkCircle"; break; case "notice": + iconName = "AlertDiamond"; + break; case "negative": case "closable": - iconName = "Alert"; + iconName = "AlertTriangle"; break; default: iconName = undefined; @@ -40,6 +47,24 @@ export const Template = ({ customClasses: [`${rootClass}-icon`], }, context) : nothing; + + const titleMarkup = !withoutHeader ? html` +
+ ${headerText} + ${iconMarkup} +
+ ` : nothing; + + const linkMarkup = hasLink ? html` + + ` : nothing; + const closableMarkup = isClosable ? html` ` : nothing; @@ -57,17 +83,53 @@ export const Template = ({ class=${classMap({ [rootClass]: true, [`${rootClass}--${variant}`]: typeof variant !== "undefined", + [`${rootClass}--${treatment}`]: treatment !== "border", ...customClasses.reduce((a, c) => ({ ...a, [c]: true }), {}), })} style=${styleMap(customStyles)} > -
- ${headerText} - ${iconMarkup} + ${titleMarkup} +
+ ${text} + ${withoutHeader ? iconMarkup : nothing}
-
${text}
+ ${linkMarkup} ${closableMarkup}
`; }; + +/** + * Convert provided string to title case + */ +const toTitleCase = (string) => string.replace(/\w\S*/g, text => text.charAt(0).toUpperCase() + text.substring(1).toLowerCase()); + +/** + * Set the appropriate treatment header text + */ +const setTreatmentHeaderText = (variant, treatment) => `${toTitleCase(variant)} variant with ${treatment !== "border" ? treatment : "outline"} fill`; + +export const AlertsWithStyleOptions = (args, context = {}) => Container({ + withBorder: false, + direction: "row", + wrapperStyles: { + columnGap: "12px", + }, + content: [ + Template({ + ...args, + headerText: setTreatmentHeaderText(args.variant, "border"), + }, context), + Template({ + ...args, + treatment: "subtle", + headerText: setTreatmentHeaderText(args.variant, "subtle"), + }, context), + Template({ + ...args, + treatment: "bold", + headerText: setTreatmentHeaderText(args.variant, "bold"), + }, context), + ], +}, context);