Component Variables

# Overview

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;
}
1
2
3
4

Test out what you can do with the component variables in this CodeSandbox (opens new window).

# Contract of Intent

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

# Use When

  • 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

# Don't Use When

  • 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

# Naming Structure

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.

# Examples

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

# Usage

# Install

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/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;
}
1
2
3
4
5
6
7
8

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();
}
1
2
3
4
5
6
7
8

# Examples

CdrAlert

  • CdrAlert should be paired with an icon preceding the text
ExampleHTMLSCSS
success!
<div class="cdr-alert-success"> success! </div>
.cdr-alert-success {
  @include cdr-alert-base-mixin;
  @include cdr-alert-success-mixin;
}
info!
<div class="cdr-alert-info"> info! </div>
.cdr-alert-info {
  @include cdr-alert-base-mixin;
  @include cdr-alert-info-mixin;
}
warning!
<div class="cdr-alert-warning"> warning! </div>
.cdr-alert-warning {
  @include cdr-alert-base-mixin;
  @include cdr-alert-warning-mixin;
}
error!
<div class="cdr-alert-error"> error! </div>
.cdr-alert-error {
  @include cdr-alert-base-mixin;
  @include cdr-alert-error-mixin;
}

CdrBreadcrumb

  • current page should not be rendered in breadcrumbs
ExampleHTMLSCSS
breadcrumb <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;
}

CdrButton

  • 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.)
ExampleHTMLSCSS
<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
ExampleHTMLSCSS
<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;
}
}

CdrChip

  • See the CdrChip docs page for more information on accessibility requirements for chips
ExampleHTMLSCSS
<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> Chip with Icon</button>
.cdr-chip-icon-left {
  @include cdr-chip-base-mixin;
  .cdr-chip-icon-left-icon { @include cdr-chip-icon-left-mixin; }
}
<button class="cdr-chip-icon-right">Chip with Icon <span class="cdr-chip-icon-right-icon">🌮</span></button>
.cdr-chip-icon-right {
  @include cdr-chip-base-mixin;
  .cdr-chip-icon-right-icon { @include cdr-chip-icon-right-mixin; }
}

CdrFormError

  • Error messaging for form inputs
ExampleHTMLSCSS
Form Error
<div class="cdr-form-error-default"> <div class="cdr-form-error-icon"></div> Form Error </div>
.cdr-form-error-default {
  @include cdr-form-error-base-mixin;
  .cdr-form-error-icon {
  @include cdr-form-error-icon-mixin;
}
}

CdrFormGroup

  • Form groups should wrap a `legend` element and contain a group of logically related input elements.
ExampleHTMLSCSS
form group title
<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;
  }
}
form group title
<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
ExampleHTMLSCSS
a
b
c
<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;
}
a
b
c
<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;
}
a
b
c
<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;
}
a
b
c
<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;
}
a
b
c
<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;
}

CdrInput

  • note that the vue component is a combination of the label and input examples
ExampleHTMLSCSS
<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
ExampleHTMLSCSS
<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;
}
Helper text
<div class="cdr-label-standalone-helper-text"> Helper text </div>
.cdr-label-standalone-helper-text {
  @include cdr-label-standalone-helper-mixin;
}
Info text
<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
ExampleHTMLSCSS
<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;
}
    ExampleHTMLSCSS
    link default <a href="#" class="cdr-link-default"> link default </a>
    .cdr-link-default {
      @include cdr-link-base-mixin;
    }
    link standalone <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.
    ExampleHTMLSCSS
    1. one
    2. two
    3. three
    <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;
    }
    • one
    • two
    • three
    <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;
    }

    CdrSelect

    • note that the vue component is a combination of the label and select examples
    ExampleHTMLSCSS
    <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
    ExampleHTMLSCSS
    Test head
    Test content
    <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;
    }

    Questions about when to use component variables? Ask the Cedar team in #cedar-user-support (opens new window)