diff --git a/.yarn/offline-mirror/@storybook-addon-actions-5.3.0.tgz b/.yarn/offline-mirror/@storybook-addon-actions-5.3.0.tgz new file mode 100644 index 000000000000..87fa01627573 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-actions-5.3.0.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addons-5.3.0.tgz b/.yarn/offline-mirror/@storybook-addons-5.3.0.tgz new file mode 100644 index 000000000000..271f16c29906 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addons-5.3.0.tgz differ diff --git a/.yarn/offline-mirror/@storybook-api-5.3.0.tgz b/.yarn/offline-mirror/@storybook-api-5.3.0.tgz new file mode 100644 index 000000000000..00afe7181d4a Binary files /dev/null and b/.yarn/offline-mirror/@storybook-api-5.3.0.tgz differ diff --git a/.yarn/offline-mirror/@storybook-channel-postmessage-5.3.0.tgz b/.yarn/offline-mirror/@storybook-channel-postmessage-5.3.0.tgz new file mode 100644 index 000000000000..a399744f9bdc Binary files /dev/null and b/.yarn/offline-mirror/@storybook-channel-postmessage-5.3.0.tgz differ diff --git a/.yarn/offline-mirror/@storybook-channels-5.3.0.tgz b/.yarn/offline-mirror/@storybook-channels-5.3.0.tgz new file mode 100644 index 000000000000..724a9b44bb65 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-channels-5.3.0.tgz differ diff --git a/.yarn/offline-mirror/@storybook-client-api-5.3.0.tgz b/.yarn/offline-mirror/@storybook-client-api-5.3.0.tgz new file mode 100644 index 000000000000..dafdcd296d81 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-client-api-5.3.0.tgz differ diff --git a/.yarn/offline-mirror/@storybook-client-logger-5.3.0.tgz b/.yarn/offline-mirror/@storybook-client-logger-5.3.0.tgz new file mode 100644 index 000000000000..1cddf0536ea6 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-client-logger-5.3.0.tgz differ diff --git a/.yarn/offline-mirror/@storybook-components-5.3.0.tgz b/.yarn/offline-mirror/@storybook-components-5.3.0.tgz new file mode 100644 index 000000000000..c2118594eb03 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-components-5.3.0.tgz differ diff --git a/.yarn/offline-mirror/@storybook-core-events-5.3.0.tgz b/.yarn/offline-mirror/@storybook-core-events-5.3.0.tgz new file mode 100644 index 000000000000..3c544a4d981c Binary files /dev/null and b/.yarn/offline-mirror/@storybook-core-events-5.3.0.tgz differ diff --git a/.yarn/offline-mirror/@storybook-router-5.3.0.tgz b/.yarn/offline-mirror/@storybook-router-5.3.0.tgz new file mode 100644 index 000000000000..383d3de266ad Binary files /dev/null and b/.yarn/offline-mirror/@storybook-router-5.3.0.tgz differ diff --git a/.yarn/offline-mirror/@storybook-theming-5.3.0.tgz b/.yarn/offline-mirror/@storybook-theming-5.3.0.tgz new file mode 100644 index 000000000000..7f4c5f095784 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-theming-5.3.0.tgz differ diff --git a/.yarn/offline-mirror/schema-utils-2.6.1.tgz b/.yarn/offline-mirror/schema-utils-2.6.1.tgz new file mode 100644 index 000000000000..734fc4252eae Binary files /dev/null and b/.yarn/offline-mirror/schema-utils-2.6.1.tgz differ diff --git a/packages/components/src/globals/scss/vendor/@carbon/elements/scss/grid/_inlined/_mixins.scss b/packages/components/src/globals/scss/vendor/@carbon/elements/scss/grid/_inlined/_mixins.scss new file mode 100644 index 000000000000..044afd79301e --- /dev/null +++ b/packages/components/src/globals/scss/vendor/@carbon/elements/scss/grid/_inlined/_mixins.scss @@ -0,0 +1,339 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +// Helpers for defining columns, rows, and containers are heavily inspired by, +// and often derived from, bootstrap: +// https://github.com/twbs/bootstrap/blob/v4-dev/scss/mixins/_grid.scss + +@import '../vendor/@carbon/layout/breakpoint'; +@import 'prefix'; + +// ----------------------------------------------------------------------------- +// Columns +// ----------------------------------------------------------------------------- + +/// Used to initialize the default properties for a column class, most notably +/// for setting width and default gutters when a column's breakpoint has not been +/// hit yet. +/// @param {Number} $gutter [$carbon--grid-gutter] - The gutter for the grid system +/// @param {Number} $collapsed-gutter [$carbon--grid-gutter--condensed] - The condensed mode gutter +/// @access private +/// @group @carbon/grid +@mixin carbon--make-col-ready( + $gutter: $carbon--grid-gutter, + $condensed-gutter: $carbon--grid-gutter--condensed +) { + // Prevent columns from becoming too narrow when at smaller grid tiers by + // always setting `width: 100%;`. This works because we use `flex` values + // later on to override this initial width. + width: 100%; + padding-right: ($gutter / 2); + padding-left: ($gutter / 2); + + // For our condensed use-case, our gutters collapse to 2px solid, 1px on each + // side. + .#{$prefix}--row--condensed &, + .#{$prefix}--grid--condensed & { + padding-right: ($condensed-gutter / 2); + padding-left: ($condensed-gutter / 2); + } +} + +/// Define the width of the column for a given span and column count. +/// A width of 0 will hide the column entirely. +/// @param {Number} $span - The number of columns covered +/// @param {Number} $columns - The total number of columns available +/// @access private +/// @group @carbon/grid +@mixin carbon--make-col($span, $columns) { + @if $span == 0 { + display: none; + } @else { + // Explicitly include `display: block` to override + display: block; + flex: 0 0 percentage($span / $columns); + // Add a `max-width` to ensure content within each column does not blow out + // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari + // do not appear to require this. + max-width: percentage($span / $columns); + } +} + +/// Create a column offset for a given span and column count. +/// @param {Number} $span - The number of columns the offset should cover +/// @param {Number} $columns - The total number of columns available +/// @access private +/// @group @carbon/grid +@mixin carbon--make-col-offset($span, $columns) { + $offset: $span / $columns; + @if $offset == 0 { + margin-left: 0; + } @else { + margin-left: percentage($offset); + } +} + +/// Output the CSS required for all the columns in a given grid system. +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - The breakpoints in the grid system +/// @param {Number} $gutter [$carbon--grid-gutter] - The gutter for the grid system +/// @access private +/// @group @carbon/grid +@mixin carbon--make-grid-columns( + $breakpoints: $carbon--grid-breakpoints, + $gutter: $carbon--grid-gutter +) { + .#{$prefix}--col { + @include carbon--make-col-ready(); + } + + @each $breakpoint in map-keys($breakpoints) { + $infix: carbon--breakpoint-infix($breakpoint); + $columns: map-get(map-get($breakpoints, $breakpoint), columns); + + // Allow columns to stretch full width below their breakpoints + @for $i from 0 through $columns { + .#{$prefix}--col#{$infix}-#{$i} { + @include carbon--make-col-ready(); + } + } + + .#{$prefix}--col#{$infix}, + .#{$prefix}--col#{$infix}--auto { + @include carbon--make-col-ready(); + } + + @include carbon--breakpoint($breakpoint, $breakpoints) { + // Provide basic `.col-{bp}` classes for equal-width flexbox columns + .#{$prefix}--col, + .#{$prefix}--col#{$infix} { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; + } + + .#{$prefix}--col--auto, + .#{$prefix}--col#{$infix}--auto { + flex: 1 0 0%; + width: auto; + // Reset earlier grid tiers + max-width: 100%; + } + + @for $i from 0 through $columns { + .#{$prefix}--col#{$infix}-#{$i} { + @include carbon--make-col($i, $columns); + } + } + + @for $i from 0 through ($columns - 1) { + @if not($infix == '') { + .#{$prefix}--offset#{$infix}-#{$i} { + @include carbon--make-col-offset($i, $columns); + } + } + } + } + } +} + +// ----------------------------------------------------------------------------- +// Rows +// ----------------------------------------------------------------------------- + +/// Define the properties for a selector assigned to a row in the grid system. +/// @param {Number} $gutter [$carbon--grid-gutter] - The gutter in the grid system +/// @access private +/// @group @carbon/grid +@mixin carbon--make-row($gutter: $carbon--grid-gutter) { + display: flex; + flex-wrap: wrap; + margin-right: -1 * $gutter / 2; + margin-left: -1 * $gutter / 2; +} + +// ----------------------------------------------------------------------------- +// No gutter +// ----------------------------------------------------------------------------- + +/// Add `no-gutter` and `no-gutter--{left,right}` classes to the output CSS. These +/// classes are useful for dropping the gutter in fluid situations. +/// @access private +/// @group @carbon/grid +@mixin carbon--no-gutter { + .#{$prefix}--no-gutter, + .#{$prefix}--row.#{$prefix}--no-gutter [class*='#{$prefix}--col'] { + padding-left: 0; + padding-right: 0; + } + + .#{$prefix}--no-gutter--left, + .#{$prefix}--row.#{$prefix}--no-gutter--left [class*='#{$prefix}--col'] { + padding-left: 0; + } + + .#{$prefix}--no-gutter--right, + .#{$prefix}--row.#{$prefix}--no-gutter--right [class*='#{$prefix}--col'] { + padding-right: 0; + } +} + +// ----------------------------------------------------------------------------- +// Hang +// ----------------------------------------------------------------------------- + +/// Add `hang--left` and `hang--right` classes for a given gutter. These classes are +/// used alongside `no-gutter--left` and `no-gutter--right` to "hang" type. +/// @param {Number} $gutter [$carbon--grid-gutter] - The gutter in the grid system +/// @access private +/// @group @carbon/grid +@mixin carbon--hang($gutter: $carbon--grid-gutter) { + .#{$prefix}--hang--left { + padding-left: ($gutter / 2); + } + + .#{$prefix}--hang--right { + padding-right: ($gutter / 2); + } +} + +// ----------------------------------------------------------------------------- +// Aspect ratio +// ----------------------------------------------------------------------------- + +/// The aspect ratios that are used to generate corresponding aspect ratio +/// classes in code +/// @type List +/// @access public +/// @group @carbon/grid +$carbon--aspect-ratios: ((16, 9), (2, 1), (4, 3), (1, 1), (1, 2)); + +/// Output the CSS classes for generating aspect ratio classes +/// @param {List} $aspect-ratios [$carbon--aspect-ratios] - A list of aspect ratios to generate +/// @access private +/// @group @carbon/grid +@mixin carbon--aspect-ratio($aspect-ratios: $carbon--aspect-ratios) { + .#{$prefix}--aspect-ratio { + height: 0; + position: relative; + } + + .#{$prefix}--aspect-ratio--object { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + } + + @each $ratio in $aspect-ratios { + $width: nth($ratio, 1); + $height: nth($ratio, 2); + + .#{$prefix}--aspect-ratio--#{$width}x#{$height} { + padding-bottom: percentage($height / $width); + } + } +} + +// ----------------------------------------------------------------------------- +// Grid +// ----------------------------------------------------------------------------- + +/// Create the container for a grid. Will cause full-bleed for the grid unless +/// max-width properties are added with `make-container-max-widths` +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - A map of breakpoints where the key is the name +/// @access private +/// @group @carbon/grid +@mixin carbon--make-container($breakpoints: $carbon--grid-breakpoints) { + margin-right: auto; + margin-left: auto; + + @include carbon--set-largest-breakpoint(); + + @each $name, $value in $breakpoints { + $prev-breakpoint: map-get($breakpoints, carbon--breakpoint-prev($name)); + $margin: map-get($value, margin); + + @if $prev-breakpoint { + $prev-margin: map-get($prev-breakpoint, margin); + @if $prev-margin != $margin { + @include carbon--breakpoint($name) { + padding-left: #{($carbon--grid-gutter / 2) + $margin}; + padding-right: #{($carbon--grid-gutter / 2) + $margin}; + } + } + } @else { + @include carbon--breakpoint($name) { + padding-left: #{($carbon--grid-gutter / 2) + $margin}; + padding-right: #{($carbon--grid-gutter / 2) + $margin}; + } + } + } +} + +/// Get the last breakpoint width and set max-width to its value +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - A map of breakpoints where the key is the name +/// @access private +/// @group @carbon/grid +@mixin carbon--set-largest-breakpoint($breakpoints: $carbon--grid-breakpoints) { + $largest-breakpoint: last-map-item($breakpoints); + + max-width: map-get($largest-breakpoint, 'width'); +} + +/// Add in the max-widths for each breakpoint to the container +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - A map of breakpoints where the key is the name +/// @access private +/// @group @carbon/grid +@mixin carbon--make-container-max-widths( + $breakpoints: $carbon--grid-breakpoints +) { + @each $name, $value in $breakpoints { + @include carbon--breakpoint($name) { + max-width: map-get($value, width); + } + } +} + +/// Generate the CSS for a grid for the given breakpoints and gutters +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - The default breakpoints +/// @param {Number} $grid-gutter [$carbon--grid-gutter] - The default gutters +/// @param {Number} $condensed-gutter [$carbon--grid-gutter--condensed] - The condensed mode gutter +/// @access public +/// @group @carbon/grid +@mixin carbon--grid( + $breakpoints: $carbon--grid-breakpoints, + $grid-gutter: $carbon--grid-gutter, + $condensed-gutter: $carbon--grid-gutter--condensed +) { + .#{$prefix}--grid { + @include carbon--make-container($breakpoints); + } + + @include carbon--largest-breakpoint($breakpoints) { + .#{$prefix}--grid--full-width { + max-width: 100%; + } + } + + .#{$prefix}--row { + @include carbon--make-row(); + } + + .#{$prefix}--grid--condensed [class*='#{$prefix}--col'] { + padding-top: $condensed-gutter / 2; + padding-bottom: $condensed-gutter / 2; + } + + @include carbon--make-grid-columns($breakpoints, $grid-gutter); + @include carbon--no-gutter(); + @include carbon--hang($grid-gutter); + @include carbon--aspect-ratio(); +} diff --git a/packages/components/src/globals/scss/vendor/@carbon/elements/scss/grid/_mixins.scss b/packages/components/src/globals/scss/vendor/@carbon/elements/scss/grid/_mixins.scss new file mode 100644 index 000000000000..b9d31e773bd6 --- /dev/null +++ b/packages/components/src/globals/scss/vendor/@carbon/elements/scss/grid/_mixins.scss @@ -0,0 +1,339 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +// Helpers for defining columns, rows, and containers are heavily inspired by, +// and often derived from, bootstrap: +// https://github.com/twbs/bootstrap/blob/v4-dev/scss/mixins/_grid.scss + +@import '../layout/breakpoint'; +@import 'prefix'; + +// ----------------------------------------------------------------------------- +// Columns +// ----------------------------------------------------------------------------- + +/// Used to initialize the default properties for a column class, most notably +/// for setting width and default gutters when a column's breakpoint has not been +/// hit yet. +/// @param {Number} $gutter [$carbon--grid-gutter] - The gutter for the grid system +/// @param {Number} $collapsed-gutter [$carbon--grid-gutter--condensed] - The condensed mode gutter +/// @access private +/// @group @carbon/grid +@mixin carbon--make-col-ready( + $gutter: $carbon--grid-gutter, + $condensed-gutter: $carbon--grid-gutter--condensed +) { + // Prevent columns from becoming too narrow when at smaller grid tiers by + // always setting `width: 100%;`. This works because we use `flex` values + // later on to override this initial width. + width: 100%; + padding-right: ($gutter / 2); + padding-left: ($gutter / 2); + + // For our condensed use-case, our gutters collapse to 2px solid, 1px on each + // side. + .#{$prefix}--row--condensed &, + .#{$prefix}--grid--condensed & { + padding-right: ($condensed-gutter / 2); + padding-left: ($condensed-gutter / 2); + } +} + +/// Define the width of the column for a given span and column count. +/// A width of 0 will hide the column entirely. +/// @param {Number} $span - The number of columns covered +/// @param {Number} $columns - The total number of columns available +/// @access private +/// @group @carbon/grid +@mixin carbon--make-col($span, $columns) { + @if $span == 0 { + display: none; + } @else { + // Explicitly include `display: block` to override + display: block; + flex: 0 0 percentage($span / $columns); + // Add a `max-width` to ensure content within each column does not blow out + // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari + // do not appear to require this. + max-width: percentage($span / $columns); + } +} + +/// Create a column offset for a given span and column count. +/// @param {Number} $span - The number of columns the offset should cover +/// @param {Number} $columns - The total number of columns available +/// @access private +/// @group @carbon/grid +@mixin carbon--make-col-offset($span, $columns) { + $offset: $span / $columns; + @if $offset == 0 { + margin-left: 0; + } @else { + margin-left: percentage($offset); + } +} + +/// Output the CSS required for all the columns in a given grid system. +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - The breakpoints in the grid system +/// @param {Number} $gutter [$carbon--grid-gutter] - The gutter for the grid system +/// @access private +/// @group @carbon/grid +@mixin carbon--make-grid-columns( + $breakpoints: $carbon--grid-breakpoints, + $gutter: $carbon--grid-gutter +) { + .#{$prefix}--col { + @include carbon--make-col-ready(); + } + + @each $breakpoint in map-keys($breakpoints) { + $infix: carbon--breakpoint-infix($breakpoint); + $columns: map-get(map-get($breakpoints, $breakpoint), columns); + + // Allow columns to stretch full width below their breakpoints + @for $i from 0 through $columns { + .#{$prefix}--col#{$infix}-#{$i} { + @include carbon--make-col-ready(); + } + } + + .#{$prefix}--col#{$infix}, + .#{$prefix}--col#{$infix}--auto { + @include carbon--make-col-ready(); + } + + @include carbon--breakpoint($breakpoint, $breakpoints) { + // Provide basic `.col-{bp}` classes for equal-width flexbox columns + .#{$prefix}--col, + .#{$prefix}--col#{$infix} { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; + } + + .#{$prefix}--col--auto, + .#{$prefix}--col#{$infix}--auto { + flex: 1 0 0%; + width: auto; + // Reset earlier grid tiers + max-width: 100%; + } + + @for $i from 0 through $columns { + .#{$prefix}--col#{$infix}-#{$i} { + @include carbon--make-col($i, $columns); + } + } + + @for $i from 0 through ($columns - 1) { + @if not($infix == '') { + .#{$prefix}--offset#{$infix}-#{$i} { + @include carbon--make-col-offset($i, $columns); + } + } + } + } + } +} + +// ----------------------------------------------------------------------------- +// Rows +// ----------------------------------------------------------------------------- + +/// Define the properties for a selector assigned to a row in the grid system. +/// @param {Number} $gutter [$carbon--grid-gutter] - The gutter in the grid system +/// @access private +/// @group @carbon/grid +@mixin carbon--make-row($gutter: $carbon--grid-gutter) { + display: flex; + flex-wrap: wrap; + margin-right: -1 * $gutter / 2; + margin-left: -1 * $gutter / 2; +} + +// ----------------------------------------------------------------------------- +// No gutter +// ----------------------------------------------------------------------------- + +/// Add `no-gutter` and `no-gutter--{left,right}` classes to the output CSS. These +/// classes are useful for dropping the gutter in fluid situations. +/// @access private +/// @group @carbon/grid +@mixin carbon--no-gutter { + .#{$prefix}--no-gutter, + .#{$prefix}--row.#{$prefix}--no-gutter [class*='#{$prefix}--col'] { + padding-left: 0; + padding-right: 0; + } + + .#{$prefix}--no-gutter--left, + .#{$prefix}--row.#{$prefix}--no-gutter--left [class*='#{$prefix}--col'] { + padding-left: 0; + } + + .#{$prefix}--no-gutter--right, + .#{$prefix}--row.#{$prefix}--no-gutter--right [class*='#{$prefix}--col'] { + padding-right: 0; + } +} + +// ----------------------------------------------------------------------------- +// Hang +// ----------------------------------------------------------------------------- + +/// Add `hang--left` and `hang--right` classes for a given gutter. These classes are +/// used alongside `no-gutter--left` and `no-gutter--right` to "hang" type. +/// @param {Number} $gutter [$carbon--grid-gutter] - The gutter in the grid system +/// @access private +/// @group @carbon/grid +@mixin carbon--hang($gutter: $carbon--grid-gutter) { + .#{$prefix}--hang--left { + padding-left: ($gutter / 2); + } + + .#{$prefix}--hang--right { + padding-right: ($gutter / 2); + } +} + +// ----------------------------------------------------------------------------- +// Aspect ratio +// ----------------------------------------------------------------------------- + +/// The aspect ratios that are used to generate corresponding aspect ratio +/// classes in code +/// @type List +/// @access public +/// @group @carbon/grid +$carbon--aspect-ratios: ((16, 9), (2, 1), (4, 3), (1, 1), (1, 2)); + +/// Output the CSS classes for generating aspect ratio classes +/// @param {List} $aspect-ratios [$carbon--aspect-ratios] - A list of aspect ratios to generate +/// @access private +/// @group @carbon/grid +@mixin carbon--aspect-ratio($aspect-ratios: $carbon--aspect-ratios) { + .#{$prefix}--aspect-ratio { + height: 0; + position: relative; + } + + .#{$prefix}--aspect-ratio--object { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + } + + @each $ratio in $aspect-ratios { + $width: nth($ratio, 1); + $height: nth($ratio, 2); + + .#{$prefix}--aspect-ratio--#{$width}x#{$height} { + padding-bottom: percentage($height / $width); + } + } +} + +// ----------------------------------------------------------------------------- +// Grid +// ----------------------------------------------------------------------------- + +/// Create the container for a grid. Will cause full-bleed for the grid unless +/// max-width properties are added with `make-container-max-widths` +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - A map of breakpoints where the key is the name +/// @access private +/// @group @carbon/grid +@mixin carbon--make-container($breakpoints: $carbon--grid-breakpoints) { + margin-right: auto; + margin-left: auto; + + @include carbon--set-largest-breakpoint(); + + @each $name, $value in $breakpoints { + $prev-breakpoint: map-get($breakpoints, carbon--breakpoint-prev($name)); + $margin: map-get($value, margin); + + @if $prev-breakpoint { + $prev-margin: map-get($prev-breakpoint, margin); + @if $prev-margin != $margin { + @include carbon--breakpoint($name) { + padding-left: #{($carbon--grid-gutter / 2) + $margin}; + padding-right: #{($carbon--grid-gutter / 2) + $margin}; + } + } + } @else { + @include carbon--breakpoint($name) { + padding-left: #{($carbon--grid-gutter / 2) + $margin}; + padding-right: #{($carbon--grid-gutter / 2) + $margin}; + } + } + } +} + +/// Get the last breakpoint width and set max-width to its value +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - A map of breakpoints where the key is the name +/// @access private +/// @group @carbon/grid +@mixin carbon--set-largest-breakpoint($breakpoints: $carbon--grid-breakpoints) { + $largest-breakpoint: last-map-item($breakpoints); + + max-width: map-get($largest-breakpoint, 'width'); +} + +/// Add in the max-widths for each breakpoint to the container +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - A map of breakpoints where the key is the name +/// @access private +/// @group @carbon/grid +@mixin carbon--make-container-max-widths( + $breakpoints: $carbon--grid-breakpoints +) { + @each $name, $value in $breakpoints { + @include carbon--breakpoint($name) { + max-width: map-get($value, width); + } + } +} + +/// Generate the CSS for a grid for the given breakpoints and gutters +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - The default breakpoints +/// @param {Number} $grid-gutter [$carbon--grid-gutter] - The default gutters +/// @param {Number} $condensed-gutter [$carbon--grid-gutter--condensed] - The condensed mode gutter +/// @access public +/// @group @carbon/grid +@mixin carbon--grid( + $breakpoints: $carbon--grid-breakpoints, + $grid-gutter: $carbon--grid-gutter, + $condensed-gutter: $carbon--grid-gutter--condensed +) { + .#{$prefix}--grid { + @include carbon--make-container($breakpoints); + } + + @include carbon--largest-breakpoint($breakpoints) { + .#{$prefix}--grid--full-width { + max-width: 100%; + } + } + + .#{$prefix}--row { + @include carbon--make-row(); + } + + .#{$prefix}--grid--condensed [class*='#{$prefix}--col'] { + padding-top: $condensed-gutter / 2; + padding-bottom: $condensed-gutter / 2; + } + + @include carbon--make-grid-columns($breakpoints, $grid-gutter); + @include carbon--no-gutter(); + @include carbon--hang($grid-gutter); + @include carbon--aspect-ratio(); +} diff --git a/packages/components/src/globals/scss/vendor/@carbon/grid/scss/_inlined/_mixins.scss b/packages/components/src/globals/scss/vendor/@carbon/grid/scss/_inlined/_mixins.scss new file mode 100644 index 000000000000..044afd79301e --- /dev/null +++ b/packages/components/src/globals/scss/vendor/@carbon/grid/scss/_inlined/_mixins.scss @@ -0,0 +1,339 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +// Helpers for defining columns, rows, and containers are heavily inspired by, +// and often derived from, bootstrap: +// https://github.com/twbs/bootstrap/blob/v4-dev/scss/mixins/_grid.scss + +@import '../vendor/@carbon/layout/breakpoint'; +@import 'prefix'; + +// ----------------------------------------------------------------------------- +// Columns +// ----------------------------------------------------------------------------- + +/// Used to initialize the default properties for a column class, most notably +/// for setting width and default gutters when a column's breakpoint has not been +/// hit yet. +/// @param {Number} $gutter [$carbon--grid-gutter] - The gutter for the grid system +/// @param {Number} $collapsed-gutter [$carbon--grid-gutter--condensed] - The condensed mode gutter +/// @access private +/// @group @carbon/grid +@mixin carbon--make-col-ready( + $gutter: $carbon--grid-gutter, + $condensed-gutter: $carbon--grid-gutter--condensed +) { + // Prevent columns from becoming too narrow when at smaller grid tiers by + // always setting `width: 100%;`. This works because we use `flex` values + // later on to override this initial width. + width: 100%; + padding-right: ($gutter / 2); + padding-left: ($gutter / 2); + + // For our condensed use-case, our gutters collapse to 2px solid, 1px on each + // side. + .#{$prefix}--row--condensed &, + .#{$prefix}--grid--condensed & { + padding-right: ($condensed-gutter / 2); + padding-left: ($condensed-gutter / 2); + } +} + +/// Define the width of the column for a given span and column count. +/// A width of 0 will hide the column entirely. +/// @param {Number} $span - The number of columns covered +/// @param {Number} $columns - The total number of columns available +/// @access private +/// @group @carbon/grid +@mixin carbon--make-col($span, $columns) { + @if $span == 0 { + display: none; + } @else { + // Explicitly include `display: block` to override + display: block; + flex: 0 0 percentage($span / $columns); + // Add a `max-width` to ensure content within each column does not blow out + // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari + // do not appear to require this. + max-width: percentage($span / $columns); + } +} + +/// Create a column offset for a given span and column count. +/// @param {Number} $span - The number of columns the offset should cover +/// @param {Number} $columns - The total number of columns available +/// @access private +/// @group @carbon/grid +@mixin carbon--make-col-offset($span, $columns) { + $offset: $span / $columns; + @if $offset == 0 { + margin-left: 0; + } @else { + margin-left: percentage($offset); + } +} + +/// Output the CSS required for all the columns in a given grid system. +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - The breakpoints in the grid system +/// @param {Number} $gutter [$carbon--grid-gutter] - The gutter for the grid system +/// @access private +/// @group @carbon/grid +@mixin carbon--make-grid-columns( + $breakpoints: $carbon--grid-breakpoints, + $gutter: $carbon--grid-gutter +) { + .#{$prefix}--col { + @include carbon--make-col-ready(); + } + + @each $breakpoint in map-keys($breakpoints) { + $infix: carbon--breakpoint-infix($breakpoint); + $columns: map-get(map-get($breakpoints, $breakpoint), columns); + + // Allow columns to stretch full width below their breakpoints + @for $i from 0 through $columns { + .#{$prefix}--col#{$infix}-#{$i} { + @include carbon--make-col-ready(); + } + } + + .#{$prefix}--col#{$infix}, + .#{$prefix}--col#{$infix}--auto { + @include carbon--make-col-ready(); + } + + @include carbon--breakpoint($breakpoint, $breakpoints) { + // Provide basic `.col-{bp}` classes for equal-width flexbox columns + .#{$prefix}--col, + .#{$prefix}--col#{$infix} { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; + } + + .#{$prefix}--col--auto, + .#{$prefix}--col#{$infix}--auto { + flex: 1 0 0%; + width: auto; + // Reset earlier grid tiers + max-width: 100%; + } + + @for $i from 0 through $columns { + .#{$prefix}--col#{$infix}-#{$i} { + @include carbon--make-col($i, $columns); + } + } + + @for $i from 0 through ($columns - 1) { + @if not($infix == '') { + .#{$prefix}--offset#{$infix}-#{$i} { + @include carbon--make-col-offset($i, $columns); + } + } + } + } + } +} + +// ----------------------------------------------------------------------------- +// Rows +// ----------------------------------------------------------------------------- + +/// Define the properties for a selector assigned to a row in the grid system. +/// @param {Number} $gutter [$carbon--grid-gutter] - The gutter in the grid system +/// @access private +/// @group @carbon/grid +@mixin carbon--make-row($gutter: $carbon--grid-gutter) { + display: flex; + flex-wrap: wrap; + margin-right: -1 * $gutter / 2; + margin-left: -1 * $gutter / 2; +} + +// ----------------------------------------------------------------------------- +// No gutter +// ----------------------------------------------------------------------------- + +/// Add `no-gutter` and `no-gutter--{left,right}` classes to the output CSS. These +/// classes are useful for dropping the gutter in fluid situations. +/// @access private +/// @group @carbon/grid +@mixin carbon--no-gutter { + .#{$prefix}--no-gutter, + .#{$prefix}--row.#{$prefix}--no-gutter [class*='#{$prefix}--col'] { + padding-left: 0; + padding-right: 0; + } + + .#{$prefix}--no-gutter--left, + .#{$prefix}--row.#{$prefix}--no-gutter--left [class*='#{$prefix}--col'] { + padding-left: 0; + } + + .#{$prefix}--no-gutter--right, + .#{$prefix}--row.#{$prefix}--no-gutter--right [class*='#{$prefix}--col'] { + padding-right: 0; + } +} + +// ----------------------------------------------------------------------------- +// Hang +// ----------------------------------------------------------------------------- + +/// Add `hang--left` and `hang--right` classes for a given gutter. These classes are +/// used alongside `no-gutter--left` and `no-gutter--right` to "hang" type. +/// @param {Number} $gutter [$carbon--grid-gutter] - The gutter in the grid system +/// @access private +/// @group @carbon/grid +@mixin carbon--hang($gutter: $carbon--grid-gutter) { + .#{$prefix}--hang--left { + padding-left: ($gutter / 2); + } + + .#{$prefix}--hang--right { + padding-right: ($gutter / 2); + } +} + +// ----------------------------------------------------------------------------- +// Aspect ratio +// ----------------------------------------------------------------------------- + +/// The aspect ratios that are used to generate corresponding aspect ratio +/// classes in code +/// @type List +/// @access public +/// @group @carbon/grid +$carbon--aspect-ratios: ((16, 9), (2, 1), (4, 3), (1, 1), (1, 2)); + +/// Output the CSS classes for generating aspect ratio classes +/// @param {List} $aspect-ratios [$carbon--aspect-ratios] - A list of aspect ratios to generate +/// @access private +/// @group @carbon/grid +@mixin carbon--aspect-ratio($aspect-ratios: $carbon--aspect-ratios) { + .#{$prefix}--aspect-ratio { + height: 0; + position: relative; + } + + .#{$prefix}--aspect-ratio--object { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + } + + @each $ratio in $aspect-ratios { + $width: nth($ratio, 1); + $height: nth($ratio, 2); + + .#{$prefix}--aspect-ratio--#{$width}x#{$height} { + padding-bottom: percentage($height / $width); + } + } +} + +// ----------------------------------------------------------------------------- +// Grid +// ----------------------------------------------------------------------------- + +/// Create the container for a grid. Will cause full-bleed for the grid unless +/// max-width properties are added with `make-container-max-widths` +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - A map of breakpoints where the key is the name +/// @access private +/// @group @carbon/grid +@mixin carbon--make-container($breakpoints: $carbon--grid-breakpoints) { + margin-right: auto; + margin-left: auto; + + @include carbon--set-largest-breakpoint(); + + @each $name, $value in $breakpoints { + $prev-breakpoint: map-get($breakpoints, carbon--breakpoint-prev($name)); + $margin: map-get($value, margin); + + @if $prev-breakpoint { + $prev-margin: map-get($prev-breakpoint, margin); + @if $prev-margin != $margin { + @include carbon--breakpoint($name) { + padding-left: #{($carbon--grid-gutter / 2) + $margin}; + padding-right: #{($carbon--grid-gutter / 2) + $margin}; + } + } + } @else { + @include carbon--breakpoint($name) { + padding-left: #{($carbon--grid-gutter / 2) + $margin}; + padding-right: #{($carbon--grid-gutter / 2) + $margin}; + } + } + } +} + +/// Get the last breakpoint width and set max-width to its value +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - A map of breakpoints where the key is the name +/// @access private +/// @group @carbon/grid +@mixin carbon--set-largest-breakpoint($breakpoints: $carbon--grid-breakpoints) { + $largest-breakpoint: last-map-item($breakpoints); + + max-width: map-get($largest-breakpoint, 'width'); +} + +/// Add in the max-widths for each breakpoint to the container +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - A map of breakpoints where the key is the name +/// @access private +/// @group @carbon/grid +@mixin carbon--make-container-max-widths( + $breakpoints: $carbon--grid-breakpoints +) { + @each $name, $value in $breakpoints { + @include carbon--breakpoint($name) { + max-width: map-get($value, width); + } + } +} + +/// Generate the CSS for a grid for the given breakpoints and gutters +/// @param {Map} $breakpoints [$carbon--grid-breakpoints] - The default breakpoints +/// @param {Number} $grid-gutter [$carbon--grid-gutter] - The default gutters +/// @param {Number} $condensed-gutter [$carbon--grid-gutter--condensed] - The condensed mode gutter +/// @access public +/// @group @carbon/grid +@mixin carbon--grid( + $breakpoints: $carbon--grid-breakpoints, + $grid-gutter: $carbon--grid-gutter, + $condensed-gutter: $carbon--grid-gutter--condensed +) { + .#{$prefix}--grid { + @include carbon--make-container($breakpoints); + } + + @include carbon--largest-breakpoint($breakpoints) { + .#{$prefix}--grid--full-width { + max-width: 100%; + } + } + + .#{$prefix}--row { + @include carbon--make-row(); + } + + .#{$prefix}--grid--condensed [class*='#{$prefix}--col'] { + padding-top: $condensed-gutter / 2; + padding-bottom: $condensed-gutter / 2; + } + + @include carbon--make-grid-columns($breakpoints, $grid-gutter); + @include carbon--no-gutter(); + @include carbon--hang($grid-gutter); + @include carbon--aspect-ratio(); +} diff --git a/packages/grid/README.md b/packages/grid/README.md index b6a422424d54..6d6643afd5be 100644 --- a/packages/grid/README.md +++ b/packages/grid/README.md @@ -20,6 +20,9 @@ yarn add @carbon/grid ## Usage +_More examples and documentation can be found on this +[live demo website](https://carbon-elements.netlify.com/grid/examples/preview/)._ + `@carbon/grid` has three primitive class types to use in order to structure your application. They include: diff --git a/packages/react/.storybook/config.js b/packages/react/.storybook/config.js index 25ef617dbd9b..497f5a52db04 100644 --- a/packages/react/.storybook/config.js +++ b/packages/react/.storybook/config.js @@ -32,6 +32,8 @@ addDecorator( addParameters({ options: { + // display in alphabetic order + storySort: (a, b) => a[1].id.localeCompare(b[1].id), theme: { brandTitle: 'carbon components react', brandUrl: @@ -68,9 +70,4 @@ addons.getChannel().on(CARBON_TYPE_TOKEN, ({ tokenName, tokenValue }) => { ); }); -function loadStories() { - const req = require.context('../src/components', true, /\-story\.js$/); - req.keys().forEach(filename => req(filename)); -} - -configure(loadStories, module); +configure(require.context('../src/components', true, /\-story\.js$/), module); diff --git a/packages/react/src/__tests__/index-test.js b/packages/react/src/__tests__/index-test.js index d2f1062ce83a..8d0cfc639b3c 100644 --- a/packages/react/src/__tests__/index-test.js +++ b/packages/react/src/__tests__/index-test.js @@ -28,6 +28,7 @@ describe('Carbon Components React', () => { "ClickableTile", "CodeSnippet", "CodeSnippetSkeleton", + "Column", "ComboBox", "ComposedModal", "Content", @@ -55,6 +56,7 @@ describe('Carbon Components React', () => { "FormGroup", "FormItem", "FormLabel", + "Grid", "Header", "HeaderContainer", "HeaderGlobalAction", @@ -96,6 +98,7 @@ describe('Carbon Components React', () => { "RadioButtonGroup", "RadioButtonSkeleton", "RadioTile", + "Row", "Search", "SearchFilterButton", "SearchLayoutButton", diff --git a/packages/react/src/components/Grid/Column.js b/packages/react/src/components/Grid/Column.js new file mode 100644 index 000000000000..e9ef5d9f6104 --- /dev/null +++ b/packages/react/src/components/Grid/Column.js @@ -0,0 +1,159 @@ +/** + * Copyright IBM Corp. 2016, 2018 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { settings } from 'carbon-components'; +import cx from 'classnames'; +import PropTypes from 'prop-types'; +import React from 'react'; + +const { prefix } = settings; + +function Column({ + as: BaseComponent = 'div', + children, + className: containerClassName, + sm, + md, + lg, + xlg, + max, + ...rest +}) { + const columnClassName = getClassNameForBreakpoints([sm, md, lg, xlg, max]); + const className = cx(containerClassName, columnClassName, { + [`${prefix}--col`]: columnClassName.length === 0, + }); + + return ( + + {children} + + ); +} + +const spanPropType = PropTypes.oneOfType([ + PropTypes.bool, + PropTypes.number, + PropTypes.shape({ + span: PropTypes.number, + offset: PropTypes.number, + }), +]); + +Column.propTypes = { + /** + * Provide a custom element to render instead of the default
+ */ + as: PropTypes.oneOfType([PropTypes.string, PropTypes.elementType]), + + /** + * Specify column span for the `sm` breakpoint (Default breakpoint up to 672px) + * This breakpoint supports 4 columns by default. + * + * @see https://www.carbondesignsystem.com/guidelines/layout#breakpoints + */ + sm: spanPropType, + + /** + * Specify column span for the `md` breakpoint (Default breakpoint up to 1056px) + * This breakpoint supports 8 columns by default. + * + * @see https://www.carbondesignsystem.com/guidelines/layout#breakpoints + */ + md: spanPropType, + + /** + * Specify column span for the `lg` breakpoint (Default breakpoint up to 1312px) + * This breakpoint supports 16 columns by default. + * + * @see https://www.carbondesignsystem.com/guidelines/layout#breakpoints + */ + lg: spanPropType, + + /** + * Specify column span for the `xlg` breakpoint (Default breakpoint up to + * 1584px) This breakpoint supports 16 columns by default. + * + * @see https://www.carbondesignsystem.com/guidelines/layout#breakpoints + */ + xlg: spanPropType, + + /** + * Specify column span for the `max` breakpoint. This breakpoint supports 16 + * columns by default. + * + * @see https://www.carbondesignsystem.com/guidelines/layout#breakpoints + */ + max: spanPropType, + + /** + * Specify a custom className to be applied to the `Column` + */ + className: PropTypes.string, + + /** + * Pass in content that will be rendered within the `Column` + */ + children: PropTypes.node, +}; + +const breakpointNames = ['sm', 'md', 'lg', 'xlg', 'max']; + +/** + * @typedef {object} Breakpoint + * @property {boolean|number} [span] + * @property {number} [offset] + */ + +/** + * Build the appropriate className for the given set of breakpoints. + * @param {Array} breakpoints + * @returns {string} + */ +function getClassNameForBreakpoints(breakpoints) { + const classNames = []; + + for (let i = 0; i < breakpoints.length; i++) { + const breakpoint = breakpoints[i]; + if (!breakpoint) { + continue; + } + + const name = breakpointNames[i]; + + // If our breakpoint is a boolean, the user has specified that the column + // should be "auto" at this size + if (breakpoint === true) { + classNames.push(`${prefix}--col-${name}`); + continue; + } + + // If our breakpoint is a number, the user has specified the number of + // columns they'd like this column to span + if (typeof breakpoint === 'number') { + classNames.push(`${prefix}--col-${name}-${breakpoint}`); + continue; + } + + const { span, offset } = breakpoint; + if (typeof span === 'number') { + classNames.push(`${prefix}--col-${name}-${span}`); + } + + if (span === true) { + classNames.push(`${prefix}--col-${name}`); + } + + if (typeof offset === 'number') { + classNames.push(`${prefix}--offset-${name}-${offset}`); + } + } + + return classNames.join(' '); +} + +export default Column; diff --git a/packages/react/src/components/Grid/Grid-story.js b/packages/react/src/components/Grid/Grid-story.js new file mode 100644 index 000000000000..25e4bdb6057f --- /dev/null +++ b/packages/react/src/components/Grid/Grid-story.js @@ -0,0 +1,158 @@ +import './Grid-story.scss'; +import React from 'react'; +import { Grid, Row, Column } from './'; + +export default { + decorators: [storyFn =>
{storyFn()}
], + title: 'Grid', +}; + +function DemoContent({ children }) { + return ( +
+
{children}
+
+ ); +} + +export const autoColumns = () => ( + + + + 1/4 + + + 1/4 + + + 1/4 + + + 1/4 + + + +); + +export const responsiveGrid = () => ( + + + + sm: 1/4, md: 1/2, lg: 2/3 + + + sm: 1/4, md: 1/4, lg: 1/6 + + + sm: 1/4, md: 1/8, lg: 1/12 + + + sm: 1/4, md: 1/8, lg: 1/12 + + + +); + +export const offset = () => ( + + + + Small Screen Offset 3 + + + Small Screen Offset 2 + + + Small Screen Offset 1 + + + Small Screen Offset 0 + + + +); + +export const condensed = () => ( + + + + 1/4 + + + 1/4 + + + 1/4 + + + 1/4 + + + +); + +export const condensedColumns = () => ( + + + + 1/4 + + + 1/4 + + + 1/4 + + + 1/4 + + + + + 1/4 + + + 1/4 + + + 1/4 + + + 1/4 + + + + + 1/4 + + + 1/4 + + + 1/4 + + + 1/4 + + + +); + +export const fullWidth = () => ( + + + + 1/4 + + + 1/4 + + + 1/4 + + + 1/4 + + + +); diff --git a/packages/react/src/components/Grid/Grid-story.scss b/packages/react/src/components/Grid/Grid-story.scss new file mode 100644 index 000000000000..e9c3a47afa73 --- /dev/null +++ b/packages/react/src/components/Grid/Grid-story.scss @@ -0,0 +1,60 @@ +@import '~carbon-components/scss/globals/scss/colors'; + +// base of project work area +#root > div:first-child > div:first-child { + width: 100%; +} + +// grid styles +#root .outside { + min-height: 80px; + height: 100%; +} + +#root .inside { + min-height: 80px; + height: 100%; +} + +// hack to enable zoom feature to trigger +.bx--grid--full-width { + max-width: 100%; +} + +.default .bx--col code { + display: flex; + justify-content: center; +} + +// template hard-coded styles +#templates .inside { + background-color: $blue-10; +} + +#templates [class*='col'] { + background-color: $blue-20; + outline: 1px dashed $blue-40; +} + +#templates .bx--grid--condensed, +#templates .bx--row--condensed { + background-color: $warm-gray-100; + color: $gray-10; +} + +#templates .bx--grid--condensed [class*='col'], +#templates .bx--row--condensed [class*='col'] { + background: none; + outline: none; +} + +#templates .bx--grid--condensed .outside, +#templates .bx--row--condensed .outside { + background-color: $gray-80; + outline: none; +} + +#templates .bx--grid--condensed .inside, +#templates .bx--row--condensed .inside { + background: none; +} diff --git a/packages/react/src/components/Grid/Grid.js b/packages/react/src/components/Grid/Grid.js new file mode 100644 index 000000000000..5518f29c9779 --- /dev/null +++ b/packages/react/src/components/Grid/Grid.js @@ -0,0 +1,64 @@ +/** + * Copyright IBM Corp. 2016, 2018 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { settings } from 'carbon-components'; +import cx from 'classnames'; +import PropTypes from 'prop-types'; +import React from 'react'; + +const { prefix } = settings; + +function Grid({ + as: BaseComponent = 'div', + condensed = false, + fullWidth = false, + className: containerClassName, + children, + ...rest +}) { + const className = cx(containerClassName, { + [`${prefix}--grid`]: true, + [`${prefix}--grid--condensed`]: condensed, + [`${prefix}--grid--full-width`]: fullWidth, + }); + + return ( + + {children} + + ); +} + +Grid.propTypes = { + /** + * Provide a custom element to render instead of the default
+ */ + as: PropTypes.oneOfType([PropTypes.string, PropTypes.elementType]), + + /** + * Collapse the gutter to 2px. Useful for fluid layouts. + * Rows have 2px of margin between them to match gutter. + */ + condensed: PropTypes.bool, + + /** + * Remove the default max width that the grid has set + */ + fullWidth: PropTypes.bool, + + /** + * Specify a custom className to be applied to the `Grid` + */ + className: PropTypes.string, + + /** + * Pass in content that will be rendered within the `Grid` + */ + children: PropTypes.node, +}; + +export default Grid; diff --git a/packages/react/src/components/Grid/Row.js b/packages/react/src/components/Grid/Row.js new file mode 100644 index 000000000000..9444bfbcb88d --- /dev/null +++ b/packages/react/src/components/Grid/Row.js @@ -0,0 +1,57 @@ +/** + * Copyright IBM Corp. 2016, 2018 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { settings } from 'carbon-components'; +import cx from 'classnames'; +import PropTypes from 'prop-types'; +import React from 'react'; + +const { prefix } = settings; + +function Row({ + as: BaseComponent = 'div', + condensed = false, + className: containerClassName, + children, + ...rest +}) { + const className = cx(containerClassName, { + [`${prefix}--row`]: true, + [`${prefix}--row--condensed`]: condensed, + }); + + return ( + + {children} + + ); +} + +Row.propTypes = { + /** + * Provide a custom element to render instead of the default
+ */ + as: PropTypes.oneOfType([PropTypes.string, PropTypes.elementType]), + + /** + * Specify a single row as condensed.Rows that are adjacent + * and are condensed will have 2px of margin between them to match gutter. + */ + condensed: PropTypes.bool, + + /** + * Specify a custom className to be applied to the `Row` + */ + className: PropTypes.string, + + /** + * Pass in content that will be rendered within the `Row` + */ + children: PropTypes.node, +}; + +export default Row; diff --git a/packages/react/src/components/Grid/__tests__/Column-test.js b/packages/react/src/components/Grid/__tests__/Column-test.js new file mode 100644 index 000000000000..965cc1437b3d --- /dev/null +++ b/packages/react/src/components/Grid/__tests__/Column-test.js @@ -0,0 +1,108 @@ +/** + * Copyright IBM Corp. 2016, 2018 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { render, cleanup } from '@carbon/test-utils/react'; +import { settings } from 'carbon-components'; +import React from 'react'; +import { Column } from '../'; + +const { prefix } = settings; + +describe('Column', () => { + afterEach(cleanup); + + it('should support a custom element as the root node', () => { + const { container } = render(); + expect(container.firstChild.tagName).toBe('SECTION'); + }); + + it('should include a custom className', () => { + const { container } = render(); + expect(container.firstChild.classList.contains('test')).toBe(true); + }); + + it('should pass un-used props to the top-level node that is rendered', () => { + const { container } = render(); + expect(container.firstChild.getAttribute('id')).toBe('test'); + }); + + it('should render `children` that are given', () => { + const { container } = render( + + Test + + ); + const testNode = container.querySelector('#test'); + expect(testNode).toBeInstanceOf(HTMLElement); + }); + + it('should default to rendering a column that auto-spans', () => { + const { container } = render(); + expect(container.firstChild.classList.contains(`${prefix}--col`)).toBe( + true + ); + }); + + it('should set the column span per breakpoint with a number', () => { + const breakpoints = ['sm', 'md', 'lg', 'xlg', 'max']; + const spans = [1, 2, 3, 4, 5]; + const props = {}; + + for (let i = 0; i < breakpoints.length; i++) { + const name = breakpoints[i]; + props[name] = spans[i]; + } + + const { container } = render(); + const { firstChild: column } = container; + + for (let i = 0; i < column.classList.length; i++) { + const name = breakpoints[i]; + const span = spans[i]; + const className = column.classList[i]; + expect(className).toEqual(expect.stringContaining(`col-${name}-${span}`)); + } + }); + + it('should set the column span to auto if a boolean is set to true for a breakpoint', () => { + const breakpoints = ['sm', 'md', 'lg', 'xlg', 'max']; + const props = {}; + + for (let i = 0; i < breakpoints.length; i++) { + const name = breakpoints[i]; + props[name] = true; + } + + const { container } = render(); + const { firstChild: column } = container; + for (let i = 0; i < column.classList.length; i++) { + const name = breakpoints[i]; + const className = column.classList[i]; + expect(className).toEqual(expect.stringContaining(`col-${name}`)); + } + }); + + it.each(['sm', 'md', 'lg', 'xlg', 'max'])( + 'should support specifying column span and offset as an object for breakpoint %s', + breakpoint => { + const { container } = render( + React.createElement(Column, { + [breakpoint]: { + span: 1, + offset: 1, + }, + }) + ); + expect(container.firstChild.className).toEqual( + expect.stringContaining(`col-${breakpoint}-1`) + ); + expect(container.firstChild.className).toEqual( + expect.stringContaining(`offset-${breakpoint}-1`) + ); + } + ); +}); diff --git a/packages/react/src/components/Grid/__tests__/Grid-test.js b/packages/react/src/components/Grid/__tests__/Grid-test.js new file mode 100644 index 000000000000..555371d859a9 --- /dev/null +++ b/packages/react/src/components/Grid/__tests__/Grid-test.js @@ -0,0 +1,53 @@ +/** + * Copyright IBM Corp. 2019 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { render, cleanup } from '@carbon/test-utils/react'; +import React from 'react'; +import { Grid } from '../'; + +describe('Grid', () => { + afterEach(cleanup); + + it('should support a custom element as the root node', () => { + const { container } = render(); + expect(container.firstChild.tagName).toBe('SECTION'); + }); + + it('should include a custom className', () => { + const { container } = render(); + expect(container.firstChild.classList.contains('test')).toBe(true); + }); + + it('should pass un-used props to the top-level node that is rendered', () => { + const { container } = render(); + expect(container.firstChild.getAttribute('id')).toBe('test'); + }); + + it('should render `children` that are given', () => { + const { container } = render( + + Test + + ); + const testNode = container.querySelector('#test'); + expect(testNode).toBeInstanceOf(HTMLElement); + }); + + it('should support setting the condensed class through the `condensed` prop', () => { + const { container } = render(); + expect(container.firstChild.className).toEqual( + expect.stringContaining('grid--condensed') + ); + }); + + it('should support setting the full-width class through the `fullWidth` prop', () => { + const { container } = render(); + expect(container.firstChild.className).toEqual( + expect.stringContaining('grid--full-width') + ); + }); +}); diff --git a/packages/react/src/components/Grid/__tests__/Row-test.js b/packages/react/src/components/Grid/__tests__/Row-test.js new file mode 100644 index 000000000000..f6683b76173f --- /dev/null +++ b/packages/react/src/components/Grid/__tests__/Row-test.js @@ -0,0 +1,46 @@ +/** + * Copyright IBM Corp. 2016, 2018 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { render, cleanup } from '@carbon/test-utils/react'; +import React from 'react'; +import { Row } from '../'; + +describe('Row', () => { + afterEach(cleanup); + + it('should support a custom element as the root node', () => { + const { container } = render(); + expect(container.firstChild.tagName).toBe('SECTION'); + }); + + it('should include a custom className', () => { + const { container } = render(); + expect(container.firstChild.classList.contains('test')).toBe(true); + }); + + it('should pass un-used props to the top-level node that is rendered', () => { + const { container } = render(); + expect(container.firstChild.getAttribute('id')).toBe('test'); + }); + + it('should render `children` that are given', () => { + const { container } = render( + + Test + + ); + const testNode = container.querySelector('#test'); + expect(testNode).toBeInstanceOf(HTMLElement); + }); + + it('should support setting the condensed class through the `condensed` prop', () => { + const { container } = render(); + expect(container.firstChild.className).toEqual( + expect.stringContaining('row--condensed') + ); + }); +}); diff --git a/packages/react/src/components/Grid/index.js b/packages/react/src/components/Grid/index.js new file mode 100644 index 000000000000..9eade1048838 --- /dev/null +++ b/packages/react/src/components/Grid/index.js @@ -0,0 +1,10 @@ +/** + * Copyright IBM Corp. 2016, 2018 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +export { default as Grid } from './Grid'; +export { default as Row } from './Row'; +export { default as Column } from './Column'; diff --git a/packages/react/src/components/Toolbar/Toolbar-story.js b/packages/react/src/components/Toolbar/Toolbar-story.js index 6e1ecfd22dcf..be1b0563277c 100644 --- a/packages/react/src/components/Toolbar/Toolbar-story.js +++ b/packages/react/src/components/Toolbar/Toolbar-story.js @@ -29,7 +29,7 @@ const inputProps = { onChange: action('onChange'), }; -storiesOf('[Deprecated] Toolbar', module).add( +storiesOf('Toolbar [Deprecated]', module).add( 'Default', () => ( diff --git a/packages/react/src/index.js b/packages/react/src/index.js index c040649f2d61..8717c1877107 100644 --- a/packages/react/src/index.js +++ b/packages/react/src/index.js @@ -61,6 +61,7 @@ export Form from './components/Form'; export FormGroup from './components/FormGroup'; export FormItem from './components/FormItem'; export FormLabel from './components/FormLabel'; +export { Grid, Row, Column } from './components/Grid'; export Icon from './components/Icon'; export InlineLoading from './components/InlineLoading'; export Link from './components/Link'; diff --git a/yarn.lock b/yarn.lock index d761425d4c06..5dba2fc33c13 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2649,7 +2649,7 @@ ts-dedent "^1.1.0" util-deprecate "^1.0.2" -"@storybook/addon-actions@^5.1.11", "@storybook/addon-actions@^5.2.1": +"@storybook/addon-actions@^5.1.11": version "5.3.9" resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-5.3.9.tgz#fc8b1d912c87f418e69c2b52031d29465bb4867b" integrity sha512-saTxUXnu8O8pE1G2yPDY8NbvK+qZS27HcoeN3HzU/ooAQDffMTnreU4C8LU6/yKAx4KBDvXS4oyiBguOlQfIgg== @@ -2669,6 +2669,26 @@ react-inspector "^4.0.0" uuid "^3.3.2" +"@storybook/addon-actions@^5.2.1": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-5.3.0.tgz#04927681118469f7db0c8cde7c21ba01c4486640" + integrity sha512-vt1yzMeP8rtNqmxo3Ix/uqRQf45sAzgbHJ2celO8Fw8rDf3yaBdgquSK5JmDUNb5yk8dj/YkTao+IGQfBMLCNQ== + dependencies: + "@storybook/addons" "5.3.0" + "@storybook/api" "5.3.0" + "@storybook/client-api" "5.3.0" + "@storybook/components" "5.3.0" + "@storybook/core-events" "5.3.0" + "@storybook/theming" "5.3.0" + core-js "^3.0.1" + fast-deep-equal "^2.0.1" + global "^4.3.2" + polished "^3.3.1" + prop-types "^15.7.2" + react "^16.8.3" + react-inspector "^4.0.0" + uuid "^3.3.2" + "@storybook/addon-info@^5.2.1": version "5.3.9" resolved "https://registry.yarnpkg.com/@storybook/addon-info/-/addon-info-5.3.9.tgz#626950c69fdbfe9a22b0c4f4f2ae9531f9431c67" @@ -2749,6 +2769,19 @@ regenerator-runtime "^0.13.3" util-deprecate "^1.0.2" +"@storybook/addons@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.3.0.tgz#93e57742085acd69f2b82b35ec4890420beae0e4" + integrity sha512-++/dIpvf6dzcGBHUMIf+juFvMiffexmAFilHZRGOvV8FuU8X2dKrQ1zIoyPVtHintx6HPgXA7KClbLm9r/wC8Q== + dependencies: + "@storybook/api" "5.3.0" + "@storybook/channels" "5.3.0" + "@storybook/client-logger" "5.3.0" + "@storybook/core-events" "5.3.0" + core-js "^3.0.1" + global "^4.3.2" + util-deprecate "^1.0.2" + "@storybook/addons@5.3.9", "@storybook/addons@^5.1.11", "@storybook/addons@^5.2.1": version "5.3.9" resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.3.9.tgz#f2492de356e0cd38e3da357f4dafa058a4756e36" @@ -2762,6 +2795,32 @@ global "^4.3.2" util-deprecate "^1.0.2" +"@storybook/api@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.3.0.tgz#1fbcc2f400958e42a6d7face0e1a50c47cf8ac86" + integrity sha512-U8IDgPI7rzwng/JdWleZhMEkIQGpL9w0SgpJLFCDA8e0yAa1lUaMn56wD2ksud2qjVktHQCTnYf7xsNpF4IvBQ== + dependencies: + "@reach/router" "^1.2.1" + "@storybook/channels" "5.3.0" + "@storybook/client-logger" "5.3.0" + "@storybook/core-events" "5.3.0" + "@storybook/csf" "0.0.1" + "@storybook/router" "5.3.0" + "@storybook/theming" "5.3.0" + "@types/reach__router" "^1.2.3" + core-js "^3.0.1" + fast-deep-equal "^2.0.1" + global "^4.3.2" + lodash "^4.17.15" + memoizerific "^1.11.3" + prop-types "^15.6.2" + react "^16.8.3" + semver "^6.0.0" + shallow-equal "^1.1.0" + store2 "^2.7.1" + telejson "^3.2.0" + util-deprecate "^1.0.2" + "@storybook/api@5.3.9": version "5.3.9" resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.3.9.tgz#090119c6fd4082442e926a434d3d171535ec6784" @@ -2788,6 +2847,17 @@ telejson "^3.2.0" util-deprecate "^1.0.2" +"@storybook/channel-postmessage@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.3.0.tgz#70d9ddb96af839e934a9f515c28a5461137ad859" + integrity sha512-HZp/ZhDBWWcZB0D3n7tCTwPHPYZJhD1oyI3a8e07jiBOoOqy4uqCP0F3UxBjAqZAVLaZw4sWrB5Z1EPjPBiGyg== + dependencies: + "@storybook/channels" "5.3.0" + "@storybook/client-logger" "5.3.0" + core-js "^3.0.1" + global "^4.3.2" + telejson "^3.2.0" + "@storybook/channel-postmessage@5.3.9": version "5.3.9" resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.3.9.tgz#3846ae7ea5bc2fe36b1ef64fbc215f480cf8a189" @@ -2799,6 +2869,13 @@ global "^4.3.2" telejson "^3.2.0" +"@storybook/channels@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.3.0.tgz#d124815216df6a48161f0ff2a31c18ba6412f5f0" + integrity sha512-qa43flSWfHtPo5UlokcMfnFNeZ/UG49H9AQokjoUXUepQWeSneqKFVPNktOLaciUTownKVXuT2gCxsUGKZMs8g== + dependencies: + core-js "^3.0.1" + "@storybook/channels@5.3.9": version "5.3.9" resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.3.9.tgz#7ee8f6e6f4c9465227120d6711805b5e6862107f" @@ -2806,6 +2883,28 @@ dependencies: core-js "^3.0.1" +"@storybook/client-api@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.3.0.tgz#b2f1e7bbbfb1db36e2788314150e3291a1370b79" + integrity sha512-JhsIKgru+eabq8YQGe1VzDiPtbMVUkNnpoiIwGY9tGiChoVYuEXOFlDprmdQ4ONBSWjq4rzsl/XaYISVwlnkXA== + dependencies: + "@storybook/addons" "5.3.0" + "@storybook/channel-postmessage" "5.3.0" + "@storybook/channels" "5.3.0" + "@storybook/client-logger" "5.3.0" + "@storybook/core-events" "5.3.0" + "@storybook/csf" "0.0.1" + core-js "^3.0.1" + eventemitter3 "^4.0.0" + global "^4.3.2" + is-plain-object "^3.0.0" + lodash "^4.17.15" + memoizerific "^1.11.3" + qs "^6.6.0" + stable "^0.1.8" + ts-dedent "^1.1.0" + util-deprecate "^1.0.2" + "@storybook/client-api@5.3.9": version "5.3.9" resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.3.9.tgz#43ae2651bf303e832e97c014fd6c77a523669fd9" @@ -2829,6 +2928,13 @@ ts-dedent "^1.1.0" util-deprecate "^1.0.2" +"@storybook/client-logger@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.3.0.tgz#e609b97d2e942183b7520f76f29d86d83f7420e6" + integrity sha512-pnAsrL7luTgaeVloNZYq8Oxdvfg+G31o09Pcq8POzcbcbh8QCa66C5W4LIrs8bq4yxAwqitdNMGdV+8g5WrkFA== + dependencies: + core-js "^3.0.1" + "@storybook/client-logger@5.3.9": version "5.3.9" resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.3.9.tgz#06654be9caa8d37366270b0426c2d5acb217f504" @@ -2836,6 +2942,33 @@ dependencies: core-js "^3.0.1" +"@storybook/components@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.3.0.tgz#0746a3dfe45b56b661fed6230b655d0d47dc6233" + integrity sha512-i7EAYd5okZ3d43+mP6SdgWR0a888eRIzbA8/uFXU4ay4eFbS9caribciRFkvcsX6QNVzcclUEXX9AxsDxw6SGg== + dependencies: + "@storybook/client-logger" "5.3.0" + "@storybook/theming" "5.3.0" + "@types/react-syntax-highlighter" "11.0.2" + "@types/react-textarea-autosize" "^4.3.3" + core-js "^3.0.1" + global "^4.3.2" + lodash "^4.17.15" + markdown-to-jsx "^6.9.1" + memoizerific "^1.11.3" + polished "^3.3.1" + popper.js "^1.14.7" + prop-types "^15.7.2" + react "^16.8.3" + react-dom "^16.8.3" + react-focus-lock "^2.1.0" + react-helmet-async "^1.0.2" + react-popper-tooltip "^2.8.3" + react-syntax-highlighter "^11.0.2" + react-textarea-autosize "^7.1.0" + simplebar-react "^1.0.0-alpha.6" + ts-dedent "^1.1.0" + "@storybook/components@5.3.9", "@storybook/components@^5.0.6": version "5.3.9" resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.3.9.tgz#1fbc688770889ddadb8c603f5a4dbcf987f3eb0f" @@ -2863,6 +2996,13 @@ simplebar-react "^1.0.0-alpha.6" ts-dedent "^1.1.0" +"@storybook/core-events@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.3.0.tgz#cc4f08d1e41c9fa25d06c36f7fb2b8cee6204e36" + integrity sha512-QT9IgZbCusKUTXkp58JT9AslXAXxF5t/QquOy9Id2HS6RZMcSllobZlVqLlWmyaRmtQbNTTPkjgndOWQIQi3ew== + dependencies: + core-js "^3.0.1" + "@storybook/core-events@5.3.9", "@storybook/core-events@^5.0.6": version "5.3.9" resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.3.9.tgz#3c7fbc20204ae4b937c896ed6281e782cc09c4aa" @@ -2995,6 +3135,21 @@ ts-dedent "^1.1.0" webpack "^4.33.0" +"@storybook/router@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.3.0.tgz#eaa1492ac3bef903b229892733112fb50a487c36" + integrity sha512-4YwTZR6hCPL9l4SWAjAhTQlHopoOhXzwHcV8WhFReSYgaog7FSnyYXe0GFGxDZhXQTF51VdEV06bQxNLEZWXZg== + dependencies: + "@reach/router" "^1.2.1" + "@storybook/csf" "0.0.1" + "@types/reach__router" "^1.2.3" + core-js "^3.0.1" + global "^4.3.2" + lodash "^4.17.15" + memoizerific "^1.11.3" + qs "^6.6.0" + util-deprecate "^1.0.2" + "@storybook/router@5.3.9": version "5.3.9" resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.3.9.tgz#3c6e01f4dced9de8e8c5c314352fdc437f2441c2" @@ -3026,6 +3181,24 @@ prop-types "^15.7.2" regenerator-runtime "^0.13.3" +"@storybook/theming@5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.3.0.tgz#d6431399b07126c78c9e023759aa34bda9137f8e" + integrity sha512-pOxtQz2uZCfxIlCAg+3kQJE3VbQ0x0GB6vzpg2UoiNm9b3UA/lY8Avw0Zv0tWsaQRtVZctCKP6/q5m+nF6QRFA== + dependencies: + "@emotion/core" "^10.0.20" + "@emotion/styled" "^10.0.17" + "@storybook/client-logger" "5.3.0" + core-js "^3.0.1" + deep-object-diff "^1.1.0" + emotion-theming "^10.0.19" + global "^4.3.2" + memoizerific "^1.11.3" + polished "^3.3.1" + prop-types "^15.7.2" + resolve-from "^5.0.0" + ts-dedent "^1.1.0" + "@storybook/theming@5.3.9": version "5.3.9" resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.3.9.tgz#caaeea398f9e630394298ccfe8f36a185a289e4f" @@ -19882,7 +20055,7 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.0.1, schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.1, schema-utils@^2.6.4: +schema-utils@^2.0.1, schema-utils@^2.6.0, schema-utils@^2.6.1, schema-utils@^2.6.4: version "2.6.4" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.4.tgz#a27efbf6e4e78689d91872ee3ccfa57d7bdd0f53" integrity sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ== @@ -19890,6 +20063,14 @@ schema-utils@^2.0.1, schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6 ajv "^6.10.2" ajv-keywords "^3.4.1" +schema-utils@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.1.tgz#eb78f0b945c7bcfa2082b3565e8db3548011dc4f" + integrity sha512-0WXHDs1VDJyo+Zqs9TKLKyD/h7yDpHUhEFsM2CzkICFdoX1av+GBq/J2xRTFfsQO5kBfhZzANf2VcIm84jqDbg== + dependencies: + ajv "^6.10.2" + ajv-keywords "^3.4.1" + scss-comment-parser@^0.8.4: version "0.8.4" resolved "https://registry.yarnpkg.com/scss-comment-parser/-/scss-comment-parser-0.8.4.tgz#8e82c3fcf7fdbbb7f172f8955e2aa88b685f86d8"