From 76051bbd8bd647cb234878e07edc98939d90e43d Mon Sep 17 00:00:00 2001 From: Tyler Sticka Date: Fri, 9 Jul 2021 09:25:18 -0700 Subject: [PATCH] Replace Message with Alert, use in Comment (#1373) * Convert container padding values to tokens * Add Alert component * Remove Message component * Integrate alert into comment --- .changeset/neat-stingrays-fry.md | 5 + .changeset/tender-seas-film.md | 5 + src/components/alert/alert.scss | 91 +++++++++++++++++++ src/components/alert/alert.stories.mdx | 81 +++++++++++++++++ src/components/alert/alert.twig | 23 +++++ src/components/comment/comment.stories.mdx | 11 ++- src/components/comment/comment.twig | 5 + src/components/comment/demo/data.ts | 7 +- .../message/demo/default-message.twig | 8 -- src/components/message/message.scss | 67 -------------- src/components/message/message.stories.mdx | 30 ------ src/components/message/message.twig | 21 ----- src/objects/container/container.scss | 5 +- src/tokens/size/padding.js | 12 ++- 14 files changed, 239 insertions(+), 132 deletions(-) create mode 100644 .changeset/neat-stingrays-fry.md create mode 100644 .changeset/tender-seas-film.md create mode 100644 src/components/alert/alert.scss create mode 100644 src/components/alert/alert.stories.mdx create mode 100644 src/components/alert/alert.twig delete mode 100644 src/components/message/demo/default-message.twig delete mode 100644 src/components/message/message.scss delete mode 100644 src/components/message/message.stories.mdx delete mode 100644 src/components/message/message.twig diff --git a/.changeset/neat-stingrays-fry.md b/.changeset/neat-stingrays-fry.md new file mode 100644 index 000000000..c3c3da4a2 --- /dev/null +++ b/.changeset/neat-stingrays-fry.md @@ -0,0 +1,5 @@ +--- +'@cloudfour/patterns': minor +--- + +Show alert in unapproved comments diff --git a/.changeset/tender-seas-film.md b/.changeset/tender-seas-film.md new file mode 100644 index 000000000..d0fde809d --- /dev/null +++ b/.changeset/tender-seas-film.md @@ -0,0 +1,5 @@ +--- +'@cloudfour/patterns': major +--- + +Replace Message component with Alert component that takes into account inline and full-width use cases and responds to themes diff --git a/src/components/alert/alert.scss b/src/components/alert/alert.scss new file mode 100644 index 000000000..360f1f8fe --- /dev/null +++ b/src/components/alert/alert.scss @@ -0,0 +1,91 @@ +@use '../../compiled/tokens/scss/color'; +@use '../../compiled/tokens/scss/ease'; +@use '../../compiled/tokens/scss/scale'; +@use '../../compiled/tokens/scss/size'; +@use '../../compiled/tokens/scss/transition'; +@use '../../mixins/focus'; +@use '../../mixins/ms'; + +.c-alert { + background: var(--theme-color-background-secondary); + border-radius: size.$border-radius-medium; + color: var(--theme-color-text-emphasis); +} + +/// When alert is meant to span the full viewport width, we omit its rounded +/// corners to avoid awkward counter spaces where the background shows through +/// those corners. +.c-alert--full-width { + border-radius: 0; +} + +/// We use a separate inner element so we can constrain it when the alert is +/// full-width without having to factor in the size of the optional dismissal +/// control. +/// +/// We lay out elements using CSS Grid to avoid relying on negative margins +/// so that the dismissal control's interactive area will reach the element's +/// edges. +/// +/// The spacing here involves more "magic" numbers than I wanted it to, but +/// since the default container is pretty subtle neither the standard container +/// padding nor control padding felt quite right. We may want to revisit that +/// in the future. +.c-alert__inner { + display: grid; + grid-column-gap: ms.step(1); + grid-template-areas: + '. . dismiss' + '. content dismiss' + '. . dismiss'; + grid-template-columns: 0 1fr minmax(0, auto); + grid-template-rows: ms.step(-1) minmax(0, auto) ms.step(-1); + + /// We only bother constraining this element when it's full-width. + .c-alert--full-width & { + margin: 0 auto; + max-width: size.$max-width-spread; + } +} + +.c-alert__content { + grid-area: content; +} + +/// Reset the dismissal button's appearance and center-align its content +.c-alert__dismiss { + align-items: center; + appearance: none; + background: transparent; + border: 0; + border-radius: size.$border-radius-medium; + color: inherit; + cursor: pointer; + display: flex; + font: inherit; + grid-area: dismiss; + justify-content: center; + margin: 0; + // This is a magic number but it just feels right, y'know? + min-width: ms.step(5); + padding: 0; + + @include focus.focus-visible { + box-shadow: 0 0 0 size.$edge-large color.$brand-primary-lighter; + } +} + +/// We apply the transition effects to the icon so the button itself won't break +/// outside of the alert, which is particularly important when it's full-width. +.c-alert__dismiss-icon { + transition: filter transition.$slow ease.$out, + transform transition.$quick ease.$out; + + .c-alert__dismiss:hover & { + transform: scale(scale.$effect-grow); + } + + .c-alert__dismiss:active & { + transform: scale(scale.$effect-shrink); + } +} diff --git a/src/components/alert/alert.stories.mdx b/src/components/alert/alert.stories.mdx new file mode 100644 index 000000000..d864274ac --- /dev/null +++ b/src/components/alert/alert.stories.mdx @@ -0,0 +1,81 @@ +import { Story, Canvas, Meta } from '@storybook/addon-docs/blocks'; +import template from './alert.twig'; + + + +# Alert + +A simple container for displaying important messages to the user such as errors, changes in state or confirmation of actions taken. + +## Status + +This component is still a work in progress. The following features are not yet implemented: + +- The dismissal control does not actually dismiss the alert. + +## Basic usage + + + + {(args) => template(args)} + + + +## Dismissable + +When `dismissable` is `true`, a close button will display to the right of the message. + + + + {(args) => template(args)} + + + +## Full width + +By default, alerts assume they'll display within page content. For alerts meant to fill the full browser width, use the `c-alert--full-width` modifier class or set the `full_width` template property to `true`. This removes the rounded corners (which would awkwardly interact with viewport edges) and constrains the content to the value of [our `size.$max-width-spread` token](/docs/design-tokens-layout--page). + + + + {(args) => template(args)} + + + +## Template Properties + +- `class` (string) +- `dismissable` (boolean, default `false`) +- `full_width` (boolean, default `false`) +- `message` (string, default `'Hello world!'`) +- `tag_name` (string, default `'div'`) + +## Template Blocks + +- `content` diff --git a/src/components/alert/alert.twig b/src/components/alert/alert.twig new file mode 100644 index 000000000..0614e2cbf --- /dev/null +++ b/src/components/alert/alert.twig @@ -0,0 +1,23 @@ +{% set tag_name = tag_name|default('div') %} + +<{{ tag_name }} class="c-alert{% if full_width %} c-alert--full-width{% endif %}{% if class %} {{ class }}{% endif %}"> +
+
+ {% block content %} +

+ {{message|default('Hello world!')}} +

+ {% endblock %} +
+ {% if dismissable %} + + {% endif %} +
+ diff --git a/src/components/comment/comment.stories.mdx b/src/components/comment/comment.stories.mdx index 360303b0c..ed148d160 100644 --- a/src/components/comment/comment.stories.mdx +++ b/src/components/comment/comment.stories.mdx @@ -13,7 +13,6 @@ Displays a single comment in a comment thread, optionally with replies. Multiple This component is still a work in progress. The following features are still in development: - Indicating when a comment's author is a Cloud Four team member. -- Displaying a message when a comment is not yet approved. - Integrating the comment reply form. - Adding blocks to the template to allow for more customization. @@ -33,6 +32,16 @@ This information may be passed to the component as a `comment` object matching t {template({ comment: makeComment() })} +## Unapproved + +If `comment.approved` is not `true`, an [Alert](/docs/components-alert--basic) will indicate that the comment is not yet approved. + + + + {template({ comment: makeComment({ approved: false }) })} + + + ## With source Additionally, a `source` object may be passed to the template consisting of a `url` and `name`. This is helpful if integrating [webmentions](https://indieweb.org/Webmention) into comment threads. diff --git a/src/components/comment/comment.twig b/src/components/comment/comment.twig index c3eaac55d..cde6507a3 100644 --- a/src/components/comment/comment.twig +++ b/src/components/comment/comment.twig @@ -19,6 +19,11 @@ class: 'c-comment__content o-rhythm--condensed' } %} {% block content %} + {% if not comment.approved %} + {% include '@cloudfour/components/alert/alert.twig' with { + message: 'This comment is awaiting moderation.' + } only %} + {% endif %} {{comment.comment_content|raw}} {% endblock %} {% endembed %} diff --git a/src/components/comment/demo/data.ts b/src/components/comment/demo/data.ts index e9e170d16..66b8c0096 100644 --- a/src/components/comment/demo/data.ts +++ b/src/components/comment/demo/data.ts @@ -75,7 +75,11 @@ const placeImgCategories = ['animals', 'arch', 'nature', 'people', 'tech']; const jabber = new Jabber(themeWords, 1.5); -export const makeComment = ({ isChild = false, replies = 0 } = {}) => { +export const makeComment = ({ + isChild = false, + replies = 0, + approved = true, +} = {}) => { const id = uniqueId(); const paragraphs = []; const paragraphCount = random(1, 2); @@ -95,6 +99,7 @@ export const makeComment = ({ isChild = false, replies = 0 } = {}) => { comment_content: content, is_child: isChild, children: [] as any, + approved, }; if (replies > 0) { diff --git a/src/components/message/demo/default-message.twig b/src/components/message/demo/default-message.twig deleted file mode 100644 index f240ab5c3..000000000 --- a/src/components/message/demo/default-message.twig +++ /dev/null @@ -1,8 +0,0 @@ -{% embed '@cloudfour/components/message/message.twig' %} - {% block content %} -

- {{label|default('Messages contain short, concise information used to highlight important - information.')}} -

- {% endblock %} -{% endembed %} diff --git a/src/components/message/message.scss b/src/components/message/message.scss deleted file mode 100644 index 25500ca3d..000000000 --- a/src/components/message/message.scss +++ /dev/null @@ -1,67 +0,0 @@ -@use "../../compiled/tokens/scss/brightness"; -@use "../../compiled/tokens/scss/color"; -@use "../../compiled/tokens/scss/ease"; -@use "../../compiled/tokens/scss/line-height"; -@use "../../compiled/tokens/scss/transition"; -@use "../../compiled/tokens/scss/scale"; -@use "../../compiled/tokens/scss/size"; -@use "../../mixins/focus"; -@use "../../mixins/ms"; - -/** - * 1. Push message and close button as far apart as possible. - * 2. When text breaks onto multiple lines our default line-height visually - * competes with this element's padding, so we condense it a little. - */ - -.c-message { - background-color: color.$base-gray-lighter; - color: color.$text-dark; - display: flex; /* 1 */ - justify-content: space-between; /* 1 */ - line-height: line-height.$tight; /* 2 */ -} - -.c-message__content { - padding: ms.step(1); -} - -/** - * 1. Transparent background and inherited text color promote harmony with - * adjacent text and won't compete with any adjacent calls to action. - * 2. To add a little visual emphasis, make icon a little larger than the - * parent text size. - * 3. To prevent the message text from colliding with to the close button, - * we add some space between the message and the button. - */ - -.c-message__close { - align-items: center; - background-color: inherit; /* 1 */ - border-radius: size.$border-radius-medium; - border-width: 0; - color: inherit; /* 1 */ - cursor: pointer; - display: flex; - font-size: size.$font-big; /* 2 */ - margin-left: ms.step(1); /* 3 */ - padding: 0 ms.step(1); - - @include focus.focus-visible { - box-shadow: 0 0 0 size.$edge-large color.$brand-primary-lighter; - } -} - -.c-message__close-icon { - transition: filter transition.$slow ease.$out, - transform transition.$quick ease.$out; -} - -.c-message__close:hover .c-message__close-icon { - transform: scale(scale.$effect-grow); -} - -.c-message__close:active .c-message__close-icon { - filter: brightness(brightness.$control-dim); - transform: scale(scale.$effect-shrink); -} diff --git a/src/components/message/message.stories.mdx b/src/components/message/message.stories.mdx deleted file mode 100644 index 65e4a0740..000000000 --- a/src/components/message/message.stories.mdx +++ /dev/null @@ -1,30 +0,0 @@ -import { Story, Canvas, Meta } from '@storybook/addon-docs/blocks'; -import messageDemo from './demo/default-message.twig'; -import './message.scss'; - - - -# Message - -A containing element intended for short, actionable user messages. Originally -designed to notify the user of offline network connection status. - - - {(args) => messageDemo(args)} - - -## Message with close button - -Most messages should allow users to dismiss them with a close button. - - - - {(args) => messageDemo(args)} - - diff --git a/src/components/message/message.twig b/src/components/message/message.twig deleted file mode 100644 index 701418541..000000000 --- a/src/components/message/message.twig +++ /dev/null @@ -1,21 +0,0 @@ -{% set tag_name = tag_name | default('div') %} - -<{{ tag_name }} class="c-message{% if class %} {{ class }}{% endif %}"> -
- {% block content %} -

- {{ label|default('Hi, I\'m a message!') }} -

- {% endblock %} -
- {% if include_close %} - - {% endif %} - diff --git a/src/objects/container/container.scss b/src/objects/container/container.scss index 34ea04155..f77d2dedb 100644 --- a/src/objects/container/container.scss +++ b/src/objects/container/container.scss @@ -1,12 +1,11 @@ @use "../../compiled/tokens/scss/breakpoint"; @use "../../compiled/tokens/scss/size"; @use "../../mixins/fluid"; -@use '../../mixins/ms'; $pad-breakpoint-min: breakpoint.$s; $pad-breakpoint-max: breakpoint.$xl; -$pad-min: ms.step(-1, 1rem); -$pad-max: ms.step(3, 1rem); +$pad-min: size.$padding-container-min; +$pad-max: size.$padding-container-max; /** * There are no default styles for `o-container`. It acts as a wrapper so that diff --git a/src/tokens/size/padding.js b/src/tokens/size/padding.js index afcd25f49..3c3b7aa1f 100644 --- a/src/tokens/size/padding.js +++ b/src/tokens/size/padding.js @@ -1,4 +1,4 @@ -const { modularEm } = require('../../scripts/modular-scale'); +const { modularEm, modularRem } = require('../../scripts/modular-scale'); module.exports = { size: { @@ -17,6 +17,16 @@ module.exports = { comment: 'Used for table cells or other repeating content rows.', }, }, + container: { + min: { + value: modularRem(-1), + comment: 'Minimum fluid padding for container objects.', + }, + max: { + value: modularRem(3), + comment: 'Maximum fluid padding for container objects.', + }, + }, }, }, };