diff --git a/.changeset/two-forks-kiss.md b/.changeset/two-forks-kiss.md new file mode 100644 index 000000000..2bd3815d6 --- /dev/null +++ b/.changeset/two-forks-kiss.md @@ -0,0 +1,5 @@ +--- +'@cloudfour/patterns': minor +--- + +Add optional icon and floating modifier to the Alert component diff --git a/src/assets/icons/cloud-slash.svg b/src/assets/icons/cloud-slash.svg new file mode 100644 index 000000000..b84cf5853 --- /dev/null +++ b/src/assets/icons/cloud-slash.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/src/components/alert/alert.scss b/src/components/alert/alert.scss index acd206eb9..6e9c4cf29 100644 --- a/src/components/alert/alert.scss +++ b/src/components/alert/alert.scss @@ -1,4 +1,6 @@ +@use '../../compiled/tokens/scss/breakpoint'; @use '../../compiled/tokens/scss/color'; +@use 'sass:color' as sass-color; @use '../../compiled/tokens/scss/ease'; @use '../../compiled/tokens/scss/scale'; @use '../../compiled/tokens/scss/size'; @@ -6,6 +8,17 @@ @use '../../mixins/border-radius'; @use '../../mixins/focus'; @use '../../mixins/ms'; +@use '../../mixins/theme'; + +@include theme.props() { + --theme-color-background-icon: #{lighten(color.$base-orange, 30%)}; + --theme-color-icon: #{color.$base-orange}; +} + +@include theme.props(dark) { + --theme-color-background-icon: #{color.$base-orange}; + --theme-color-icon: #{lighten(color.$base-orange, 30%)}; +} .c-alert { background: var(--theme-color-background-secondary); @@ -29,15 +42,69 @@ display: grid; grid-column-gap: ms.step(1); grid-template-areas: - '. . dismiss' - '. content dismiss' - '. . dismiss'; - grid-template-columns: 0 1fr minmax(0, auto); + 'icon . dismiss' + 'icon content dismiss' + 'icon . dismiss'; + grid-template-columns: minmax(0, auto) 1fr minmax(0, auto); grid-template-rows: ms.step(-1) minmax(0, auto) ms.step(-1); margin: 0 auto; max-width: size.$max-width-spread; } +// Adds a box shadow to add the appearance of the alert floating +// above the containers below. Floating has a white background for higher +// contrast between the background and the shadow. +.c-alert--floating { + box-shadow: 0 0 0 size.$edge-medium var(--theme-color-shadow-inner), + size.$edge-large size.$edge-large 0 size.$edge-medium + var(--theme-color-shadow-outer); + @include theme.styles() { + --theme-color-shadow-inner: #{sass-color.change( + color.$brand-primary-darker, + $alpha: 0.2 + )}; + --theme-color-shadow-outer: #{sass-color.change( + color.$brand-primary-darker, + $alpha: 0.1 + )}; + } + @include theme.styles(dark) { + --theme-color-shadow-inner: #{sass-color.change( + color.$brand-primary-darker, + $alpha: 0.6 + )}; + --theme-color-shadow-outer: #{sass-color.change( + color.$brand-primary-darker, + $alpha: 0.4 + )}; + } +} + +/** + * 1. This number was chosen because in combination with the usual + * single-line height of the element, it makes a perfect square. + */ +.c-alert__extra { + --icon-size: #{size.$icon-medium}; + align-items: center; + background-color: var(--theme-color-background-icon); + border-bottom-left-radius: size.$border-radius-medium; + border-top-left-radius: size.$border-radius-medium; + color: var(--theme-color-icon); + display: flex; + grid-area: icon; + justify-content: center; + width: ms.step(5); /* 1 */ + + // On large screens, when the alert content reaches it's max width and + // the icon no longer touches the edge of its container, we change the + // icon style so it's self contained. + @media (min-width: breakpoint.$xxl) { + border: ms.step(-4) solid var(--theme-color-background-secondary); + border-radius: size.$border-radius-full; + } +} + .c-alert__content { grid-area: content; } diff --git a/src/components/alert/alert.stories.mdx b/src/components/alert/alert.stories.mdx index 0c8b222ab..b43bee014 100644 --- a/src/components/alert/alert.stories.mdx +++ b/src/components/alert/alert.stories.mdx @@ -66,10 +66,66 @@ Alerts work well even when displayed at full width. Their contents will constrai +## Icon + +An option to add an icon to the alert. You can add any icon name from our library in the `icon` property. Right now, the color is hardcoded to orange to satisfy the current use case of our offline notification, but it would be nice to add more color options in the future. + + + + {(args) => template(args)} + + + +## Floating + +By adding `floating: true`, a light border and shadow will be added to the alert for a floating effect. The background is white to improve the contrast between the border, shadow and background. In the future, we could make it a possibility to change the background color by itself. + + + + {(args) => template(args)} + + + +When more contrast is desired, you may also attach a theme class to the the floating variation. In this example, the card has a class of `t-light` within a `t-dark` container: + + + + {(args) => template(args)} + + + ## Template Properties - `class` (string) +- `icon` (string) - `dismissable` (boolean, default `false`) +- `floating` (boolean, default `false`) - `message` (string, default `'Hello world!'`) - `tag_name` (string, default `'div'`) diff --git a/src/components/alert/alert.twig b/src/components/alert/alert.twig index 7c4cca156..eeb96322f 100644 --- a/src/components/alert/alert.twig +++ b/src/components/alert/alert.twig @@ -1,7 +1,23 @@ {% set tag_name = tag_name|default('div') %} -<{{ tag_name }} class="c-alert{% if class %} {{ class }}{% endif %}"> +{% set _icon_block %} + {% block icon %} + {% if icon %} + {% include '@cloudfour/components/icon/icon.twig' with { + name: icon, + aria_hidden: true + } only %} + {% endif %} + {% endblock %} +{% endset %} + +<{{ tag_name }} class="c-alert{% if floating %} c-alert--floating{% endif %}{% if class %} {{ class }}{% endif %}">
+ {% if _icon_block|trim is not empty %} + + {{_icon_block}} + + {% endif %}
{% block content %}

diff --git a/src/prototypes/single-page/example/example.scss b/src/prototypes/single-page/example/example.scss index e9afcd292..1f4b6fa7d 100644 --- a/src/prototypes/single-page/example/example.scss +++ b/src/prototypes/single-page/example/example.scss @@ -1,9 +1,22 @@ @use "../../../mixins/ms"; @use "../../../compiled/tokens/scss/size"; +@use "../../../compiled/tokens/scss/breakpoint"; + #single-page { .main-container { padding-top: ms.step(6); padding-bottom: ms.step(6); + position: relative; + } + + .alert-container { + position: absolute; + top: -.5em; + left: 10%; + @media (min-width: breakpoint.$l) { + top: -1.5em; + left: 35%; + } } } diff --git a/src/prototypes/single-page/example/example.twig b/src/prototypes/single-page/example/example.twig index 1317cbdf1..7366f2876 100644 --- a/src/prototypes/single-page/example/example.twig +++ b/src/prototypes/single-page/example/example.twig @@ -39,6 +39,21 @@ {% embed '@cloudfour/objects/container/container.twig' with { class: 'o-container--prose o-container--pad main-container'} %} {% block content %} + + + {% embed '@cloudfour/components/alert/alert.twig' with { + dismissable: true, + floating: true, + icon: 'cloud-slash', + class: 'alert-container' + } only %} + {% block content %} +

+ You appear to be offline. Try again. +

+ {% endblock %} + {% endembed %} + {% embed '@cloudfour/objects/rhythm/rhythm.twig' with { class: 'o-rhythm--generous-headings' } %} {% block content %}