Component variables provide a versioned method for teams to:
- Import the exact CSS styles used in the Cedar Vue component
- Apply these exact CSS styles to elements in their project
Component variables are only available for a core subset of Cedar components, and are distributed in SCSS and LESS format.
Component variables include mixins such as @include cdr-button-base-mixin
which sets many properties on an element. Each component has a base
mixin which sets properties that apply to all components of that type, as well as modifier
mixins which only apply to a specific variant of that component
For example, you can import the styling for a Cedar primary button component using a mixin:
.your-button-component {
@include cdr-button-base-mixin;
@include cdr-button-primary-mixin;
}
Test out what you can do with the component variables in this CodeSandbox.
See the component variables example project for a template demonstrating how to use Cedar tokens and component variables to generate a unique CSS stylesheet that applies Cedar styles to arbitrary HTML markup.
Versioning
- Component variables are a versioned export of the exact CSS styles being used in the Cedar Vue components
- Whenever a major version of Cedar is released, a corresponding major version of component variables will also be published
- For minor or patch versions of Cedar, component variables will only be published if there were changes made to the distributed files
- Outside of the Cedar release schedule, patch versions of component variables will only be issued if a bug is found in the distribution
Semantic naming
- Component variable mixins are semantically named based on the component being styled, how the style is intended to be used, and the CSS property being targeted
- Teams must only use component variables when semantically appropriate
When to use
- Your project does not use Vue.js, but you want to use Cedar
- Your component must visually match an existing Cedar component, but not it's functionality. For example, a
vue-router
link component that looks like a CdrLink
component - Your project requires the smallest possible bundle size, and your team is willing to take on the additional maintenance cost of using component variables instead of the Vue.js Cedar components
When not to use
- Do not use the component variables in a non-semantic way. For example,
cdr-button-base-mixin
should only ever be used to style a button element - Do not use component variables to publish clones or forks of existing Cedar components. Instead, work with the Cedar team to find a long term solution to support your use case
The naming structure for component variables and mixins is as follows:
- Namespace: Top level namespace
cdr
- Component: Name of the Cedar component for the exported variable
- Modifier: Variant of Cedar component for the exported variable
- Base modifier (
base-
) indicates variables that apply to all instances of that Cedar component - Additional modifiers can be stacked on top of that
- For example, to make a primary large button you would use the variables that have
base
, primary
, and large
modifiers
- Sub-Element: Indicates a sub-element of a component. For example,
cdr-input-base-label-color
indicates the color of the label element used inside the input component - State: Describes the interactive state that this variable is applied to. These correspond to CSS selectors such as
:focus
, :active
, :hover
, :disabled
, etc.
Namespace | Component | Modifier | Sub-Element | State | Mixin |
---|
cdr- | input- | base- | | | mixin |
cdr- | button- | secondary- | | | mixin |
cdr- | breadcrumb- | | item- | linked- | mixin |
cdr- | select- | base- | label- | disabled- | mixin |
The component variables inherit values from the Cedar design tokens, so you will need to install both packages and keep them in sync when updating:
npm install --save-dev @rei/cdr-tokens @rei/cdr-component-variables
SCSS example:
@import '@rei/cdr-tokens/dist/rei-dot-com/scss/cdr-tokens.scss'; /* import the tokens file */
@import '@rei/cdr-component-variables/dist/scss/index.scss'; /* import the component variables */
.your-button-class {
/* use mixins to apply many properties at once */
@include cdr-button-base-mixin;
@include cdr-button-primary-mixin;
}
LESS example:
@import '@rei/cdr-tokens/dist/less/cdr-tokens.less'; /* import the tokens file */
@import '@rei/cdr-component-variables/dist/less/index.less'; /* import the component variables */
.your-button-class {
/* use mixins to apply many properties at once */
.cdr-button-base-mixin();
.cdr-button-primary-mixin();
}
CdrBreadcrumb
- current page should not be rendered in breadcrumbs
HTML | SCSS |
---|
<a href="cdr-breadcrumb-default">
breadcrumb
</a>
| .cdr-breadcrumb-default {
@include cdr-breadcrumb-item-mixin;
@include cdr-breadcrumb-item-linked-mixin;
@include cdr-breadcrumb-base-text-mixin;
}
|
- All Cedar buttons must use the 'base' mixin as well as either the 'primary' or 'secondary' mixin. Additional modifiers can be added as well.
- Button mixins should ideally be applied to HTML 'button' elements, but may also work on other HTML tags (i.e, div, a, span, etc.)
HTML | SCSS |
---|
<button class="cdr-button-primary">primary</button>
| .cdr-button-primary {
@include cdr-button-base-mixin;
@include cdr-button-primary-mixin;
}
|
<button class="cdr-button-secondary">secondary</button>
| .cdr-button-secondary {
@include cdr-button-base-mixin;
@include cdr-button-secondary-mixin;
}
|
<button class="cdr-button-sale">
sale
</button>
| .cdr-button-sale {
@include cdr-button-base-mixin;
@include cdr-button-sale-mixin;
}
|
<button class="cdr-button-dark">
dark
</button>
| .cdr-button-dark {
@include cdr-button-base-mixin;
@include cdr-button-dark-mixin;
}
|
<button class="cdr-button-primary-small">
primary-small
</button>
| .cdr-button-primary-small {
@include cdr-button-base-mixin;
@include cdr-button-primary-mixin;
@include cdr-button-small-mixin;
}
|
<button class="cdr-button-secondary-medium">
secondary-medium
</button>
| .cdr-button-secondary-medium {
@include cdr-button-base-mixin;
@include cdr-button-secondary-mixin;
@include cdr-button-medium-mixin;
}
|
<button class="cdr-button-primary-large">
primary-large
</button>
| .cdr-button-primary-large {
@include cdr-button-base-mixin;
@include cdr-button-primary-mixin;
@include cdr-button-large-mixin;
}
|
CdrCard
- CdrCard elements should always link to other content
- use `@include cdr-card-link-mixin` on the linked element to make the entire card function as a click target
HTML | SCSS |
---|
<div class="cdr-card-default">
<a href="#" class="link">default card</a>
</div>
| .cdr-card-default {
@include cdr-card-base-mixin;
.link {
@include cdr-card-link-mixin;
}
}
|
CdrCaption
- Supports caption and citations.
HTML | SCSS |
---|
<div class="cdr-caption-default">
<p>Caption</p>
<cite>Citation</cite>
</div>
| .cdr-caption-default {
@include cdr-caption-container-mixin;
@include cdr-caption-summary-mixin;
cite {
@include cdr-caption-cite-mixin;
}
}
|
CdrChip
- See the CdrChip docs page for more information on accessibility requirements for chips
HTML | SCSS |
---|
<button class="cdr-chip-default">Default Chip</button>
| .cdr-chip-default {
@include cdr-chip-base-mixin;
}
|
<button class="cdr-chip-icon-left"><span class="cdr-chip-icon-left-icon">🍔</span> <span class="cdr-chip-content-right">Chip with Icon Left<span></button>
| .cdr-chip-icon-left {
@include cdr-chip-base-mixin;
.cdr-chip-content-right { @include cdr-chip-content-right-mixin; }
.cdr-chip-icon-left-icon { @include cdr-chip-icon-left-mixin; }
}
|
<button class="cdr-chip-icon-right"><span class="cdr-chip-content-left">Chip with Icon Right<span> <span class="cdr-chip-icon-right-icon">🌮</span></button>
| .cdr-chip-icon-right {
@include cdr-chip-base-mixin;
.cdr-chip-content-left { @include cdr-chip-content-left-mixin; }
.cdr-chip-icon-right-icon { @include cdr-chip-icon-right-mixin; }
}
|
- Error messaging for form inputs
HTML | SCSS |
---|
<div class="cdr-form-error-default">
<span class="cdr-form-error-icon">🦆</span> Form Error
</div>
| .cdr-form-error-default {
@include cdr-form-error-base-mixin;
.cdr-form-error-icon {
@include cdr-form-error-icon-mixin;
}
}
|
- Form groups should wrap a `legend` element and contain a group of logically related input elements.
HTML | SCSS |
---|
<fieldset class="cdr-form-group-default">
<legend>form group title</legend>
<div class="cdr-form-group-content"><input/><input/></div>
</fieldset>
| .cdr-form-group-default {
@include cdr-form-group-base-mixin;
.cdr-form-group-content {
@include cdr-form-group-content-mixin;
}
}
|
<fieldset class="cdr-form-group-error">
<legend>form group title</legend>
<div class="cdr-form-group-content"><input/><input/></div>
</fieldset>
| .cdr-form-group-error {
@include cdr-form-group-base-mixin;
.cdr-form-group-content {
@include cdr-form-group-content-mixin;
@include cdr-form-group-error-mixin;
}
}
|
CdrGrid
- CdrGrid is a simple CSS grid wrapper component
HTML | SCSS |
---|
<div class="cdr-grid-default"><div>a</div><div>b</div><div>c</div></div>
| .cdr-grid-default {
@include cdr-grid-base-mixin;
grid-template-columns: 1fr 1fr 1fr;
}
|
<div class="cdr-grid-gutter-none"><div>a</div><div>b</div><div>c</div></div>
| .cdr-grid-gutter-none {
@include cdr-grid-base-mixin;
@include cdr-grid-gutter-none-mixin;
grid-template-columns: 1fr 1fr 1fr;
}
|
<div class="cdr-grid-gutter-small"><div>a</div><div>b</div><div>c</div></div>
| .cdr-grid-guttter-small {
@include cdr-grid-base-mixin;
@include cdr-grid-gutter-small-mixin;
grid-template-columns: 1fr 1fr 1fr;
}
|
<div class="cdr-grid-guttter-medium"><div>a</div><div>b</div><div>c</div></div>
| .cdr-grid-guttter-medium {
@include cdr-grid-base-mixin;
@include cdr-grid-gutter-medium-mixin;
grid-template-columns: 1fr 1fr 1fr;
}
|
<div class="cdr-grid-gutter-large"><div>a</div><div>b</div><div>c</div></div>
| .cdr-grid-guttter-large {
@include cdr-grid-base-mixin;
@include cdr-grid-gutter-large-mixin;
grid-template-columns: 1fr 1fr 1fr;
}
|
- note that the vue component is a combination of the label and input examples
HTML | SCSS |
---|
<input class="cdr-input-default"/>
| .cdr-input-default {
@include cdr-input-base-mixin;
@include cdr-input-primary-mixin;
}
|
<input class="cdr-input-error"/>
| .cdr-input-error {
@include cdr-input-base-mixin;
@include cdr-input-primary-mixin;
@include cdr-input-error-mixin;
}
|
<input class="cdr-input-large"/>
| .cdr-input-large {
@include cdr-input-base-mixin;
@include cdr-input-primary-mixin;
@include cdr-input-large-mixin;
}
|
<input class="cdr-input-on-secondary-bg"/>
| .cdr-input-on-secondary-bg {
@include cdr-input-base-mixin;
@include cdr-input-secondary-mixin;
}
|
CdrLabelStandalone
- label element for text inputs and selects
HTML | SCSS |
---|
<label class="cdr-label-standalone-default">
Default label
</label>
| .cdr-label-standalone-default {
@include cdr-label-standalone-label-mixin;
}
|
<label class="cdr-label-standalone-required">
Required label *
</label>
| .cdr-label-standalone-required {
@include cdr-label-standalone-label-mixin;
}
|
<label class="cdr-label-standalone-optional">
Optional label <span class="optional-label">(optional)</span>
</label>
| .cdr-label-standalone-optional {
@include cdr-label-standalone-label-mixin;
.optional-label {
@include cdr-label-standalone-optional-mixin;
}
}
|
<label class="cdr-label-standalone-disabled">
Disabled label
</label>
| .cdr-label-standalone-disabled {
@include cdr-label-standalone-disabled-mixin;
}
|
<div class="cdr-label-standalone-helper-text">
Helper text
</div>
| .cdr-label-standalone-helper-text {
@include cdr-label-standalone-helper-mixin;
}
|
<div class="cdr-label-standalone-info">
Info text
</div>
| .cdr-label-standalone-info {
@include cdr-label-standalone-info-mixin;
}
|
CdrLabelWrapper
- Wrapper label element for radio and checkbox inputs
- See also the CdrRadio and CdrCheckbox input examples
HTML | SCSS |
---|
<label class="cdr-label-wrapper-default">
<input type="checkbox"/> Default label
</label>
| .cdr-label-wrapper-default {
@include cdr-label-wrapper-base-mixin;
@include cdr-label-wrapper-primary-mixin;
}
|
<label class="cdr-label-wrapper-secondary-bg">
<input type="radio"/> Label on secondary background
</label>
| .cdr-label-wrapper-secondary-bg {
@include cdr-label-wrapper-base-mixin;
@include cdr-label-wrapper-secondary-mixin;
}
|
<label class="cdr-label-wrapper-disabled">
<input type="checkbox" disabled/> Disabled label
</label>
| .cdr-label-wrapper-disabled {
@include cdr-label-wrapper-base-mixin;
@include cdr-label-wrapper-disabled-mixin;
}
|
CdrLink
HTML | SCSS |
---|
<a href="#" class="cdr-link-default">
link default
</a>
| .cdr-link-default {
@include cdr-link-base-mixin;
}
|
<a href="#" class="cdr-link-standalone">
link standalone
</a>
| .cdr-link-standalone {
@include cdr-link-base-mixin;
@include cdr-link-standalone-mixin;
}
|
CdrList
- Styles for the `inline` variations are not currently supported.
- CdrList mixins assume that you are using <li> tags for the list items. See the mixin source in `/dist` if you need to customize that.
HTML | SCSS |
---|
<ol class="cdr-list-ordered">
<li>one</li>
<li>two</li>
<li>three</li>
</ol>
| .cdr-list-ordered {
@include cdr-list-base-mixin;
@include cdr-list-ordered-mixin;
}
|
<ul class="cdr-list-unordered">
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
| .cdr-list-unordered {
@include cdr-list-base-mixin;
@include cdr-list-unordered-mixin;
}
|
CdrQuote
- Supports block and pull quotes.
- Use blockquote to provide quote attribution
HTML | SCSS |
---|
<blockquote class="cdr-quote-default">
<p>Quote</p>
<cite>Attribution</cite>
</blockquote>
| .cdr-quote-default {
@include cdr-quote-base-container;
@include cdr-quote-base-content;
}
|
<aside class="cdr-quote-pull">
<p>Quote</p>
</aside>
| .cdr-quote-pull {
@include cdr-quote-pull-container;
@include cdr-quote-pull-content
}
|
CdrSelect
- note that the vue component is a combination of the label and select examples
HTML | SCSS |
---|
<select class="cdr-select-default"/>
| .cdr-select-default {
@include cdr-select-base-mixin;
@include cdr-select-primary-mixin;
}
|
<select class="cdr-select-error"/>
| .cdr-select-error {
@include cdr-select-base-mixin;
@include cdr-select-primary-mixin;
@include cdr-select-error-mixin;
}
|
<select class="cdr-select-large"/>
| .cdr-select-large {
@include cdr-select-base-mixin;
@include cdr-select-primary-mixin;
@include cdr-select-large-mixin;
}
|
<select class="cdr-select-on-secondary-bg"/>
| .cdr-select-on-secondary-bg {
@include cdr-select-base-mixin;
@include cdr-select-secondary-mixin;
}
|
CdrTable
- CdrTable is a simple wrapper component that applies styles to HTML tables
HTML | SCSS |
---|
<table class="cdr-table-default">
<tr><th>Test head</th></tr>
<tr><td>Test content</td></tr>
</table>
| .cdr-table-default {
@include cdr-table-base-mixin;
}
|
CdrSkeleton
- CdrSkeleton's must wrap 1..n CdrSkeletonBones
- use `@include cdr-skeleton-shimmer-mixin` to apply the shimmer animation. It respects motion preferences by default
HTML | SCSS |
---|
<div class="cdr-skeleton-default">
<div class="cdr-skeleton-bone"/>
</div>
| .cdr-skeleton-default {
@include cdr-skeleton-base-mixin;
}
.cdr-skeleton-bone {
@include cdr-skeleton-bone-mixin;
@include cdr-skeleton-shimmer-mixin;
}
|
Questions about when to use component variables? Ask the Cedar team in #cedar-user-support