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
parameter Name | parameter Description | parameter Type | parameter Default value |
---|---|---|---|
$spacing-property | Vertical spacing custom property, will be multiplied by two | String | — none |
Used by
- [mixin]
base
- [mixin]
size-medium
- [mixin]
size-small
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
- [function]
get
Used by
- [mixin]
button-new
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
- [mixin]
text
- [function]
height-calc
- [function]
get
- [variable]
border-radius
Used by
- [mixin]
button-new
Author
CDS
text
@mixin text() { ... }
@mixin text() { color: var(--kib-button-text-color); text-decoration: none; }
siblings
@mixin siblings() { ... }
@mixin siblings() { & + & { margin-left: spacing.get('s2'); } }
Description
Sibling button styles
Parameters
None.
Requires
- [function]
get
Used by
- [mixin]
button-new
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.
Requires
- [variable]
focus-border-distance
- [variable]
focus-border-radius-length
- [variable]
focus-border-radius
- [variable]
focus-transition-duration
Used by
- [mixin]
button-new
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
- [variable]
disabled-opacity
Used by
- [mixin]
button-new
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
- [function]
get
- [variable]
focus-border-radius-length
Used by
- [mixin]
button-new
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
- [mixin]
root
- [mixin]
base
- [mixin]
text
- [mixin]
size-large
- [mixin]
default-button-styles
- [mixin]
siblings
- [mixin]
disabled
- [mixin]
focus
Used by
- [mixin]
generate-styles
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
parameter Name | parameter Description | parameter Type | parameter Default value |
---|---|---|---|
$theme | — none | String | — none |
$emphasis | — none | String | primary |
Requires
- [function]
get
- [variable]
theme-emphasis-states
- [variable]
disabled-opacity
Used by
- [mixin]
generate-styles
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
- [variable]
large-padding
Used by
- [mixin]
button-new
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
- [function]
height-calc
- [function]
get
Used by
- [mixin]
generate-styles
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
- [function]
height-calc
- [function]
get
Used by
- [mixin]
generate-styles
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; } }
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
- [variable]
icon-size-large
Used by
- [mixin]
generate-styles
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
- [variable]
icon-size-medium
Used by
- [mixin]
generate-styles
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
- [variable]
icon-size-small
Used by
- [mixin]
generate-styles
Author
CDS
icon-position-end
@mixin icon-position-end() { ... }
@mixin icon-position-end() { margin-left: spacing.get('s2'); margin-right: 0; }
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
- [mixin]
button-padding
Used by
- [mixin]
generate-styles
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
- [function]
get
- [variable]
icon-only-padding-sizes
- [variable]
size
Used by
- [mixin]
icon-only
- [mixin]
generate-styles
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.
Requires
- [variable]
appended-border-radius
- [variable]
appended-box-shadow-width
- [variable]
appended-focus-border-radius
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
parameter Name | parameter Description | parameter Type | parameter 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
- [mixin]
button-new
- [mixin]
button-styles
- [mixin]
size-medium
- [mixin]
size-small
- [mixin]
icon-only
- [mixin]
button-padding
- [mixin]
icon-size-large
- [mixin]
icon-size-medium
- [mixin]
icon-size-small
- [variable]
size
Author
CDS
Variables
default-height
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;
disabled-opacity
$disabled-opacity: 0.5 !default;
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;
focus-border-radius-length
$focus-border-radius-length: unit.rem(2px) !default;
focus-border-radius
$focus-border-radius: calc($border-radius * 2) !default;
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;
icon-size-medium
$icon-size-medium: kib-core.dimensions-get(default) + kib-core.dimensions-get(tiny) !default;
icon-size-small
$icon-size-small: kib-core.dimensions-get(default) !default;
focus-transition-duration
$focus-transition-duration: 100ms !default;
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;
appended-box-shadow-width
$appended-box-shadow-width: unit.rem(1px) !default;
appended-border-radius
$appended-border-radius: border.get('br02') !default;
appended-focus-border-radius
$appended-focus-border-radius: calc(
$appended-border-radius + ($focus-border-distance * -1)
) !default;
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;
large-padding
$large-padding: spacing.get('s7') !default;