-
{label}
-
{title}
+
+ {label &&
{label}
}
+ {title &&
{title}
}
+ {caption &&
{caption}
}
{children}
{secondaryButtonText && (
-
);
- 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..c67341a76f 100644
--- a/packages/experimental/src/components/Card/Card.stories.js
+++ b/packages/experimental/src/components/Card/Card.stories.js
@@ -6,10 +6,12 @@
//
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';
import { ArrowRight24, Cloud32 } from '@carbon/icons-react';
+import { AspectRatio } from 'carbon-components-react';
import {
storybookPrefixCanary as storybookPrefix /* , storybookPrefixReleased */,
} from '../../../config';
@@ -24,19 +26,24 @@ 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: '1x1',
+ control: {
+ type: 'select',
+ options: ['16x9', '9x16', '2x1', '1x2', '4x3', '3x4', '1x1'],
},
},
},
decorators: [
(Story) => (
-
+
),
@@ -58,30 +65,61 @@ 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, ...args } = opts;
+ const colClasses = cx(`bx--col-${columnSize}`);
+ return (
+
+
{children}
- );
- }
- return
{cardsArray.map((c) => c)}
;
+
+ );
+};
+
+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,
- media:
,
};
-export const MediaLeft = Template.bind({});
+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 = MediaTemplate.bind({});
+WithMedia.args = {
+ ...defaultProps,
+};
+
+export const MediaLeft = MediaTemplate.bind({});
MediaLeft.args = {
...defaultProps,
mediaPosition: 'left',
- media:
,
- cols: 8,
+ columnSize: 'md-4',
};
export const WithActionIcon = Template.bind({});
@@ -97,12 +135,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 +149,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..cfe1f5071d 100644
--- a/packages/experimental/src/components/Card/_storybook-styles.scss
+++ b/packages/experimental/src/components/Card/_storybook-styles.scss
@@ -1,4 +1,6 @@
@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 +8,16 @@
#root {
width: 100%;
}
+
+// aspect ratio box styling
+.card-story .bx--aspect-ratio {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: $ui-03;
+}
+
+.#{$pkg-prefix}-card--media-left .#{$pkg-prefix}-card-media {
+ width: 100%;
+ max-width: 300px;
+}