From 53d5a78dd4055df625d641e39ed4f5a2e355399e Mon Sep 17 00:00:00 2001 From: David Menendez Date: Wed, 3 Mar 2021 08:41:47 -0600 Subject: [PATCH 1/2] fix: card design revisions v1 --- .../experimental/src/components/Card/Card.js | 44 ++++++----- .../src/components/Card/Card.stories.js | 79 ++++++++++++------- .../src/components/Card/_card.scss | 22 ++++++ .../components/Card/_storybook-styles.scss | 37 +++++++++ 4 files changed, 134 insertions(+), 48 deletions(-) diff --git a/packages/experimental/src/components/Card/Card.js b/packages/experimental/src/components/Card/Card.js index d0d436ca6a..824f0e4f32 100644 --- a/packages/experimental/src/components/Card/Card.js +++ b/packages/experimental/src/components/Card/Card.js @@ -6,9 +6,9 @@ import { pkgPrefix } from '../../global/js/settings'; export const Card = ({ actionIcon: ActionIcon, + caption, children, className, - href, label, media, mediaPosition, @@ -22,13 +22,16 @@ export const Card = ({ secondaryButtonText, title, }) => { - const cardClasses = cx({ - [`${pkgPrefix}-card`]: true, + const cardClasses = cx(`${pkgPrefix}-card`, { [`${pkgPrefix}-card--clickable`]: onClick, [`${pkgPrefix}-card--media-left`]: mediaPosition === 'left', className, }); + const headerClasses = cx(`${pkgPrefix}-card-header`, { + [`${pkgPrefix}-card-header--label-only`]: label && !title && !caption, + }); + const CardContent = (
{media &&
{media}
} @@ -38,19 +41,26 @@ export const Card = ({
)}
-
-

{label}

-

{title}

+
+ {label &&

{label}

} + {title &&

{title}

} + {caption &&

{caption}

}
{children}
{secondaryButtonText && ( - )} {primaryButtonText && ( - )} @@ -65,13 +75,7 @@ export const Card = ({
); - if (!href) return CardContent; - - return ( - - {CardContent} - - ); + return CardContent; }; Card.propTypes = { @@ -79,6 +83,10 @@ Card.propTypes = { * Icon to display in the bottom right of the card */ actionIcon: PropTypes.object, + /** + * Optional header caption + */ + caption: PropTypes.string, /** * Content that shows in the body of the card */ @@ -87,10 +95,6 @@ Card.propTypes = { * Optional user provided class */ className: PropTypes.string, - /** - * Providing an href turns the card into a clickable link - */ - href: PropTypes.string, /** * Optional label for the top of the card */ @@ -143,9 +147,9 @@ Card.propTypes = { Card.defaultProps = { actionIcon: null, + caption: '', children: '', className: '', - href: '', label: '', media: null, mediaPosition: 'top', diff --git a/packages/experimental/src/components/Card/Card.stories.js b/packages/experimental/src/components/Card/Card.stories.js index 1169b5759a..39e510ff0b 100644 --- a/packages/experimental/src/components/Card/Card.stories.js +++ b/packages/experimental/src/components/Card/Card.stories.js @@ -6,6 +6,7 @@ // import React from 'react'; +import cx from 'classnames'; import { Card } from '.'; import styles from './_storybook-styles.scss'; // import index in case more files are added later. import mdx from './Card.mdx'; @@ -24,13 +25,18 @@ export default { }, }, argTypes: { - cards: { - defaultValue: 1, + columnSize: { + defaultValue: 'lg-4', control: { - type: 'range', - min: 1, - max: 4, - step: 1, + type: 'select', + options: ['sm-4', 'md-4', 'lg-4', 'max-4'], + }, + }, + mediaRatio: { + defaultValue: '1:1', + control: { + type: 'select', + options: ['1:1', '3:2', '4:3', '16:9', '2:1'], }, }, }, @@ -58,30 +64,54 @@ const defaultProps = { }; const Template = (opts) => { - const { children, cols, cards, ...args } = opts; - const cardsArray = []; - for (let i = 0; i < cards; i++) { - cardsArray.push( -
+ const { children, columnSize, mediaRatio, ...args } = opts; + const colClasses = cx(`bx--col-${columnSize}`, { + // solution for dealing with image ratios. refer to _storybook-styles.scss + [`media-ratio-11`]: mediaRatio === '1:1', + [`media-ratio-32`]: mediaRatio === '3:2', + [`media-ratio-43`]: mediaRatio === '4:3', + [`media-ratio-169`]: mediaRatio === '16:9', + [`media-ratio-21`]: mediaRatio === '2:1', + }); + return ( +
+
{children}
- ); - } - return
{cardsArray.map((c) => c)}
; +
+ ); }; export const Default = Template.bind({}); Default.args = { ...defaultProps, - media: img, +}; + +export const LabelOnly = Template.bind({}); +LabelOnly.args = { + ...defaultProps, + title: '', +}; + +export const WithCaption = Template.bind({}); +WithCaption.args = { + ...defaultProps, + caption: 'Description or long caption', + label: '', +}; + +export const WithMedia = Template.bind({}); +WithMedia.args = { + ...defaultProps, + media:
, }; export const MediaLeft = Template.bind({}); MediaLeft.args = { ...defaultProps, mediaPosition: 'left', - media: img, - cols: 8, + media:
, + columnSize: 'md-4', }; export const WithActionIcon = Template.bind({}); @@ -97,12 +127,12 @@ WithPictogram.args = { pictogram: Cloud32, }; -export const WithSeondaryAction = Template.bind({}); -WithSeondaryAction.args = { +export const WithSecondaryAction = Template.bind({}); +WithSecondaryAction.args = { ...defaultProps, secondaryButtonText: 'Secondary', - secondaryButtonKind: 'secondary', - cols: 8, + secondaryButtonKind: 'ghost', + columnSize: 'md-4', }; export const ClickableCardWithOnclick = Template.bind({}); @@ -111,10 +141,3 @@ ClickableCardWithOnclick.args = { onClick: () => {}, primaryButtonText: '', }; - -export const ClickableCardWithLink = Template.bind({}); -ClickableCardWithLink.args = { - ...defaultProps, - href: '/', - primaryButtonText: '', -}; diff --git a/packages/experimental/src/components/Card/_card.scss b/packages/experimental/src/components/Card/_card.scss index 9992c9aff9..8fd5abf37a 100644 --- a/packages/experimental/src/components/Card/_card.scss +++ b/packages/experimental/src/components/Card/_card.scss @@ -9,6 +9,11 @@ .#{$pkg-prefix}-card--clickable { cursor: pointer; + transition: background $duration--fast-02; +} + +.#{$pkg-prefix}-card--clickable:hover { + background: $hover-ui; } .#{$pkg-prefix}-card--media-left { @@ -18,6 +23,7 @@ .#{$pkg-prefix}-card--media-left .#{$pkg-prefix}-card-content-container { display: flex; + flex: 1; flex-direction: column; } @@ -35,12 +41,28 @@ padding: $spacing-05; } +.#{$pkg-prefix}-card-header--label-only { + padding-bottom: $spacing-03; +} + +.#{$pkg-prefix}-card-header--label-only .#{$pkg-prefix}-card-label { + margin-bottom: 0; +} + .#{$pkg-prefix}-card-title { @include carbon--type-style('productive-heading-03'); } .#{$pkg-prefix}-card-label { @include carbon--type-style('label-01'); + + margin-bottom: $spacing-01; +} + +.#{$pkg-prefix}-card-caption { + @include carbon--type-style('caption-01'); + + margin-top: $spacing-01; } .#{$pkg-prefix}-card-body { diff --git a/packages/experimental/src/components/Card/_storybook-styles.scss b/packages/experimental/src/components/Card/_storybook-styles.scss index 9f9826a3cb..f08acb16c0 100644 --- a/packages/experimental/src/components/Card/_storybook-styles.scss +++ b/packages/experimental/src/components/Card/_storybook-styles.scss @@ -1,4 +1,8 @@ +/* stylelint-disable */ + @import './index'; +@import '../../global/styles/project-settings'; +@import '../../global/styles/carbon-settings'; // make the root full width to get a better idea of how the cards // look in a real grid situation @@ -6,3 +10,36 @@ #root { width: 100%; } + +// solution for image ratios- generate empty boxes to represent media + +.media-box { + width: 100%; + background: $ui-03; +} + +.media-ratio-11 .media-box { + padding-bottom: 100%; +} + +.media-ratio-43 .media-box { + padding-bottom: 75%; +} + +.media-ratio-32 .media-box { + padding-bottom: 66.66%; +} + +.media-ratio-169 .media-box { + padding-bottom: 56.25%; +} + +.media-ratio-21 .media-box { + padding-bottom: 50%; +} + +.media-box--left { + width: 300px; +} + +/* stylelint-enable */ From 97ab568ad42494f070578729c70b9d421b026b73 Mon Sep 17 00:00:00 2001 From: David Menendez Date: Wed, 3 Mar 2021 16:41:48 -0600 Subject: [PATCH 2/2] fix: card story aspect ratio update --- .../src/components/Card/Card.stories.js | 40 +++++++++++-------- .../components/Card/_storybook-styles.scss | 38 ++++-------------- 2 files changed, 32 insertions(+), 46 deletions(-) diff --git a/packages/experimental/src/components/Card/Card.stories.js b/packages/experimental/src/components/Card/Card.stories.js index 39e510ff0b..c67341a76f 100644 --- a/packages/experimental/src/components/Card/Card.stories.js +++ b/packages/experimental/src/components/Card/Card.stories.js @@ -11,6 +11,7 @@ import { Card } from '.'; import styles from './_storybook-styles.scss'; // import index in case more files are added later. import mdx from './Card.mdx'; import { ArrowRight24, Cloud32 } from '@carbon/icons-react'; +import { AspectRatio } from 'carbon-components-react'; import { storybookPrefixCanary as storybookPrefix /* , storybookPrefixReleased */, } from '../../../config'; @@ -33,16 +34,16 @@ export default { }, }, mediaRatio: { - defaultValue: '1:1', + defaultValue: '1x1', control: { type: 'select', - options: ['1:1', '3:2', '4:3', '16:9', '2:1'], + options: ['16x9', '9x16', '2x1', '1x2', '4x3', '3x4', '1x1'], }, }, }, decorators: [ (Story) => ( -
+
), @@ -64,15 +65,8 @@ const defaultProps = { }; const Template = (opts) => { - const { children, columnSize, mediaRatio, ...args } = opts; - const colClasses = cx(`bx--col-${columnSize}`, { - // solution for dealing with image ratios. refer to _storybook-styles.scss - [`media-ratio-11`]: mediaRatio === '1:1', - [`media-ratio-32`]: mediaRatio === '3:2', - [`media-ratio-43`]: mediaRatio === '4:3', - [`media-ratio-169`]: mediaRatio === '16:9', - [`media-ratio-21`]: mediaRatio === '2:1', - }); + const { children, columnSize, ...args } = opts; + const colClasses = cx(`bx--col-${columnSize}`); return (
@@ -82,6 +76,22 @@ const Template = (opts) => { ); }; +const MediaTemplate = (opts) => { + const { children, columnSize, mediaRatio, ...args } = opts; + const colClasses = cx(`bx--col-${columnSize}`); + return ( +
+
+ {mediaRatio}} + {...args}> + {children} + +
+
+ ); +}; + export const Default = Template.bind({}); Default.args = { ...defaultProps, @@ -100,17 +110,15 @@ WithCaption.args = { label: '', }; -export const WithMedia = Template.bind({}); +export const WithMedia = MediaTemplate.bind({}); WithMedia.args = { ...defaultProps, - media:
, }; -export const MediaLeft = Template.bind({}); +export const MediaLeft = MediaTemplate.bind({}); MediaLeft.args = { ...defaultProps, mediaPosition: 'left', - media:
, columnSize: 'md-4', }; diff --git a/packages/experimental/src/components/Card/_storybook-styles.scss b/packages/experimental/src/components/Card/_storybook-styles.scss index f08acb16c0..cfe1f5071d 100644 --- a/packages/experimental/src/components/Card/_storybook-styles.scss +++ b/packages/experimental/src/components/Card/_storybook-styles.scss @@ -1,5 +1,3 @@ -/* stylelint-disable */ - @import './index'; @import '../../global/styles/project-settings'; @import '../../global/styles/carbon-settings'; @@ -11,35 +9,15 @@ width: 100%; } -// solution for image ratios- generate empty boxes to represent media - -.media-box { - width: 100%; +// aspect ratio box styling +.card-story .bx--aspect-ratio { + display: flex; + align-items: center; + justify-content: center; background: $ui-03; } -.media-ratio-11 .media-box { - padding-bottom: 100%; -} - -.media-ratio-43 .media-box { - padding-bottom: 75%; -} - -.media-ratio-32 .media-box { - padding-bottom: 66.66%; -} - -.media-ratio-169 .media-box { - padding-bottom: 56.25%; -} - -.media-ratio-21 .media-box { - padding-bottom: 50%; -} - -.media-box--left { - width: 300px; +.#{$pkg-prefix}-card--media-left .#{$pkg-prefix}-card-media { + width: 100%; + max-width: 300px; } - -/* stylelint-enable */