fulfillment tile
Selection variant of CdrSurfaceSelection with additional interactive states
The fulfillment tile shows a checked state with descriptive content. It extends the surface selection component, providing a set of features intended for product, checkout, and search pages.
This component comes with styles for checked, disabled, loading, and active states. It also provides:
- A layout for inner elements
- A content component for styling text below the header
- An icon component that can be used in the header
- A header component
These parts allow Cedar users to build a custom version of the fulfillment tile.
All dos and don'ts from surface selection apply, but with some extra criteria:
When to use
- The ability to select a surface is needed, but with a more structured approach to the header and lower content
- When a status icon is helpful within a surface selection
When not to use
- Displaying mixed media, like a color swatch. The surface selection component may be more appropriate for these types of designs
Make sure fulfillment tiles:
- Convey the current state at all times (checked, disabled, active, loading)
- Serve a single purpose for a changing an option. It should not contain links or other interactive elements
- Are part of a radio group if used with a
radio
role. The group should be properly labled (see implementation)
Loading
When the loading
prop is true
, all content in the body
and footer
slots will have the opacity animated to 0
, hiding the content. At this point, the loading
slot will appear, while retaining the same size of the component. You can provide a loading
slot, or use the default, which is a single CdrSkeletonBone
line. The header
slot will always display.
Disabled
When a selection is disabled, it will not emit any events.
Orientation
Inside of the component is CdrLayout
, a grid that comes with a recommended gap.
Body
The body content is for displaying any lengthier text that needs to be part of the tile. It will attempt to stretch to use any extra space within the tile.
Footer
The footer content is for text that is slightly larger than the body content and has a bit more prominence.
What Cedar provides
- Adds the
aria-checked
attribute at all times - Adds the
disabled
attribute
Development responsibilities
When using this component, here's what you are responsible for:
- Always group within a radio group if used with a
radio
role. Make sure the group is properly labled (see implementation) - Add a
tabindex="0"
prop when appropriate (most of the time this is true)
Radio
Use the component within a radio group and include a label. Here is a simple example of how you can use the fulfillment tile on the product page:
<div id="radio-label">
How would you like to receieve your order?
</div>
<div
role="radiogroup"
aria-labelledby="radio-label"
>
<CdrFulfillmentTile
tabindex="0"
role="radio"
:checked="orderPreference === 'pickup'"
@click="orderPreference = 'pickup'"
>
<template #icon-right>
<CdrFulfillmentTileIcon
v-if="orderPreference === 'pickup'"
type="success"
>
<IconCheckFill />
</CdrFulfillmentTileIcon>
</template>
<template #header>Pick up</template>
<template #body>At San Diego</template>
</CdrFulfillmentTile>
<CdrFulfillmentTile
tabindex="0"
role="radio"
:checked="orderPreference === 'ship'"
@click="orderPreference = 'ship'"
>
<template #icon-right>
<CdrFulfillmentTileIcon
v-if="orderPreference === 'ship'"
type="success"
>
<IconCheckFill />
</CdrFulfillmentTileIcon>
</template>
<template #header>Ship it</template>
</CdrFulfillmentTile>
</div>
Checkbox
Use the component as a checkbox. If the content inside does not provide an adequate description, then include a label. Here is an example of how you can use the fulfillment tile on the search page:
<h2>Fulfillment methods available:</h2>
<div role="group">
<div>
<CdrFulfillmentTile
:checked="methods.includes('store')"
role="checkbox"
tabindex="0"
@click="toggleMethod('store')"
>
<template #icon-left>
<div :class="{ 'example__icon': true, 'example__icon--checked': methods.includes('store') }" />
</template>
<template #header>Store Pickup (32)</template>
<template #footer>
In stock at
<strong>Encinitas</strong>
</template>
</CdrFulfillmentTile>
<CdrButton modifier="link">
Change store
</CdrButton>
</div>
<CdrFulfillmentTile
:checked="methods.includes('ship')"
role="checkbox"
tabindex="0"
@click="toggleMethod('ship')"
>
<template #icon-left>
<div :class="{ 'example__icon': true, 'example__icon--checked': methods.includes('store') }" />
</template>
<template #header>Ship to address (32)</template>
</CdrFulfillmentTile>
</div>
<style lang="scss" scoped>
@import '@rei/cdr-tokens/dist/rei-dot-com/scss/cdr-tokens.scss';
.example {
&__icon {
display: inline-block;
vertical-align: middle;
flex: 0 0 auto;
width: 1.8rem;
height: 1.8rem;
margin: $cdr-space-eighth-x;
fill: inherit;
border-radius: $cdr-radius-round;
border: $cdr-space-sixteenth-x solid #2e2e2b;
&--checked {
border-width: 0.7rem;
}
}
}
</style>
When using CdrFulfillmentTile in a TypeScript application, we recommend importing the surfaceSelection
interface from the library if you want fine-grained control over the options passed to the component.
ParentComponent.vue
<script setup lang="ts">
import { CdrFulfillmentTile, type surfaceSelection } from '@rei/cedar'
const example: surfaceSelection = {
checked: false,
modifier: 'primary',
role: 'checkbox',
loading: false,
disabled: true,
};
</script>
<template>
<main>
<CdrFulfillmentTile v-bind="example">
...
</CdrFulfillmentTile>
</main>
</template>
CdrFulfillmentTile
Props
Name | Type | Default |
---|---|---|
palette Defines a palette for the component's style variations. | union | |
tag Determines which HTML tag to use. | Tag | 'div' |
boxShadow Adds a shadow based on the token options within Cedar. | union | |
borderRadius Adds in a border radius based on the token options within Cedar. | union | 'soft' |
borderWidth Specifies a border width based on the token options within Cedar. | union | |
borderStyle Specifies a border style based on the token options within Cedar. | union | |
borderColor Specifies a border color based on the token options within Cedar. | union | |
background Adds in a background color based on the current palette's tokens. | union | |
checked Determines if the surface is in a checked state. Adds an `aria-checked` attribute. | boolean | |
disabled Determines if the surface is in a disabled state. | boolean | |
loading Determines if the surface is in a loading state. | boolean | |
role Determines the ARIA role of the surface. Typically 'radio' or 'checkbox'. | string | 'checkbox' |
layout Layout props that will be merged with selection defaults. | Layout |
Slots
Name |
---|
icon-left Icon to display on the left of the header. |
header Header content that is still visible during loading. |
icon-right Icon to display on the right of the header. |
body Default font size is a step down. Placed just below the header. |
footer Footer content will be at the bottom of the component. |