Button New

Installation

  yarn add @chewy/kib-controls-styles

Import

  @use '~@chewy/kib-controls-styles/src/kib-button-new/styles' as kib-button-new;

Functions

height-calc

@function height-calc($spacing-property) { ... }@function height-calc($spacing-property) { 
  $font-size: typography.get('button', 'font-size');
  $line-height: typography.get('button', 'line-height');

  @return #{calc(($spacing-property * 2) + ($font-size * $line-height) + unit.rem(4px))};
 }
Description

This function generates a calc function that determines the button height. It uses several values to do the calculation:

  • The type style font size and the unitless line-height are multiplied to get the type style height
  • The parameter is the spacing token used for the vertical padding for the button
  • The left over 4px is temporary until border widths are defined as tokens

The button height is determined by a calculated height like this because of the edge case of buttons with more than one line of text, like the Ship Once With Next Autoship button. This requires the button to have a fixed height set, but we need it to be dynamic and take spacing tokens into account, so we leverage the CSS calc() function to calculate this height for us.

Parameters
Parameters
parameter Nameparameter Descriptionparameter Typeparameter Default value
$spacing-property

Vertical spacing custom property, will be multiplied by two

String none
Requires
Used by

Mixins

root

@mixin root() { ... }@mixin root() { 
  --kib-button-text-color: #{color.get('action', 'cta', 'primary', 'text')};
  --kib-button-background: #{color.get('action', 'cta', 'primary', 'primary')};
  --kib-button-focus-border-color: #{color.get('action', 'cta', 'primary', 'primary')};
  --kib-button-box-shadow-color: none;
 }
Description

Root variables with default styles

Parameters

None.

Requires
Used by
Author
  • CDS

base

@mixin base() { ... }@mixin base() { 
  @include typography.style-as('button');
  @include text;

  &:visited {
    @include text;
  }

  position: relative;
  display: inline-flex;
  padding-top: 0;
  padding-bottom: 0;
  min-width: var(--kib-button-size, #{functions.height-calc(spacing.get('s3'))});
  min-height: var(--kib-button-size, #{functions.height-calc(spacing.get('s3'))});
  align-items: center;
  justify-content: center;
  appearance: none;
  border-radius: settings.$border-radius;
  cursor: pointer;
  touch-action: manipulation;
  transform: translate(0);
  user-select: none;
  border: 0;
  background-color: var(--kib-button-background);
  text-align: center;
 }
Description

Base button styles

Parameters

None.

Requires
Used by
Author
  • CDS

text

@mixin text() { ... }@mixin text() { 
  color: var(--kib-button-text-color);
  text-decoration: none;
 }
Description

Text styles

Parameters

None.

Used by
Author
  • CDS

siblings

@mixin siblings() { ... }@mixin siblings() { 
  & + & {
    margin-left: spacing.get('s2');
  }
 }
Description

Sibling button styles

Parameters

None.

Requires
Used by
Author
  • CDS

focus

@mixin focus() { ... }@mixin focus() { 
  // Custom outline around button shown on focus
  &::after {
    $distance: settings.$focus-border-distance;

    position: absolute;
    z-index: -1;
    top: $distance;
    left: $distance;
    right: $distance;
    bottom: $distance;
    border: settings.$focus-border-radius-length solid var(--kib-button-focus-border-color);
    border-radius: settings.$focus-border-radius;
    color: inherit;
    content: '';
    opacity: 0;
    transition: opacity settings.$focus-transition-duration ease-out;
  }

  &:focus {
    outline: 0;

    &::after {
      opacity: 1;
    }
  }
 }
Description

Focus button styles

Parameters

None.

Used by
Author
  • CDS

disabled

@mixin disabled() { ... }@mixin disabled() { 
  opacity: settings.$disabled-opacity;
  pointer-events: none;

  @media (forced-colors: active) {
    opacity: 1;
    color: GrayText !important;
    border-color: GrayText !important;
  }
 }
Description

Disabled button styles

Parameters

None.

Requires
Used by
Author
  • CDS

default-button-styles

@mixin default-button-styles() { ... }@mixin default-button-styles() { 
  box-shadow: inset 0 0 0 #{settings.$focus-border-radius-length} var(--kib-button-box-shadow-color);

  &:hover {
    --kib-button-background: #{color.get('action', 'cta', 'primary', '03')};
  }

  &:active,
  &--loading {
    --kib-button-background: #{color.get('action', 'cta', 'primary', '02')};
  }
 }
Description

Default button styles

Parameters

None.

Requires
Used by
Author
  • CDS

button-new

@mixin button-new() { ... }@mixin button-new() { 
  @include root;
  @include base;
  @include text;
  @include size-large;
  @include default-button-styles;
  @include siblings;

  &:hover,
  &:active,
  &--loading {
    @include text;
  }

  &:disabled,
  &--loading {
    @include disabled;
  }

  @include focus;
 }
Description

Primary button styles

Parameters

None.

Requires
Used by
Author
  • CDS

button-styles

@mixin button-styles($theme, $emphasis: primary) { ... }@mixin button-styles($theme, $emphasis: primary) { 
  --kib-button-box-shadow-color: #{map.get(
      settings.$theme-emphasis-states,
      $theme,
      $emphasis,
      'border-color'
    )};
  --kib-button-focus-border-color: #{map.get(
      settings.$theme-emphasis-states,
      $theme,
      'focus-border-color'
    )};
  --kib-button-background: #{map.get(
      settings.$theme-emphasis-states,
      $theme,
      $emphasis,
      'background'
    )};
  --kib-button-text-color: #{map.get(
      settings.$theme-emphasis-states,
      $theme,
      $emphasis,
      'text-color'
    )};

  &:hover {
    --kib-button-text-color: #{map.get(
        settings.$theme-emphasis-states,
        $theme,
        $emphasis,
        'text-color'
      )};
    --kib-button-background: #{map.get(
        settings.$theme-emphasis-states,
        $theme,
        $emphasis,
        'hover-color'
      )};

    @if $emphasis == 'tertiary' {
      box-shadow: none;
    }
  }

  // loading must match pressed styles
  &:active,
  &--loading {
    --kib-button-background: #{map.get(
        settings.$theme-emphasis-states,
        $theme,
        $emphasis,
        'press-color'
      )};

    @if $emphasis == 'tertiary' {
      box-shadow: none;
    }
  }

  &--loading {
    opacity: settings.$disabled-opacity;
    @media (forced-colors: active) {
      opacity: 1;
    }
  }

  @if $theme == 'destructive' {
    @media (forced-colors: active) {
      border-style: dashed !important;
    }
  }
 }
Description

button styles for different cases

Parameters
Parameters
parameter Nameparameter Descriptionparameter Typeparameter Default value
$theme noneString none
$emphasis noneStringprimary
Requires
Used by
Author
  • CDS

size-large

@mixin size-large() { ... }@mixin size-large() { 
  padding-left: settings.$large-padding;
  padding-right: settings.$large-padding;
 }
Description

Large size styles

Parameters

None.

Requires
Used by
Author
  • CDS

size-medium

@mixin size-medium() { ... }@mixin size-medium() { 
  --kib-button-size: #{functions.height-calc(spacing.get('s2'))};

  padding-left: spacing.get('s5');
  padding-right: spacing.get('s5');
 }
Description

Medium size styles

Parameters

None.

Requires
Used by
Author
  • CDS

size-small

@mixin size-small() { ... }@mixin size-small() { 
  --kib-button-size: #{functions.height-calc(spacing.get('s1'))};

  padding-left: spacing.get('s3');
  padding-right: spacing.get('s3');
 }
Description

Small size styles

Parameters

None.

Requires
Used by
Author
  • CDS

icon

@mixin icon() { ... }@mixin icon() { 
  margin-right: spacing.get('s2');
  flex-shrink: 0;
  display: inline-block;
  vertical-align: middle;
  width: settings.$default-icon-size;
  height: settings.$default-icon-size;

  > svg {
    fill: currentColor;
  }

  > :only-child {
    display: block;
    width: inherit;
    height: inherit;
  }
 }
Description

icon styles

Parameters

None.

Requires
Author
  • CDS

icon-size-large

@mixin icon-size-large() { ... }@mixin icon-size-large() { 
  width: settings.$icon-size-large;
  height: settings.$icon-size-large;
 }
Description

icon large size styles

Parameters

None.

Requires
Used by
Author
  • CDS

icon-size-medium

@mixin icon-size-medium() { ... }@mixin icon-size-medium() { 
  width: settings.$icon-size-medium;
  height: settings.$icon-size-medium;
 }
Description

icon medium size styles

Parameters

None.

Requires
Used by
Author
  • CDS

icon-size-small

@mixin icon-size-small() { ... }@mixin icon-size-small() { 
  width: settings.$icon-size-small;
  height: settings.$icon-size-small;
 }
Description

icon small size styles

Parameters

None.

Requires
Used by
Author
  • CDS

icon-position-end

@mixin icon-position-end() { ... }@mixin icon-position-end() { 
  margin-left: spacing.get('s2');
  margin-right: 0;
 }
Description

position icon at end styles

Parameters

None.

Requires
Author
  • CDS

icon-only

@mixin icon-only() { ... }@mixin icon-only() { 
  @include button-padding;

  border-radius: 50%;

  &::after {
    border-radius: inherit;
  }
 }
Description

icon only styles

Parameters

None.

Requires
Used by
Author
  • CDS

icon-only-icon

@mixin icon-only-icon() { ... }@mixin icon-only-icon() { 
  margin: 0;
 }
Description

icon only icon styles

Parameters

None.

Author
  • CDS

button-padding

@mixin button-padding() { ... }@mixin button-padding() { 
  padding: map.get(settings.$icon-only-padding-sizes, $size);
 }
Description

button padding styles

Parameters

None.

Requires
Used by
Author
  • CDS

visually-hidden

@mixin visually-hidden() { ... }@mixin visually-hidden() { 
  @include kib-core.visually-hidden;
 }
Description

visually hide button text styles

Parameters

None.

Author
  • CDS

button-appended

@mixin button-appended() { ... }@mixin button-appended() { 
  margin: 0;
  height: auto;
  border-radius: 0 settings.$appended-border-radius settings.$appended-border-radius 0;
  box-shadow: inset 0 0 0 settings.$appended-box-shadow-width var(--kib-button-box-shadow-color);

  &::after {
    border-radius: 0 settings.$appended-focus-border-radius settings.$appended-focus-border-radius 0;
  }
 }
Description

Appended button styles

Parameters

None.

Author
  • CDS

generate-styles

@mixin generate-styles($theme, $emphasis, $size, $icon-only) { ... }@mixin generate-styles($theme, $emphasis, $size, $icon-only) { 
  @include button-new;
  @include button-styles($theme, $emphasis);

  @if $size == 'medium' {
    @include size-medium;
  } @else if $size == 'small' {
    @include size-small;
  }

  @if $icon-only {
    @include icon-only;

    @if $size != 'large' {
      @include button-padding($size);
    }

    > svg {
      @if $size == 'large' {
        @include icon-size-large;
      } @else if $size == 'medium' {
        @include icon-size-medium;
      } @else if $size == 'small' {
        @include icon-size-small;
      }
    }
  }
 }
Description

Button New Generators

Parameters
Parameters
parameter Nameparameter Descriptionparameter Typeparameter Default value
$theme

functional color theme ('action', 'utility', 'destructive', 'transactional')

String none
$emphasis

theme emphasis ('primary', 'secondary', 'tertiary')

String none
$size

button size ('large', 'medium', 'small')

String none
$icon-only

icon only

Boolean none
Requires
Author
  • CDS

Variables

default-height

Deprecated!

Use functions.height-calc() instead.

$default-height: kib-core.dimensions-get(huger) !default;
Description

Default height

Type

Number

Author
  • CDS

default-icon-size

$default-icon-size: kib-core.dimensions-get(large) !default;
Description

Default icon size

Type

Number

Used by
Author
  • CDS

disabled-opacity

$disabled-opacity: 0.5 !default;
Description

Disabled opacity value

Type

Number

Used by
Author
  • CDS

icon-only-padding

$icon-only-padding: spacing.get('s3') !default;
Description

Icon padding only

Type

Color

Author
  • CDS

border-radius

$border-radius: border.get('br03') !default;
Description

Border radius

Type

Number

Author
  • CDS

focus-border-distance

$focus-border-distance: unit.rem(-4px) !default;
Description

Focus border distance

Type

Number

Used by
Author
  • CDS

focus-border-radius-length

$focus-border-radius-length: unit.rem(2px) !default;
Description

Focus border radius

Type

Number

Used by
Author
  • CDS

focus-border-radius

$focus-border-radius: calc($border-radius * 2) !default;
Description

Focus border radius

Type

Number

Used by
Author
  • CDS

button-size-medium

$button-size-medium: kib-core.dimensions-get(huge) !default;
Description

Button size medium

Type

Number

Author
  • CDS

button-size-small

$button-size-small: kib-core.dimensions-get(large) + kib-core.dimensions-get(small) !default;
Description

Button size small

Type

Number

Author
  • CDS

icon-size-large

$icon-size-large: $default-icon-size !default;
Description

Icon size large

Type

Number

Used by
Author
  • CDS

icon-size-medium

$icon-size-medium: kib-core.dimensions-get(default) + kib-core.dimensions-get(tiny) !default;
Description

Icon size medium

Type

Number

Used by
Author
  • CDS

icon-size-small

$icon-size-small: kib-core.dimensions-get(default) !default;
Description

Icon size small

Type

Number

Used by
Author
  • CDS

focus-transition-duration

$focus-transition-duration: 100ms !default;
Description

Ease out timer

Type

Number

Used by
Author
  • CDS

icon-only-padding-sizes

$icon-only-padding-sizes: (...) !default;$icon-only-padding-sizes: (
  'large': spacing.get('s3'),
  'medium': spacing.get('s2'),
  'small': spacing.get('s2')
) !default;
Description

Button padding sizes

Type

Map

Used by
Author
  • CDS

appended-box-shadow-width

$appended-box-shadow-width: unit.rem(1px) !default;
Description

Appended button box shadow width

Type

Number

Used by
Author
  • CDS

appended-border-radius

$appended-border-radius: border.get('br02') !default;
Description

Appended button border radius

Type

Number

Used by
Author
  • CDS

appended-focus-border-radius

$appended-focus-border-radius: calc(
  $appended-border-radius + ($focus-border-distance * -1)
) !default;
Description

Appended button focus border radius

Type

Number

Used by
Author
  • CDS

theme-emphasis-states

$theme-emphasis-states: (...) !default;$theme-emphasis-states: (
  'action': (
    'primary': (
      'background': color.get('action', 'cta', 'primary', 'primary'),
      'text-color': color.get('action', 'cta', 'primary', 'text'),
      'border-color': color.get('action', 'cta', 'primary', 'primary'),
      'hover-color': color.get('action', 'cta', 'primary', '03'),
      'press-color': color.get('action', 'cta', 'primary', '02')
    ),
    'secondary': (
      'background': color.get('action', 'cta', 'alternate', 'primary'),
      'text-color': color.get('action', 'cta', 'alternate', 'text'),
      'border-color': color.get('action', 'cta', 'alternate', 'text'),
      'hover-color': color.get('action', 'cta', 'alternate', '03'),
      'press-color': color.get('action', 'cta', 'alternate', '02')
    ),
    'tertiary': (
      'background': color.get('action', 'cta', 'alternate', 'primary'),
      'text-color': color.get('action', 'cta', 'alternate', 'text'),
      'border-color': color.get('action', 'cta', 'alternate', '03'),
      'hover-color': color.get('action', 'cta', 'alternate', '03'),
      'press-color': color.get('action', 'cta', 'alternate', '02')
    ),
    'focus-border-color': color.get('action', 'cta', 'primary', 'primary')
  ),
  'utility': (
    'primary': (
      'background': color.get('action', 'utility', 'primary', 'primary'),
      'text-color': color.get('action', 'utility', 'primary', 'text'),
      'hover-color': color.get('action', 'utility', 'primary', '03'),
      'press-color': color.get('action', 'utility', 'primary', '02'),
      'border-color': none
    ),
    'secondary': (
      'background': color.get('action', 'utility', 'alternate', 'primary'),
      'text-color': color.get('action', 'utility', 'alternate', 'text'),
      'border-color': color.get('action', 'utility', 'alternate', 'text'),
      'hover-color': color.get('action', 'utility', 'alternate', '03'),
      'press-color': color.get('action', 'utility', 'alternate', '02')
    ),
    'tertiary': (
      'background': color.get('action', 'utility', 'alternate', 'primary'),
      'text-color': color.get('action', 'utility', 'alternate', 'text'),
      'border-color': color.get('action', 'utility', 'alternate', '03'),
      'hover-color': color.get('action', 'utility', 'alternate', '03'),
      'press-color': color.get('action', 'utility', 'alternate', '02')
    ),
    'focus-border-color': color.get('action', 'utility', 'primary', 'primary')
  ),
  'destructive': (
    'primary': (
      'background': color.get('action', 'danger', 'primary', 'primary'),
      'text-color': color.get('action', 'danger', 'primary', 'text'),
      'hover-color': color.get('action', 'danger', 'primary', '03'),
      'press-color': color.get('action', 'danger', 'primary', '02'),
      'border-color': none
    ),
    'secondary': (
      'background': color.get('action', 'danger', 'alternate', 'primary'),
      'text-color': color.get('action', 'danger', 'alternate', 'text'),
      'border-color': color.get('action', 'danger', 'alternate', 'text'),
      'hover-color': color.get('action', 'danger', 'alternate', '03'),
      'press-color': color.get('action', 'danger', 'alternate', '02')
    ),
    'tertiary': (
      'background': color.get('action', 'danger', 'alternate', 'primary'),
      'text-color': color.get('action', 'danger', 'alternate', 'text'),
      'border-color': color.get('action', 'danger', 'alternate', '03'),
      'hover-color': color.get('action', 'danger', 'alternate', '03'),
      'press-color': color.get('action', 'danger', 'alternate', '02')
    ),
    'focus-border-color': color.get('action', 'danger', 'primary', 'primary')
  ),
  'transactional': (
    'primary': (
      'background': color.get('action', 'transaction', 'primary'),
      'text-color': color.get('action', 'transaction', 'text'),
      'hover-color': color.get('action', 'transaction', '03'),
      'press-color': color.get('action', 'transaction', '02'),
      'border-color': none
    ),
    'secondary': (
      'background': color.get('action', 'cta', 'alternate', 'primary'),
      'text-color': color.get('action', 'transaction', 'secondary', 'text'),
      'border-color': color.get('action', 'transaction', 'secondary', 'primary'),
      'hover-color': color.get('action', 'transaction', 'secondary', '03'),
      'press-color': color.get('action', 'transaction', 'secondary', '02')
    ),
    'focus-border-color': color.get('action', 'transaction', 'primary')
  )
) !default;
Description

Button theme and emphasis state

Type

Map

Used by
Author
  • CDS

large-padding

$large-padding: spacing.get('s7') !default;
Description

Large button padding

Type

Number

Used by
Author
  • CDS