packages/react-components/react-card/library/docs/Spec.md
A card's main function is to provide the scaffolding for hosting actions and content for a single topic within a card sized object. It is a framework for organizing content within the confines of a card.
The card itself should not have content or actions built in, but provide the mechanisms for it to be displayed.
Example:
<DocumentCard
aria-label="Default Document Card with large file name. Created by Annie Lindqvist a few minutes ago."
onClickHref="http://bing.com"
>
<DocumentCardPreview {...previewProps} />
<DocumentCardTitle title="Filename" />
<DocumentCardActivity activity="Created a few minutes ago" people={DocumentCardActivityPeople} />
</DocumentCard>
<Card>
<CardHeader>
<Flex gap="gap.small">
<Avatar
image="https://fabricweb.azureedge.net/fabric-website/assets/images/avatar/RobertTolbert.jpg"
label="Forward Division Analyst"
name="Lura Hermiston"
status="unknown"
/>
<Flex column>
<Text content="Lura Hermiston" weight="bold" />
<Text content="Forward Division Analyst" size="small" />
</Flex>
</Flex>
</CardHeader>
<CardBody>Sit quaerat dolorem quos sit et dolorem asperiores.</CardBody>
</Card>
Fabric's DocumentCard seems tied to a specific format, Office focused, while Northstar's Card is more generic. DocumentCard has components for each specific need of a card that displays documents as it offers image previews/file lists, user activity and other related things. Card goes for a more structural and generic approach to a card component and is closer to the vision for the v9 Card.
| Purpose | Fabric | Northstar | Matching? |
|---|---|---|---|
| Main component wrapper | DocumentCard | Card | ✅ |
| Component to add actions like sharing | DocumentCardActions | CardTopControls | ⚠️ |
| Component to render an image | DocumentCardImage | CardPreview | ⚠️ |
| Hybrid component to render an image preview for a document or list of documents. Possibly redundant with DocumentCardImage | DocumentCardPreview | ❌ | |
| Adds an icon/logo to the card | DocumentCardLogo | ❌ | |
| Wrapper for the right side of horizontal cards | DocumentCardDetails | ❌ | |
| Show document activity (user list) | DocumentCardActivity | ❌ | |
| Link element | DocumentCardLocation | ❌ | |
| Extra text component with a grayed out background | DocumentCardStatus | ❌ | |
| Header of the card | CardHeader | ❌ | |
| Body of the card | CardBody | ❌ | |
| Footer of the card | CardFooter | ❌ | |
| Wrapper to render in column format | CardColumn | ❌ | |
| Allows for content to expand on hover | CardExpandableBox | ❌ |
...
| Component | Purpose |
|---|---|
| Card | Wrapper for the main content of a card. |
| CardHeader | Optional header slot for the card. |
| CardPreview | Previewing the document/article presented in the card through an image |
| CardFooter | Optional footer slot for the card. (non-applicable for horizontal cards) |
<div role="group">
{children}
</div>
| Property | Values | Default | Purpose |
|---|---|---|---|
| orientation | vertical, horizontal | vertical | Orientation of the card |
| size | small, medium, large | medium | Define the minimum size of the card. Smaller sizes only apply to horizontal card |
| scale | fixed, auto-width, auto-height, auto, fluid-width, fluid-height, fluid | auto | Manages how the card handles it's scaling depending on the content |
| appearance | filled, filled-alternative, outline, subtle | filled | Define the appearance of the card |
| select | slot | undefined | Slot for a custom checkbox element for when a card is selectable |
| selected | boolean | false | Set to true if card is selected |
| defaultSelected | boolean | false | Set to true if card is selected by default |
| onSelectionChange | function | undefined | Callback called when the card selection changes |
| expandable | boolean | false | Allow card to expand to show whole content |
| disabled | boolean | false | Makes the card and card selection disabled (not propagated to children) |
| focusMode | off, no-tab, tab-exit, tab-only | off | Sets the focus behavior for the card. |
scale propertyfixed: Size of the card is fixed.auto-width: width is set to fit-content.auto-height: height is set to fit-content.auto: width and height are set to fit-content.fluid-width: width is set to 100%.fluid-height: height is set to 100%.fluid: width and height are set to 100%.focusMode propertyThe three allowed focus behaviours (no-tab, tab-exit, tab-only) map to the behaviors provided by Tabster.
off
The card will not focusable.
no-tab (trapFocus in Tabster)
This behaviour traps the focus inside of the Card when pressing the Enter key and will only release focus when pressing the Escape key.
tab-exit (limited in Tabster)
This behaviour traps the focus inside of the Card when pressing the Enter key but will release focus when pressing the Tab key on the last inner element.
tab-only (unlimited in Tabster)
This behaviour will cycle through all elements inside of the Card when pressing the Tab key and then release focus after the last inner element.
Context menu should be handled in conjunction with the @fluentui/react-menu component. A simple usage example would be:
<Menu openOnContext>
<MenuTrigger>
<Card />
</MenuTrigger>
<MenuPopover>
<MenuList>
<MenuItem>Share</MenuItem>
<MenuItem>Dismiss</MenuItem>
</MenuList>
</MenuPopover>
</Menu>
react-card documentation will contain more elaborate examples to cover the different use cases.
<div>
<div>{image}</div>
<div>
{header}
{description}
</div>
</div>
| Property | Values | Default | Purpose |
|---|---|---|---|
| image | slot | undefined | Logo or image to better contextualize the content |
| header | slot | undefined | Header of the card |
| description | slot | undefined | Further description of the content |
<div>
{children}
<div>
{logo}
</div>
</div>
| Property | Values | Default | Purpose |
|---|---|---|---|
| logo | slot | undefined | A logo/file type to add over the image preview |
This component has no custom props and only ensures the proper positioning of content and itself within the card.
<div>{children}</div>
<Card orientation="horizontal">
<CardHeader image={} header="Team offsite 2020" description="Onedrive > Files" />
</Card>
<Card>
<CardHeader image={} header="App Name" description="Developer" />
<span>
Donut chocolate bar oat cake. Dragée tiramisu lollipop bear claw. Marshmallow pastry jujubes toffee sugar plum.
</span>
</Card>
<Card>
<CardHeader header="Alert in Teams when a new document is uploaded in channel" description="By Microsoft" />
<CardFooter>
<span>Automated</span>
<span>3290 uses</span>
</CardFooter>
</Card>
<Card>
<CardPreview src="monkey.png" alt="image of monkey" />
<div>
<span>Length</span>
<span>4.6-39.6 IN</span>
<span>11.7-100.6 cm</span>
</div>
<div>
<span>Diet</span>
<span>Omnivore</span>
<span>nuts, fruits, eggs</span>
</div>
<CardFooter>
<Button>Share</Button>
</CardFooter>
</Card>
The card surface can be used as a clickable target
Rest
OnHover
Cursor style changes to pointer, background color & elevation values change to show card is an actionable element
OnClick
Executes action assigned to card i.e. “Open file, Open link in browser etc...”
Cards that have multiple actions within them cannot be clickable. We preserve the use of EnterKey for moving focus to actionable controls inside the card.
OnMouseEnter / Hover
Cursor style stays at default, rest state stays persistent no visual feedback is applied to the card surface
Hover & onClick
Hover state only applies to actionable items within card i.e. buttons, links etc. Cursor changes to pointer (or follows behavior of that component) ”
Clicking the card surface can toggle the checkbox state to selected. Note that checkboxes are composed together as an additional component and are not provided by default.
Rest
Default state is unselected
Hover
Cursor style changes to pointer, background color and elevation follows interactive styling to show visual feedback.
Pressed
Cursor does not change background color and elevation follows interactive styling to show visual feedback for pressed state.
onClick
Card and Checkbox are both in selected state, clicking again toggles components to unselected state.
Cards that have multiple actionable child components are expected to not be clickable. We preserve the use of EnterKey for moving focus to actionable controls inside the card, therefore the card surface should not be used to set the state of the card but is reliant on the checkbox or similar inputs to set the card state.
If users have a scenario that requires them to use actionable components within a clickable Card then the bubbling of events is expected to be managed by the users themselves.
If users have a scenario that requires them to use actionable components within a clickable Card then the bubbling of events is expected to be managed by the users themselves.
OnMouseEnter / Hover
Cursor style stays at default, rest state stays persistent no visual feedback is applied to the card surface
Hover & onClick (Checkbox)
Hover state & pressed state applies to checkbox component
onClick (Checkbox)
Card and Checkbox are both in selected state, clicking again toggles components to unselected state
In scenarios where a selectable card may be disabled both the card and the checkbox should be set to disabled. Hovering the card changes the cursor style to not-allowed
Unselected disabled
Selected disabled
Rest
Keyboard interaction
EnterKey Perfoms action on card “Open file, Open link in browser etc...”.
Focus
Initial focus is set on card, to access items within the card use EnterKey or Spacebar.
Focus-Inside
Focus moves to first actionable item in the card. Use ArrowKeys or TabKey to move focus to child elements within the card. To exit card use EscKey, to move focus back to card.
Rest
Default state is ‘unselected’
Focus
Focus rectangle is shown on card
Focus
Use spacebar to toggle state (selected/unselected)
Focus
Initial focus is set on card, to access items within the card use EnterKey or Spacebar.
Focus-Inside
Focus moves to first actionable item in the card. Use ArrowKeys or TabKey to move focus to child elements within the card. To exit card use EscKey, to move focus back to card.
Checkbox-Focus
Depending on your tab order of items within the card, the number of keystrokes will vary.
SpaceBar or EnterKey while focused on the Checkbox
Will toggle both Card and Checkbox to selected state. Keying again will toggle to unselected.
If a card is in a disabled state it should not receive focus from the tab order. And navigation to actionable child elements within the card should not be possible.
⚠️ Note: All other accessibility information, not covered in this section, is provided throughout the spec.
Each card is of role="group".
1 Focus + unselected
2 Focus + selected
1 Focus + unselected
2 Focus (inside)
3 Focus Checkbox unselected
4 Focus Checkbox selected
If a card is in a disabled state it should not receive focus from the tab order.
1 Unselected disabled
2 Selected disabled