Card
A card is a summary representation of a piece of content and typically is used in a horizontal row or grid of related content.
- Install
npm install @pluralsight/ps-design-system-card
- Import
import Avatar from '@pluralsight/ps-design-system-card'
Examples
In-app example
The card is a flexible component that will fit the container it's given. A gallery is a common container layout that one might encounter in the product. This is an example implementation of how the Card might look in a gallery in your app, using the Layout.EqualColumnLayout component.
import Avatar from '@pluralsight/ps-design-system-avatar'import Card from '@pluralsight/ps-design-system-card'import { BookmarkIcon, MoreIcon, PathIcon, PlayCircleIcon } from '@pluralsight/ps-design-system-icon'import { EqualColumnLayout } from '@pluralsight/ps-design-system-layout'function Example() {return (<EqualColumnLayout><ul><li><Cardtag={<Card.Tag icon={<PathIcon />}>Path</Card.Tag>}title={<Card.Title>Advanced TypeScript</Card.Title>}progress={0}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}metadata1={['Brice Wilson', 'Advanced']}metadata2={['0m watched']}size={Card.sizes.small}/></li><li><CardbonusBar={<Avatar size={Avatar.sizes.xSmall} name="Jake Trent" />}title={<Card.Title>Getting Started with Reactive Programming Using RxJS</Card.Title>}progress={20}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}metadata1={['Scott Allen', 'Intermediate']}metadata2={['23m watched']}size={Card.sizes.small}/></li><li><CardactionBar={[<Card.Actionkey="1"title="Book action"icon={<BookmarkIcon />}/>,<Card.Action key="2" title="More action" icon={<MoreIcon />} />]}title={<Card.Title>Building a JavaScript Development Environment"</Card.Title>}fullOverlay={<Card.FullOverlayLink><a><PlayCircleIcon size={PlayCircleIcon.sizes.large} /></a></Card.FullOverlayLink>}progress={67}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}metadata1={['Cory House', 'Intermediate']}metadata2={['3h 23m watched']}size={Card.sizes.small}/></li><li><CardactionBar={[<Card.Actionkey="1"title="Bookmark action"icon={<BookmarkIcon />}/>,<Card.Action key="2" title="More action" icon={<MoreIcon />} />]}actionBarVisibletitle={<Card.Title>Webpack Fundamentals"</Card.Title>}progress={100}metadata1={['Joe Eames', 'Intermediate']}metadata2={['90m watched']}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}size={Card.sizes.small}/></li></ul></EqualColumnLayout>)}export default Example
Size
While the component is flexible, the size will determine certain base proportions and flexibility min and max bounds.
import Card from '@pluralsight/ps-design-system-card'import React from 'react'function Example() {return (<div className="example-grid--spaced"><div style={{ maxWidth: '540px' }}><Cardsize={Card.sizes.large}title={<Card.Title>Large card</Card.Title>}metadata1={['Jim Cooper']}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}/></div><div style={{ maxWidth: '320px' }}><Cardsize={Card.sizes.medium}title={<Card.Title>Medium card</Card.Title>}metadata1={['Jim Cooper']}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}/></div><div style={{ maxWidth: '140px' }}><Cardsize={Card.sizes.small}title={<Card.Title>Small card</Card.Title>}metadata1={['Jim Cooper']}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}/></div></div>)}export default Example
Image
The image will cover the space given. This space is variable width but set height according to the size
property.
To ensure screen-readable text, always pass aria-label
for the image description.
import Button from '@pluralsight/ps-design-system-button'import Card from '@pluralsight/ps-design-system-card'import { BookmarkIcon } from '@pluralsight/ps-design-system-icon'import React from 'react'function Example() {return (<div style={{ maxWidth: '320px' }}><Cardimage={<Card.ImageLink><a href="https://google.com" target="_blank"><Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" /></a></Card.ImageLink>}title={<Card.Title>Linked image with other overlays</Card.Title>}actionBar={[<Card.Actionkey="1"title="Bookmark action"icon={<BookmarkIcon />}/>]}fullOverlay={<Card.FullOverlayLink><a href="https://google.com?q=full%20overlay" target="_blank">Full Overlay</a></Card.FullOverlayLink>}/></div>)}export default Example
Progress
Progress, if given, should be a number between 0 and 100 that describes the completion level of the content represented on the card.
import Card from '@pluralsight/ps-design-system-card'import React from 'react'function Example() {return (<div className="example-grid--col-2"><div style={{ width: '320px' }}><Cardprogress={25}title={<Card.Title>The Card Title</Card.Title>}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}/></div><div style={{ width: '320px' }}><Cardprogress={100}title={<Card.Title>The Card Title</Card.Title>}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}/></div></div>)}export default Example
Title
The title can be a string or a some other element, such as a link, that contains a string
Strings are line-clamped to 2 lines max, then the text will overflow with an ellipsis appended.
import Card from '@pluralsight/ps-design-system-card'import React from 'react'function Example() {return (<div className="example-grid--col-2"><div style={{ width: '320px' }}><Cardtitle={<Card.Title>Super Long Title of the Technology of the Century as Brought toYou By Tech Groupsoft in the Stunning Desert of British Lithuania</Card.Title>}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}/></div><div style={{ width: '320px' }}><Cardtitle={<Card.TextLink><a><Card.Title>Link with Super Long Title of the Technology of the Century asBrought to You By Tech Groupsoft in the Stunning Desert ofBritish Lithuania</Card.Title></a></Card.TextLink>}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}/></div></div>)}export default Example
Metadata
Metadata is free-form strings or displayable elements like links. Each bit of metadata is separated by an interpunct.
Metadata is constrained to a single line, overflowing with an ellipsis indicated. The first datum is given display space precedence.
import Card from '@pluralsight/ps-design-system-card'import React from 'react'function Example() {return (<div className="example-grid--col-2"><div style={{ width: '320px' }}><Cardmetadata1={['Simon Allardice']}metadata2={['Intermediate', '2h 20m', 'July 24, 1847']}title={<Card.Title>Card with Two Lines of Meta</Card.Title>}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}/></div><div style={{ width: '320px' }}><Cardmetadata1={[<Card.TextLink><a href="https://google.com?query=simon%20allardice">The Honorable Simon Allardice Hailing From Shores Abroad</a></Card.TextLink>]}metadata2={['Only about the Best Level in the World for Learning','2h 20m or longer depending',"July 24, 1847 or year thereabouts, it's unclear"]}title={<Card.Title>Super-long Metadata</Card.Title>}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}/></div></div>)}export default Example
Action bar
The action bar contains the on-card affordances a user can take besides linking straight to the content. These are usually buttons.
import Card from '@pluralsight/ps-design-system-card'import { BookmarkIcon, MoreIcon } from '@pluralsight/ps-design-system-icon'import React from 'react'function Example() {return (<div style={{ width: '320px' }}><CardactionBar={[<Card.Action title="Bookmark action" icon={<BookmarkIcon />} />,<Card.Action title="More action" icon={<MoreIcon />} />]}actionBarVisibletitle={<Card.Title>Action bar locked visible</Card.Title>}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}/></div>)}export default Example
Tag
The tag provides a label, usually categorizing the card's content.
import Card from '@pluralsight/ps-design-system-card'import { ChannelIcon } from '@pluralsight/ps-design-system-icon'import React from 'react'function Example() {return (<div style={{ width: '320px' }}><Cardtag={<Card.Tag icon={<ChannelIcon />}>Channel</Card.Tag>}title={<Card.Title>Icon and text on card</Card.Title>}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}/></div>)}export default Example
Full overlay
A special main action representing the main interaction for the card can be provided here. It will appear overlaid in the center of the image.
import Card from '@pluralsight/ps-design-system-card'import { BookmarkIcon, ChannelIcon } from '@pluralsight/ps-design-system-icon'import React from 'react'function Example() {return (<div style={{ width: '320px' }}><CardfullOverlay={<Card.FullOverlayLink><a>Custom Thing</a></Card.FullOverlayLink>}actionBar={[<Card.Action title="Bookmark action" icon={<BookmarkIcon />} />]}tag={<Card.Tag icon={<ChannelIcon />}>Channel</Card.Tag>}title={<Card.Title>Combined with other overlays</Card.Title>}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}/></div>)}export default Example
Bonus bar
Some cards may make use of a freeform area of content overlaid in the bottom-left corner of the image area. Use with dignity.
import Card from '@pluralsight/ps-design-system-card'import React from 'react'function Example() {return (<div style={{ width: '320px' }}><CardbonusBar={<div>Just bonus</div>}title={<Card.Title>Custom elements in lower-left</Card.Title>}image={<Card.Image src="https://picsum.photos/seed/picsum/540/360" aria-label="img desc" />}/></div>)}export default Example
Accessibility
WCAG 2.1 AA Compliance
100% axe-core testsManual audit
Props
Card
Name | Type | Description | Default |
---|---|---|---|
actionBar | Card.Action[] | top-right action buttons |
|
actionBarVisible | boolean | lock action bar on | false |
bonusBar | React.ReactNode | freeform space in image bottom-left |
|
fullOverlay | Card.FullOverlayLink | hover state for image |
|
fullOverlayVisible | boolean | lock full overlay on | false |
image Required | Card.Image | Card.ImageLink > a > Card.Image | main image or linked image |
|
metadata1 | string[] | React.ReactNode[] | first row of metadata |
|
metadata2 | string[] | React.ReactNode[] | second row of metadata |
|
progress | number | progress 0-100 |
|
size |
| size of card (from Card.sizes) | medium |
tag | Card.Tag | categorization label in top-left |
|
title Required | Card.TextLink > a > Card.Title | Card.Title | card title or linked title |
|
Card.Action
Name | Type | Description | Default |
---|---|---|---|
icon Required | Icon | icon representing action |
|
title Required |
|
|
Card.Image
Name | Type | Description | Default |
---|---|---|---|
aria-label | string | screenreader label |
|
src Required | string | image url |
|
Card.Tag
Name | Type | Description | Default |
---|---|---|---|
icon | Icon | tag icon |
|