From 1af03df10490fe3820f6c7632fc9a938f1ac5f74 Mon Sep 17 00:00:00 2001 From: Kevin Perrine Date: Thu, 14 Oct 2021 18:26:30 -0400 Subject: [PATCH 01/15] fix(repo): add check around math.div usage (#9850) Co-authored-by: Abbey Hart --- .../src/globals/scss/_typography.import.scss | 13 +++- packages/grid/scss/_mixins.import.scss | 61 ++++++++++++------- packages/grid/scss/modules/_css-grid.scss | 7 ++- packages/grid/scss/modules/_mixins.scss | 17 +++++- packages/layout/scss/_convert.import.scss | 13 +++- packages/layout/scss/_key-height.import.scss | 7 ++- packages/layout/scss/modules/_convert.scss | 13 +++- packages/styles/scss/utilities/_convert.scss | 17 ++++-- packages/type/scss/_styles.import.scss | 7 ++- 9 files changed, 116 insertions(+), 39 deletions(-) diff --git a/packages/components/src/globals/scss/_typography.import.scss b/packages/components/src/globals/scss/_typography.import.scss index be16159322c2..31529608aa37 100644 --- a/packages/components/src/globals/scss/_typography.import.scss +++ b/packages/components/src/globals/scss/_typography.import.scss @@ -19,6 +19,7 @@ // compatibility file to ensure we continue to support node-sass and dart-sass // in v10. +@use 'sass:meta'; @use 'sass:math'; @import 'vars'; /* stylelint-disable-line no-invalid-position-at-import-rule */ @@ -42,7 +43,11 @@ $base-font-size: 16px !default; @warn "Expected argument $px to be of type `px`, instead received: `#{unit($px)}`"; } - @return math.div($px, $base-font-size) * 1rem; + @if meta.function-exists('div', 'math') { + @return math.div($px, $base-font-size) * 1rem; + } @else { + @return ($px / $base-font-size) * 1rem; + } } /// Convert px to em @@ -58,7 +63,11 @@ $base-font-size: 16px !default; @warn "Expected argument $px to be of type `px`, instead received: `#{unit($px)}`"; } - @return math.div($px, $base-font-size) * 1em; + @if meta.function-exists('div', 'math') { + @return math.div($px, $base-font-size) * 1em; + } @else { + @return ($px / $base-font-size) * 1em; + } } // 🔬 Experimental diff --git a/packages/grid/scss/_mixins.import.scss b/packages/grid/scss/_mixins.import.scss index 798b69268159..e799c31da54f 100644 --- a/packages/grid/scss/_mixins.import.scss +++ b/packages/grid/scss/_mixins.import.scss @@ -23,6 +23,7 @@ // and often derived from, bootstrap: // https://github.com/twbs/bootstrap/blob/v4-dev/scss/mixins/_grid.scss +@use 'sass:meta'; @use 'sass:math'; @import '@carbon/layout/scss/breakpoint'; /* stylelint-disable-line no-invalid-position-at-import-rule */ @import 'prefix'; /* stylelint-disable-line no-invalid-position-at-import-rule */ @@ -46,21 +47,21 @@ // always setting `width: 100%;`. This works because we use `flex` values // later on to override this initial width. width: 100%; - padding-right: math.div($gutter, 2); - padding-left: math.div($gutter, 2); + padding-right: $gutter * 0.5; + padding-left: $gutter * 0.5; // For our condensed use-case, our gutters collapse to 2px solid, 1px on each // side. .#{$prefix}--row--condensed &, .#{$prefix}--grid--condensed & { - padding-right: math.div($condensed-gutter, 2); - padding-left: math.div($condensed-gutter, 2); + padding-right: $condensed-gutter * 0.5; + padding-left: $condensed-gutter * 0.5; } // For our narrow use-case, our container hangs 16px into the gutter .#{$prefix}--row--narrow &, .#{$prefix}--grid--narrow & { - padding-right: math.div($gutter, 2); + padding-right: $gutter * 0.5; padding-left: 0; } } @@ -80,8 +81,13 @@ // 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(math.div($span, $columns)); - flex: 0 0 percentage(math.div($span, $columns)); + @if meta.function-exists('div', 'math') { + max-width: percentage(math.div($span, $columns)); + flex: 0 0 percentage(math.div($span, $columns)); + } @else { + max-width: percentage(($span / $columns)); + flex: 0 0 percentage(($span / $columns)); + } } } @@ -91,7 +97,12 @@ /// @access private /// @group @carbon/grid @mixin carbon--make-col-offset($span, $columns) { - $offset: math.div($span, $columns); + $offset: 0; + @if meta.function-exists('div', 'math') { + $offset: math.div($span, $columns); + } @else { + $offset: ($span / $columns); + } @if $offset == 0 { margin-left: 0; } @else { @@ -173,8 +184,8 @@ @mixin carbon--make-row($gutter: $carbon--grid-gutter) { display: flex; flex-wrap: wrap; - margin-right: -1 * math.div($gutter, 2); - margin-left: -1 * math.div($gutter, 2); + margin-right: -1 * $gutter * 0.5; + margin-left: -1 * $gutter * 0.5; } // ----------------------------------------------------------------------------- @@ -225,20 +236,20 @@ /// @group @carbon/grid @mixin carbon--hang($gutter: $carbon--grid-gutter) { .#{$prefix}--hang--start { - padding-left: math.div($gutter, 2); + padding-left: $gutter * 0.5; } .#{$prefix}--hang--end { - padding-right: math.div($gutter, 2); + padding-right: $gutter * 0.5; } // Deprecated ☠️ .#{$prefix}--hang--left { - padding-left: math.div($gutter, 2); + padding-left: $gutter * 0.5; } .#{$prefix}--hang--right { - padding-right: math.div($gutter, 2); + padding-right: $gutter * 0.5; } } @@ -299,7 +310,11 @@ $carbon--aspect-ratios: ( $height: nth($aspect-ratio, 2); .#{$prefix}--aspect-ratio--#{$width}x#{$height}::before { - padding-top: percentage(math.div($height, $width)); + @if meta.function-exists('div', 'math') { + padding-top: percentage(math.div($height, $width)); + } @else { + padding-top: percentage(($height / $width)); + } } } @@ -336,14 +351,14 @@ $carbon--aspect-ratios: ( $prev-margin: map-get($prev-breakpoint, margin); @if $prev-margin != $margin { @include carbon--breakpoint($name) { - padding-right: #{math.div($carbon--grid-gutter, 2) + $margin}; - padding-left: #{math.div($carbon--grid-gutter, 2) + $margin}; + padding-right: #{($carbon--grid-gutter * 0.5) + $margin}; + padding-left: #{($carbon--grid-gutter * 0.5) + $margin}; } } } @else { @include carbon--breakpoint($name) { - padding-right: #{math.div($carbon--grid-gutter, 2) + $margin}; - padding-left: #{math.div($carbon--grid-gutter, 2) + $margin}; + padding-right: #{($carbon--grid-gutter * 0.5) + $margin}; + padding-left: #{($carbon--grid-gutter * 0.5) + $margin}; } } } @@ -400,13 +415,13 @@ $carbon--aspect-ratios: ( .#{$prefix}--row-padding [class*='#{$prefix}--col'], .#{$prefix}--col-padding { - padding-top: math.div($grid-gutter, 2); - padding-bottom: math.div($grid-gutter, 2); + padding-top: $grid-gutter * 0.5; + padding-bottom: $grid-gutter * 0.5; } .#{$prefix}--grid--condensed [class*='#{$prefix}--col'] { - padding-top: math.div($condensed-gutter, 2); - padding-bottom: math.div($condensed-gutter, 2); + padding-top: $condensed-gutter * 0.5; + padding-bottom: $condensed-gutter * 0.5; } @include carbon--make-grid-columns($breakpoints, $grid-gutter); diff --git a/packages/grid/scss/modules/_css-grid.scss b/packages/grid/scss/modules/_css-grid.scss index 0362b2a8876c..e5e09efe10e2 100644 --- a/packages/grid/scss/modules/_css-grid.scss +++ b/packages/grid/scss/modules/_css-grid.scss @@ -5,6 +5,7 @@ // LICENSE file in the root directory of this source tree. // +@use 'sass:meta'; @use "sass:math"; @use 'sass:map'; @@ -405,7 +406,11 @@ $carbon--aspect-ratios: ( $height: nth($aspect-ratio, 2); .#{$prefix}--aspect-ratio--#{$width}x#{$height}::before { - padding-top: percentage(math.div($height, $width)); + @if meta.function-exists('div', 'math') { + padding-top: percentage(math.div($height, $width)); + } @else { + padding-top: percentage(($height / $width)); + } } } } diff --git a/packages/grid/scss/modules/_mixins.scss b/packages/grid/scss/modules/_mixins.scss index 4561626a0cd3..08706d68a3ad 100644 --- a/packages/grid/scss/modules/_mixins.scss +++ b/packages/grid/scss/modules/_mixins.scss @@ -5,6 +5,7 @@ // LICENSE file in the root directory of this source tree. // +@use 'sass:meta'; @use "sass:math"; @use 'config' as *; @@ -63,8 +64,13 @@ // 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(math.div($span, $columns)); - flex: 0 0 percentage(math.div($span, $columns)); + @if meta.function-exists('div', 'math') { + max-width: percentage(math.div($span, $columns)); + flex: 0 0 percentage(math.div($span, $columns)); + } @else { + max-width: percentage(($span / $columns)); + flex: 0 0 percentage(($span / $columns)); + } } } @@ -74,7 +80,12 @@ /// @access private /// @group @carbon/grid @mixin -make-col-offset($span, $columns) { - $offset: math.div($span, $columns); + $offset: 0; + @if meta.function-exists('div', 'math') { + $offset: math.div($span, $columns); + } @else { + $offset: ($span / $columns); + } @if $offset == 0 { margin-left: 0; } @else { diff --git a/packages/layout/scss/_convert.import.scss b/packages/layout/scss/_convert.import.scss index 19517d19fbe0..f8cab364b5f3 100644 --- a/packages/layout/scss/_convert.import.scss +++ b/packages/layout/scss/_convert.import.scss @@ -19,6 +19,7 @@ // compatibility file to ensure we continue to support node-sass and dart-sass // in v10. +@use 'sass:meta'; @use 'sass:math'; /// Default font size @@ -38,7 +39,11 @@ $carbon--base-font-size: 16px !default; @warn "Expected argument $px to be of type `px`, instead received: `#{unit($px)}`"; } - @return math.div($px, $carbon--base-font-size) * 1rem; + @if meta.function-exists('div', 'math') { + @return math.div($px, $carbon--base-font-size) * 1rem; + } @else { + @return ($px / $carbon--base-font-size) * 1rem; + } } /// Convert a given px unit to a em unit @@ -52,5 +57,9 @@ $carbon--base-font-size: 16px !default; @warn "Expected argument $px to be of type `px`, instead received: `#{unit($px)}`"; } - @return math.div($px, $carbon--base-font-size) * 1em; + @if meta.function-exists('div', 'math') { + @return math.div($px, $carbon--base-font-size) * 1em; + } @else { + @return ($px / $carbon--base-font-size) * 1em; + } } diff --git a/packages/layout/scss/_key-height.import.scss b/packages/layout/scss/_key-height.import.scss index 0ebab92a256d..15e9f7090f33 100644 --- a/packages/layout/scss/_key-height.import.scss +++ b/packages/layout/scss/_key-height.import.scss @@ -19,6 +19,7 @@ // compatibility file to ensure we continue to support node-sass and dart-sass // in v10. +@use 'sass:meta'; @use "sass:math"; @import 'breakpoint'; /* stylelint-disable-line no-invalid-position-at-import-rule */ @import 'utilities'; /* stylelint-disable-line no-invalid-position-at-import-rule */ @@ -39,7 +40,11 @@ $margin: map-get($values, margin); $columns: map-get($values, columns); - @return math.div($width - (2 * $margin), $columns); + @if meta.function-exists('div', 'math') { + @return math.div($width - (2 * $margin), $columns); + } @else { + @return (($width - (2 * $margin)) / $columns); + } } @else { @warn 'Breakpoint: `#{$breakpoint}` is not a valid breakpoint.'; } diff --git a/packages/layout/scss/modules/_convert.scss b/packages/layout/scss/modules/_convert.scss index c159d9e03984..3b28c4f09127 100644 --- a/packages/layout/scss/modules/_convert.scss +++ b/packages/layout/scss/modules/_convert.scss @@ -5,6 +5,7 @@ // LICENSE file in the root directory of this source tree. // +@use 'sass:meta'; @use 'sass:math'; /// Default font size @@ -24,7 +25,11 @@ $base-font-size: 16px !default; @warn "Expected argument $px to be of type `px`, instead received: `#{unit($px)}`"; } - @return math.div($px, $base-font-size) * 1rem; + @if meta.function-exists('div', 'math') { + @return math.div($px, $base-font-size) * 1rem; + } @else { + @return ($px / $base-font-size) * 1rem; + } } /// Convert a given px unit to a em unit @@ -38,5 +43,9 @@ $base-font-size: 16px !default; @warn "Expected argument $px to be of type `px`, instead received: `#{unit($px)}`"; } - @return math.div($px, $base-font-size) * 1em; + @if meta.function-exists('div', 'math') { + @return math.div($px, $base-font-size) * 1em; + } @else { + @return ($px / $base-font-size) * 1em; + } } diff --git a/packages/styles/scss/utilities/_convert.scss b/packages/styles/scss/utilities/_convert.scss index e20bf087305f..58fb831d1777 100644 --- a/packages/styles/scss/utilities/_convert.scss +++ b/packages/styles/scss/utilities/_convert.scss @@ -5,11 +5,12 @@ // LICENSE file in the root directory of this source tree. // +@use 'sass:meta'; +@use "sass:math"; + /// Default font size /// @type Number /// @access public -@use "sass:math"; - $base-font-size: 16px !default; /// Convert a given px unit to a rem unit @@ -23,7 +24,11 @@ $base-font-size: 16px !default; @warn "Expected argument $px to be of type `px`, instead received: `#{unit($px)}`"; } - @return math.div($px, $base-font-size) * 1rem; + @if meta.function-exists('div', 'math') { + @return math.div($px, $base-font-size) * 1rem; + } @else { + @return ($px / $base-font-size) * 1rem; + } } /// Convert a given px unit to a em unit @@ -37,5 +42,9 @@ $base-font-size: 16px !default; @warn "Expected argument $px to be of type `px`, instead received: `#{unit($px)}`"; } - @return math.div($px, $base-font-size) * 1em; + @if meta.function-exists('div', 'math') { + @return math.div($px, $base-font-size) * 1em; + } @else { + @return ($px / $base-font-size) * 1em; + } } diff --git a/packages/type/scss/_styles.import.scss b/packages/type/scss/_styles.import.scss index 360053250589..51b105afd082 100644 --- a/packages/type/scss/_styles.import.scss +++ b/packages/type/scss/_styles.import.scss @@ -19,6 +19,7 @@ // compatibility file to ensure we continue to support node-sass and dart-sass // in v10. +@use "sass:meta"; @use "sass:math"; @import '@carbon/layout/scss/breakpoint'; /* stylelint-disable-line no-invalid-position-at-import-rule */ @import 'font-family'; /* stylelint-disable-line no-invalid-position-at-import-rule */ @@ -582,7 +583,11 @@ $tokens: ( /// @access public /// @group @carbon/type @function strip-unit($value) { - @return math.div($value, $value * 0 + 1); + @if meta.function-exists('div', 'math') { + @return math.div($value, $value * 0 + 1); + } @else { + @return $value / ($value * 0 + 1); + } } /// This helper includes fluid type styles for the given token value. Fluid type From 021df4c09cd475aa4d6e808eac4a8368a595f2a5 Mon Sep 17 00:00:00 2001 From: "Andrea N. Cardona" Date: Sun, 17 Oct 2021 19:46:36 -0500 Subject: [PATCH 02/15] fix(progress-indicator): fix active state (#9740) * feat(ContentSwitcher): preliminary unstable refactor * fix(progress-indicator): fix active state * whoops * Delete UnstableContentSwitcher.js * Delete index.js * Delete styles.scss * fix(progress-indicator): fix active state * fix(progress-indicator): fix active state -test * fix(progress-indicator): token fix * fix(reset): commit Co-authored-by: Andrea Cardona --- .../components/progress-indicator/_progress-indicator.scss | 7 ++++--- .../components/progress-indicator/_progress-indicator.scss | 6 ++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/components/src/components/progress-indicator/_progress-indicator.scss b/packages/components/src/components/progress-indicator/_progress-indicator.scss index c991dd835802..8564c19342db 100644 --- a/packages/components/src/components/progress-indicator/_progress-indicator.scss +++ b/packages/components/src/components/progress-indicator/_progress-indicator.scss @@ -102,9 +102,10 @@ margin-right: 0.75rem; } - .#{$prefix}--tooltip__label.#{$prefix}--progress-label:active { - box-shadow: 0 rem(3px) 0 0 $interactive-01; - color: $interactive-01; + .#{$prefix}--progress-step-button:not(.#{$prefix}--progress-step-button--unclickable) + .#{$prefix}--progress-label:active { + box-shadow: 0 rem(3px) 0 0 $interactive; + color: $interactive; } //OVERFLOW STYLING diff --git a/packages/styles/scss/components/progress-indicator/_progress-indicator.scss b/packages/styles/scss/components/progress-indicator/_progress-indicator.scss index 0c406b22f91e..4923b8e452af 100644 --- a/packages/styles/scss/components/progress-indicator/_progress-indicator.scss +++ b/packages/styles/scss/components/progress-indicator/_progress-indicator.scss @@ -225,6 +225,12 @@ $progress-indicator-bar-width: 1px inset transparent !default; cursor: pointer; } + .#{$prefix}--progress-step-button:not(.#{$prefix}--progress-step-button--unclickable) + .#{$prefix}--progress-label:active { + box-shadow: 0 rem(3px) 0 0 $interactive; + color: $interactive; + } + //DISABLED STYLING .#{$prefix}--progress-step--disabled { cursor: not-allowed; From b677f5425222c345f439007348a6583591854682 Mon Sep 17 00:00:00 2001 From: Alessandra Davila Date: Mon, 18 Oct 2021 09:30:59 -0500 Subject: [PATCH 03/15] feat(carbon-react): add layer stories (#9861) --- .../CodeSnippet/CodeSnippet.stories.js | 148 ++++++++++++++++++ .../components/ComboBox/ComboBox.stories.js | 37 +++++ .../ContentSwitcher.stories.js | 27 ++++ .../DatePicker/DatePicker.stories.js | 112 +++++++++++++ .../components/Dropdown/Dropdown.stories.js | 67 ++++++++ .../MultiSelect/MultiSelect.stories.js | 77 +++++++++ .../NumberInput/NumberInput.stories.js | 15 ++ .../Overflow/OverflowMenu.stories.js | 33 ++++ .../src/components/Search/Search.stories.js | 74 +++++++++ .../src/components/Slider/Slider.stories.js | 87 ++++++++++ .../src/components/Tabs/Tabs.stories.js | 75 +++++++++ 11 files changed, 752 insertions(+) diff --git a/packages/carbon-react/src/components/CodeSnippet/CodeSnippet.stories.js b/packages/carbon-react/src/components/CodeSnippet/CodeSnippet.stories.js index 864b1f06ac02..8b6a05b3f7ae 100644 --- a/packages/carbon-react/src/components/CodeSnippet/CodeSnippet.stories.js +++ b/packages/carbon-react/src/components/CodeSnippet/CodeSnippet.stories.js @@ -7,6 +7,7 @@ import React from 'react'; import { CodeSnippet, CodeSnippetSkeleton } from 'carbon-components-react'; +import { Layer } from '../Layer'; export default { title: 'Components/CodeSnippet', @@ -60,6 +61,153 @@ export const singleline = () => ( ); +export const inlineWithLayer = () => { + return ( + <> + + {'node -v'} + + + + {'node -v'} + + + + {'node -v'} + + + + + ); +}; + +export const multilineWithLayer = () => { + return ( + <> + + {` "scripts": { + "build": "lerna run build --stream --prefix --npm-client yarn", + "ci-check": "carbon-cli ci-check", + "clean": "lerna run clean && lerna clean --yes && rimraf node_modules", + "doctoc": "doctoc --title '## Table of Contents'", + "format": "prettier --write '**/*.{js,md,scss,ts}' '!**/{build,es,lib,storybook,ts,umd}/**'", + "format:diff": "prettier --list-different '**/*.{js,md,scss,ts}' '!**/{build,es,lib,storybook,ts,umd}/**' '!packages/components/**'", + "lint": "eslint actions config codemods packages", + "lint:styles": "stylelint '**/*.{css,scss}' --report-needless-disables --report-invalid-scope-disables", + "sync": "carbon-cli sync", + "test": "cross-env BABEL_ENV=test jest", + "test:e2e": "cross-env BABEL_ENV=test jest --testPathPattern=e2e --testPathIgnorePatterns='examples,/packages/components/,/packages/react/'" + }, + "resolutions": { + "react": "~16.9.0", + "react-dom": "~16.9.0", + "react-is": "~16.9.0", + "react-test-renderer": "~16.9.0" + }, + "devDependencies": { + "@babel/core": "^7.10.0", + "@babel/plugin-proposal-class-properties": "^7.7.4", + "@babel/plugin-proposal-export-default-from": "^7.7.4", + "@babel/plugin-proposal-export-namespace-from": "^7.7.4", + "@babel/plugin-transform-runtime": "^7.10.0", + "@babel/preset-env": "^7.10.0", + "@babel/preset-react": "^7.10.0", + "@babel/runtime": "^7.10.0", + "@commitlint/cli": "^8.3.5",`} + + + + {` "scripts": { + "build": "lerna run build --stream --prefix --npm-client yarn", + "ci-check": "carbon-cli ci-check", + "clean": "lerna run clean && lerna clean --yes && rimraf node_modules", + "doctoc": "doctoc --title '## Table of Contents'", + "format": "prettier --write '**/*.{js,md,scss,ts}' '!**/{build,es,lib,storybook,ts,umd}/**'", + "format:diff": "prettier --list-different '**/*.{js,md,scss,ts}' '!**/{build,es,lib,storybook,ts,umd}/**' '!packages/components/**'", + "lint": "eslint actions config codemods packages", + "lint:styles": "stylelint '**/*.{css,scss}' --report-needless-disables --report-invalid-scope-disables", + "sync": "carbon-cli sync", + "test": "cross-env BABEL_ENV=test jest", + "test:e2e": "cross-env BABEL_ENV=test jest --testPathPattern=e2e --testPathIgnorePatterns='examples,/packages/components/,/packages/react/'" + }, + "resolutions": { + "react": "~16.9.0", + "react-dom": "~16.9.0", + "react-is": "~16.9.0", + "react-test-renderer": "~16.9.0" + }, + "devDependencies": { + "@babel/core": "^7.10.0", + "@babel/plugin-proposal-class-properties": "^7.7.4", + "@babel/plugin-proposal-export-default-from": "^7.7.4", + "@babel/plugin-proposal-export-namespace-from": "^7.7.4", + "@babel/plugin-transform-runtime": "^7.10.0", + "@babel/preset-env": "^7.10.0", + "@babel/preset-react": "^7.10.0", + "@babel/runtime": "^7.10.0", + "@commitlint/cli": "^8.3.5",`} + + + + {` "scripts": { + "build": "lerna run build --stream --prefix --npm-client yarn", + "ci-check": "carbon-cli ci-check", + "clean": "lerna run clean && lerna clean --yes && rimraf node_modules", + "doctoc": "doctoc --title '## Table of Contents'", + "format": "prettier --write '**/*.{js,md,scss,ts}' '!**/{build,es,lib,storybook,ts,umd}/**'", + "format:diff": "prettier --list-different '**/*.{js,md,scss,ts}' '!**/{build,es,lib,storybook,ts,umd}/**' '!packages/components/**'", + "lint": "eslint actions config codemods packages", + "lint:styles": "stylelint '**/*.{css,scss}' --report-needless-disables --report-invalid-scope-disables", + "sync": "carbon-cli sync", + "test": "cross-env BABEL_ENV=test jest", + "test:e2e": "cross-env BABEL_ENV=test jest --testPathPattern=e2e --testPathIgnorePatterns='examples,/packages/components/,/packages/react/'" + }, + "resolutions": { + "react": "~16.9.0", + "react-dom": "~16.9.0", + "react-is": "~16.9.0", + "react-test-renderer": "~16.9.0" + }, + "devDependencies": { + "@babel/core": "^7.10.0", + "@babel/plugin-proposal-class-properties": "^7.7.4", + "@babel/plugin-proposal-export-default-from": "^7.7.4", + "@babel/plugin-proposal-export-namespace-from": "^7.7.4", + "@babel/plugin-transform-runtime": "^7.10.0", + "@babel/preset-env": "^7.10.0", + "@babel/preset-react": "^7.10.0", + "@babel/runtime": "^7.10.0", + "@commitlint/cli": "^8.3.5",`} + + + + + ); +}; + +export const singlelineWithLayer = () => { + return ( + <> + + yarn add carbon-components@latest carbon-components-react@latest + @carbon/icons-react@latest carbon-icons@latest + + + + yarn add carbon-components@latest carbon-components-react@latest + @carbon/icons-react@latest carbon-icons@latest + + + + yarn add carbon-components@latest carbon-components-react@latest + @carbon/icons-react@latest carbon-icons@latest + + + + + ); +}; + export const skeleton = () => (
diff --git a/packages/carbon-react/src/components/ComboBox/ComboBox.stories.js b/packages/carbon-react/src/components/ComboBox/ComboBox.stories.js index 0b997e2db9d7..5203768c6986 100644 --- a/packages/carbon-react/src/components/ComboBox/ComboBox.stories.js +++ b/packages/carbon-react/src/components/ComboBox/ComboBox.stories.js @@ -7,6 +7,7 @@ import React from 'react'; import { ComboBox } from 'carbon-components-react'; +import { Layer } from '../Layer'; const items = [ { @@ -54,3 +55,39 @@ export const Combobox = () => ( />
); + +export const withLayer = () => ( +
+ {}} + id="carbon-combobox" + items={items} + itemToString={(item) => (item ? item.text : '')} + placeholder="Filter..." + titleText="First Layer" + helperText="Combobox helper text" + /> + + {}} + id="carbon-combobox" + items={items} + itemToString={(item) => (item ? item.text : '')} + placeholder="Filter..." + titleText="Second Layer" + helperText="Combobox helper text" + /> + + {}} + id="carbon-combobox" + items={items} + itemToString={(item) => (item ? item.text : '')} + placeholder="Filter..." + titleText="Third Layer" + helperText="Combobox helper text" + /> + + +
+); diff --git a/packages/carbon-react/src/components/ContentSwitcher/ContentSwitcher.stories.js b/packages/carbon-react/src/components/ContentSwitcher/ContentSwitcher.stories.js index efdeef12bb1b..82daf616a49a 100644 --- a/packages/carbon-react/src/components/ContentSwitcher/ContentSwitcher.stories.js +++ b/packages/carbon-react/src/components/ContentSwitcher/ContentSwitcher.stories.js @@ -7,6 +7,7 @@ import React from 'react'; import { ContentSwitcher, Switch } from 'carbon-components-react'; +import { Layer } from '../Layer'; export default { title: 'Components/ContentSwitcher', @@ -27,3 +28,29 @@ export const Default = () => ( ); + +export const withLayer = () => { + return ( + <> + {}}> + + + + + + {}}> + + + + + + {}}> + + + + + + + + ); +}; diff --git a/packages/carbon-react/src/components/DatePicker/DatePicker.stories.js b/packages/carbon-react/src/components/DatePicker/DatePicker.stories.js index c82738966093..bfb80349c536 100644 --- a/packages/carbon-react/src/components/DatePicker/DatePicker.stories.js +++ b/packages/carbon-react/src/components/DatePicker/DatePicker.stories.js @@ -12,6 +12,7 @@ import { DatePickerInput, DatePickerSkeleton, } from 'carbon-components-react'; +import { Layer } from '../Layer'; // const patterns = { // 'Short (d{1,2}/d{4})': '\\d{1,2}/\\d{4}', @@ -108,6 +109,117 @@ export const RangeWithCalendar = () => { ); }; +export const SimpleWithLayer = () => { + return ( + <> + + + + + + + + + + + + + + + ); +}; + +export const SingleWithCalendarWithLayer = () => { + return ( + <> + + + + + + + + + + + + + + + ); +}; + +export const RangeWithCalendarWithLayer = () => { + return ( + <> + + + + + + + + + + + + + + + + + + ); +}; + /* eslint-disable react/prop-types */ export const DatePickerPlayground = () => ( diff --git a/packages/carbon-react/src/components/Dropdown/Dropdown.stories.js b/packages/carbon-react/src/components/Dropdown/Dropdown.stories.js index 06fb5251c320..92ae3ab55f0d 100644 --- a/packages/carbon-react/src/components/Dropdown/Dropdown.stories.js +++ b/packages/carbon-react/src/components/Dropdown/Dropdown.stories.js @@ -7,6 +7,7 @@ import React from 'react'; import { Dropdown, DropdownSkeleton } from 'carbon-components-react'; +import { Layer } from '../Layer'; const items = [ { @@ -73,6 +74,72 @@ export const Inline = () => ( ); +export const withLayer = () => ( +
+ (item ? item.text : '')} + /> + + (item ? item.text : '')} + /> + + (item ? item.text : '')} + /> + + +
+); + +export const InlineWithLayer = () => ( +
+ (item ? item.text : '')} + /> + + (item ? item.text : '')} + /> + + (item ? item.text : '')} + /> + + +
+); + export const Skeleton = () => (
diff --git a/packages/carbon-react/src/components/MultiSelect/MultiSelect.stories.js b/packages/carbon-react/src/components/MultiSelect/MultiSelect.stories.js index 70b0afc23cb2..ee8df2d982fd 100644 --- a/packages/carbon-react/src/components/MultiSelect/MultiSelect.stories.js +++ b/packages/carbon-react/src/components/MultiSelect/MultiSelect.stories.js @@ -7,6 +7,7 @@ import React from 'react'; import { MultiSelect } from 'carbon-components-react'; +import { Layer } from '../Layer'; const items = [ { @@ -94,3 +95,79 @@ export const _Filterable = () => {
); }; + +export const withLayer = () => { + return ( +
+ (item ? item.text : '')} + selectionFeedback="top-after-reopen" + /> + + (item ? item.text : '')} + selectionFeedback="top-after-reopen" + /> + + (item ? item.text : '')} + selectionFeedback="top-after-reopen" + /> + + +
+ ); +}; + +export const _FilterableWithLayer = () => { + return ( +
+ (item ? item.text : '')} + placeholder="Filter" + selectionFeedback="top-after-reopen" + /> + + (item ? item.text : '')} + placeholder="Filter" + selectionFeedback="top-after-reopen" + /> + + (item ? item.text : '')} + placeholder="Filter" + selectionFeedback="top-after-reopen" + /> + + +
+ ); +}; diff --git a/packages/carbon-react/src/components/NumberInput/NumberInput.stories.js b/packages/carbon-react/src/components/NumberInput/NumberInput.stories.js index b403c8622861..8109f350e78a 100644 --- a/packages/carbon-react/src/components/NumberInput/NumberInput.stories.js +++ b/packages/carbon-react/src/components/NumberInput/NumberInput.stories.js @@ -7,6 +7,7 @@ import React from 'react'; import { NumberInput, NumberInputSkeleton } from 'carbon-components-react'; +import { Layer } from '../Layer'; export default { title: 'Components/NumberInput', @@ -33,6 +34,20 @@ export const Default = () => { return ; }; +export const withLayer = () => { + return ( + <> + + + + + + + + + ); +}; + export const Skeleton = () => (
diff --git a/packages/carbon-react/src/components/Overflow/OverflowMenu.stories.js b/packages/carbon-react/src/components/Overflow/OverflowMenu.stories.js index 53d22796348d..b0b46cbf9538 100644 --- a/packages/carbon-react/src/components/Overflow/OverflowMenu.stories.js +++ b/packages/carbon-react/src/components/Overflow/OverflowMenu.stories.js @@ -7,6 +7,7 @@ import { OverflowMenu, OverflowMenuItem } from 'carbon-components-react'; import React from 'react'; +import { Layer } from '../Layer'; export default { title: 'Components/OverflowMenu', @@ -23,3 +24,35 @@ export const Default = () => { ); }; + +export const withLayer = () => { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/packages/carbon-react/src/components/Search/Search.stories.js b/packages/carbon-react/src/components/Search/Search.stories.js index aca667e6aa2e..a99ab03d57d0 100644 --- a/packages/carbon-react/src/components/Search/Search.stories.js +++ b/packages/carbon-react/src/components/Search/Search.stories.js @@ -7,6 +7,7 @@ import { Search, ExpandableSearch } from 'carbon-components-react'; import React from 'react'; +import { Layer } from '../Layer'; export default { title: 'Components/Search' }; @@ -32,3 +33,76 @@ export const Expandable = () => ( onKeyDown={() => {}} /> ); + +export const withLayer = () => { + return ( + <> + {}} + onKeyDown={() => {}} + /> + + {}} + onKeyDown={() => {}} + /> + + {}} + onKeyDown={() => {}} + /> + + + + ); +}; + +export const ExpandableWithLayer = () => { + return ( + <> + {}} + onKeyDown={() => {}} + /> + + {}} + onKeyDown={() => {}} + /> + + {}} + onKeyDown={() => {}} + /> + + + + ); +}; diff --git a/packages/carbon-react/src/components/Slider/Slider.stories.js b/packages/carbon-react/src/components/Slider/Slider.stories.js index b968c3d39bc5..802a63d55843 100644 --- a/packages/carbon-react/src/components/Slider/Slider.stories.js +++ b/packages/carbon-react/src/components/Slider/Slider.stories.js @@ -11,6 +11,7 @@ import React, { useState } from 'react'; // import { withKnobs, boolean, number, text } from '@storybook/addon-knobs'; import { Slider, SliderSkeleton } from '.'; // import { sliderValuePropSync } from '../../../../react/src/internal/FeatureFlags'; +import { Layer } from '../Layer'; import mdx from './Slider.mdx'; export default { @@ -63,4 +64,90 @@ export const ControlledSlider = () => { ); }; +export const withLayer = () => { + return ( + <> + + + + + + + + + ); +}; + +export const ControlledSliderWithLayer = () => { + const [val, setVal] = useState(87); + return ( + <> + + setVal(value)} + /> +

{val}

+ + + setVal(value)} + /> +

{val}

+ + + setVal(value)} + /> +

{val}

+
+
+ + ); +}; + export const Skeleton = () => ; diff --git a/packages/carbon-react/src/components/Tabs/Tabs.stories.js b/packages/carbon-react/src/components/Tabs/Tabs.stories.js index 08482fdb9108..1c04f224b089 100644 --- a/packages/carbon-react/src/components/Tabs/Tabs.stories.js +++ b/packages/carbon-react/src/components/Tabs/Tabs.stories.js @@ -7,6 +7,7 @@ import React from 'react'; import { Button, Tab, Tabs, TabsSkeleton } from '../Tabs'; +import { Layer } from '../Layer'; export default { title: 'Components/Tabs', @@ -42,3 +43,77 @@ export const Default = () => ( ); + +export const withLayer = () => { + return ( + <> + + +

First Layer. Content for first tab goes here.

+
+ +

Content for second tab goes here.

+ +
+ +

Content for third tab goes here.

+
+ +

Content for fourth tab goes here.

+
+ Custom Label
}> +

Content for fifth tab goes here.

+ + + + + +

Second Layer. Content for first tab goes here.

+
+ +

Content for second tab goes here.

+ +
+ +

Content for third tab goes here.

+
+ +

Content for fourth tab goes here.

+
+ Custom Label}> +

Content for fifth tab goes here.

+
+
+ + + +

Third Layer. Content for first tab goes here.

+
+ +

Content for second tab goes here.

+ +
+ +

Content for third tab goes here.

+
+ +

Content for fourth tab goes here.

+
+ Custom Label}> +

Content for fifth tab goes here.

+
+
+
+
+ + ); +}; From 6941df6b9d6007131e47c53d52fef427d4f98bfc Mon Sep 17 00:00:00 2001 From: Darsh Shah Date: Mon, 18 Oct 2021 21:38:47 +0530 Subject: [PATCH 04/15] chore: remove husky scripts from package.json (#9881) Co-authored-by: Abbey Hart --- package.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/package.json b/package.json index ee927a03ef52..2b3c358a6563 100644 --- a/package.json +++ b/package.json @@ -71,12 +71,6 @@ "rimraf": "^3.0.0", "stylelint": "^13.13.1" }, - "husky": { - "hooks": { - "commit-msg": "commitlint -e $HUSKY_GIT_PARAMS", - "pre-commit": "lint-staged" - } - }, "commitlint": { "extends": [ "@commitlint/config-conventional" From 3d06011c150ebe33a1914d828ea567eee09f37e0 Mon Sep 17 00:00:00 2001 From: Josefina Mancilla <32556167+jnm2377@users.noreply.github.com> Date: Mon, 18 Oct 2021 12:16:09 -0500 Subject: [PATCH 05/15] fix(screenshot): make textarea (#9887) --- .github/ISSUE_TEMPLATE/DESIGN_DEFECT.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/DESIGN_DEFECT.yaml b/.github/ISSUE_TEMPLATE/DESIGN_DEFECT.yaml index 804f5e773cef..a4065d5d4723 100644 --- a/.github/ISSUE_TEMPLATE/DESIGN_DEFECT.yaml +++ b/.github/ISSUE_TEMPLATE/DESIGN_DEFECT.yaml @@ -62,7 +62,7 @@ body: placeholder: What did you see? What did you expect to see? validations: required: true - - type: input + - type: textarea id: example-url attributes: label: Screenshots From 4165cc4b1c9146ecdd173d2dfbe421f62aeb4a04 Mon Sep 17 00:00:00 2001 From: Taylor Jones Date: Mon, 18 Oct 2021 14:50:46 -0500 Subject: [PATCH 06/15] fix(tooltip): prevent escape keydown from bubbling (#9875) * fix(tooltip): prevent escape keydown from bubbling * Update packages/react/src/components/Tooltip/Tooltip.js Co-authored-by: Scott Strubberg * chore: remove story used for testing Co-authored-by: Scott Strubberg Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../src/components/Tooltip/Tooltip-test.js | 29 ++++++++++++++++--- .../react/src/components/Tooltip/Tooltip.js | 8 +++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/packages/react/src/components/Tooltip/Tooltip-test.js b/packages/react/src/components/Tooltip/Tooltip-test.js index 08d2fab9615b..72ddbc00e9a9 100644 --- a/packages/react/src/components/Tooltip/Tooltip-test.js +++ b/packages/react/src/components/Tooltip/Tooltip-test.js @@ -6,22 +6,26 @@ */ import React, { Component } from 'react'; -import debounce from 'lodash.debounce'; +import debounce from 'lodash.debounce'; // eslint-disable-line no-unused-vars import FloatingMenu from '../../internal/FloatingMenu'; import Tooltip from '../Tooltip'; import { mount } from 'enzyme'; +import { screen, render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { Information16 as Information, Add16 as Add, OverflowMenuVertical16, } from '@carbon/icons-react'; import { settings } from 'carbon-components'; +import '@testing-library/jest-dom'; const { prefix } = settings; -jest.mock('lodash.debounce'); - -debounce.mockImplementation((fn) => fn); +jest.mock('lodash.debounce', () => (fn) => { + fn.cancel = jest.fn(); + return fn; +}); describe('Tooltip', () => { // An icon component class @@ -191,4 +195,21 @@ describe('Tooltip', () => { expect(rootWrapper.find('Tooltip').instance().state.open).toEqual(false); }); }); + + it('escape key keyDown should not bubble outside the tooltip', () => { + const onKeyDown = jest.fn(); + render( + <> + {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */} +
+ +
+ + ); + + userEvent.click(screen.getAllByRole('button')[0]); + userEvent.keyboard('{esc}'); + + expect(onKeyDown).not.toHaveBeenCalled(); + }); }); diff --git a/packages/react/src/components/Tooltip/Tooltip.js b/packages/react/src/components/Tooltip/Tooltip.js index 0ec8ba2924d5..27dc2d65613f 100644 --- a/packages/react/src/components/Tooltip/Tooltip.js +++ b/packages/react/src/components/Tooltip/Tooltip.js @@ -703,8 +703,16 @@ class Tooltip extends Component { this._tooltipEl = node; }} updateOrientation={this.updateOrientation}> + {/* This rule is disabled because the onKeyDown event handler is only + * being used to capture and prevent the event from bubbling: */} + {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
{ + if (keyDownMatch(event, [keys.Escape])) { + event.stopPropagation(); + } + }} {...other} id={this._tooltipId} data-floating-menu-direction={storedDirection} From b5487bc40aaeefefcd0a88ef8bcbe71d44a35b0e Mon Sep 17 00:00:00 2001 From: Josh Black Date: Tue, 19 Oct 2021 09:46:26 -0500 Subject: [PATCH 07/15] feat(styles): add default-type export to _type.scss entrypoint (#9891) --- packages/styles/scss/__tests__/type-test.js | 4 ++++ packages/styles/scss/_type.scss | 1 + 2 files changed, 5 insertions(+) diff --git a/packages/styles/scss/__tests__/type-test.js b/packages/styles/scss/__tests__/type-test.js index 7aad4e33663f..033f99697816 100644 --- a/packages/styles/scss/__tests__/type-test.js +++ b/packages/styles/scss/__tests__/type-test.js @@ -25,6 +25,8 @@ describe('@carbon/styles/scss/type', () => { mixins: ( reset: meta.mixin-exists('reset', 'type'), type-style: meta.mixin-exists('type-style', 'type'), + font-family: meta.mixin-exists('font-family', 'type'), + default-type: meta.mixin-exists('default-type', 'type'), ), )); `); @@ -33,6 +35,8 @@ describe('@carbon/styles/scss/type', () => { expect(api.mixins).toEqual({ reset: true, 'type-style': true, + 'font-family': true, + 'default-type': true, }); expect(api.variables).toMatchInlineSnapshot(` Array [ diff --git a/packages/styles/scss/_type.scss b/packages/styles/scss/_type.scss index cd76bbf2811a..4e4245a28e65 100644 --- a/packages/styles/scss/_type.scss +++ b/packages/styles/scss/_type.scss @@ -11,6 +11,7 @@ reset, type-style, font-family, + default-type, // Variables $caption-01, From ac2c448e9c0905c6f4113ffaf37863b43093d2c6 Mon Sep 17 00:00:00 2001 From: Josh Black Date: Tue, 19 Oct 2021 12:24:18 -0500 Subject: [PATCH 08/15] chore(themes): fix v11 token preview g100 color names (#9890) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/themes/examples/preview-v11/src/pages/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/themes/examples/preview-v11/src/pages/index.js b/packages/themes/examples/preview-v11/src/pages/index.js index 1644e8bc5c38..3b0c679e6031 100644 --- a/packages/themes/examples/preview-v11/src/pages/index.js +++ b/packages/themes/examples/preview-v11/src/pages/index.js @@ -277,7 +277,7 @@ export default function IndexPage() { />
- {getColorByValue(themes.g90[exportName], 'gray')} + {getColorByValue(themes.g100[exportName], 'gray')} {themes.g100[exportName]} From 727691155c4f9e5dc3c56976f5316dd8ff7d1550 Mon Sep 17 00:00:00 2001 From: Josefina Mancilla <32556167+jnm2377@users.noreply.github.com> Date: Tue, 19 Oct 2021 13:45:55 -0500 Subject: [PATCH 09/15] feat(Tab): make tab functional component (#9722) * feat(Tab): make tab functional component * feat(Tabs): convert to functional * fix: remove console.logs * fix: export components as default * fix: tabs state and refs * fix: use prefix * fix: add feature flag v11 story * fix: temp use v10 classNames * fix: clean up, comment, and fix select * fix: keyboard navigation * fix: remove console log * chore: tabs comment * feat: add tab tests * feat: add tabs tests * fix: add back light * fix: remove v11 styles * Update packages/react/src/components/Tabs/index.js Co-authored-by: Taylor Jones * fix: next tab test and deprecation * fix: tabs deprecate unused props * fix: deprecations' * fix: tab role presentation test * fix: remove unused arg' Co-authored-by: Taylor Jones Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../src/components/Tabs/Tabs.stories.js | 8 + .../__snapshots__/PublicAPI-test.js.snap | 6 +- packages/react/src/components/Tab/Tab-test.js | 2 +- packages/react/src/components/Tab/Tab.js | 4 +- packages/react/src/components/Tab/index.js | 8 +- .../react/src/components/Tab/next/Tab-test.js | 204 ++++++ packages/react/src/components/Tab/next/Tab.js | 166 +++++ packages/react/src/components/Tabs/index.js | 11 +- .../src/components/Tabs/next/Tabs-test.js | 264 ++++++++ .../react/src/components/Tabs/next/Tabs.js | 613 ++++++++++++++++++ 10 files changed, 1276 insertions(+), 10 deletions(-) create mode 100644 packages/react/src/components/Tab/next/Tab-test.js create mode 100644 packages/react/src/components/Tab/next/Tab.js create mode 100644 packages/react/src/components/Tabs/next/Tabs-test.js create mode 100644 packages/react/src/components/Tabs/next/Tabs.js diff --git a/packages/carbon-react/src/components/Tabs/Tabs.stories.js b/packages/carbon-react/src/components/Tabs/Tabs.stories.js index 1c04f224b089..4e4741d3288f 100644 --- a/packages/carbon-react/src/components/Tabs/Tabs.stories.js +++ b/packages/carbon-react/src/components/Tabs/Tabs.stories.js @@ -7,10 +7,18 @@ import React from 'react'; import { Button, Tab, Tabs, TabsSkeleton } from '../Tabs'; +import { unstable_FeatureFlags as FeatureFlags } from 'carbon-components-react'; import { Layer } from '../Layer'; export default { title: 'Components/Tabs', + decorators: [ + (Story) => ( + + + + ), + ], parameters: { component: Tabs, subcomponents: { diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index 6ac36a38f0a8..6223d424aed7 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -5905,7 +5905,6 @@ Map { "label": "provide a label", "onClick": [Function], "onKeyDown": [Function], - "role": "presentation", "selected": false, }, "propTypes": Object { @@ -5946,10 +5945,7 @@ Map { "renderContent": Object { "type": "func", }, - "role": Object { - "isRequired": true, - "type": "string", - }, + "role": [Function], "selected": Object { "isRequired": true, "type": "bool", diff --git a/packages/react/src/components/Tab/Tab-test.js b/packages/react/src/components/Tab/Tab-test.js index f28a9e157f99..f84b5668a6ac 100644 --- a/packages/react/src/components/Tab/Tab-test.js +++ b/packages/react/src/components/Tab/Tab-test.js @@ -45,7 +45,7 @@ describe('Tab', () => { }); it('renders
  • with [role="presentation"]', () => { - expect(wrapper.props().role).toEqual('presentation'); + expect(wrapper.find('li').prop('role')).toEqual('presentation'); }); it('renders + )} +
  • + ); +}); + +Tab.propTypes = { + /** + * Specify an optional className to be added to your Tab + */ + className: PropTypes.string, + + /** + * Whether your Tab is disabled. + */ + disabled: PropTypes.bool, + + /** + * A handler that is invoked when a user clicks on the control. + * Reserved for usage in Tabs + */ + handleTabClick: PropTypes.func, + + /** + * A handler that is invoked on the key down event for the control. + * Reserved for usage in Tabs + */ + handleTabKeyDown: PropTypes.func, + + /** + * The element ID for the top-level element. + */ + id: PropTypes.string, + + /** + * The index of your Tab in your Tabs. Reserved for usage in Tabs + */ + index: PropTypes.number, + + /** + * Provide the contents of your Tab + */ + label: PropTypes.node, + + /** + * Provide a handler that is invoked when a user clicks on the control + */ + onClick: PropTypes.func, + + /** + * Provide a handler that is invoked on the key down event for the control + */ + onKeyDown: PropTypes.func, + + /* + * An optional parameter to allow overriding the anchor rendering. + * Useful for using Tab along with react-router or other client + * side router libraries. + **/ + renderButton: PropTypes.func, + + /* + * An optional parameter to allow overriding the content rendering. + **/ + renderContent: PropTypes.func, + + /** + * Whether your Tab is selected. + * Reserved for usage in Tabs + */ + selected: PropTypes.bool, + + /** + * Specify the tab index of the ` + {!leftOverflowNavButtonHidden && ( +
    + )} +
      + {tabsWithProps} +
    + {!rightOverflowNavButtonHidden && ( +
    + )} + +
    + {tabContentWithProps} + + ); +}); + +Tabs.propTypes = { + /** + * Pass in a collection of children to be rendered depending on the + * currently selected tab + */ + children: PropTypes.node, + + /** + * Provide a className that is applied to the root
    component for the + * + */ + className: PropTypes.string, + + /** + * Specify whether the Tab content is hidden + */ + hidden: PropTypes.bool, + + /** + * Provide the props that describe the left overflow button + */ + leftOverflowButtonProps: PropTypes.object, + + /** + * Specify whether or not to use the light component variant + */ + light: deprecate( + PropTypes.bool, + 'The light prop has been deprecated in v11 in favor of our new layering model that uses the Layer component' + ), + + /** + * Optionally provide an `onClick` handler that is invoked when a is + * clicked + */ + onClick: PropTypes.func, + + /** + * Optionally provide an `onKeyDown` handler that is invoked when keyed + * navigation is triggered + */ + onKeyDown: PropTypes.func, + + /** + * Provide an optional handler that is called whenever the selection + * changes. This method is called with the index of the tab that was + * selected + */ + onSelectionChange: PropTypes.func, + + /** + * Provide the props that describe the right overflow button + */ + rightOverflowButtonProps: PropTypes.object, + + /** + * Choose whether or not to automatically scroll to newly selected tabs + * on component rerender + */ + scrollIntoView: PropTypes.bool, + + /** + * Optionally provide an index for the currently selected + */ + selected: PropTypes.number, + + /** + * Choose whether or not to automatically change selection on focus + */ + selectionMode: PropTypes.oneOf(['automatic', 'manual']), + + /** + * Provide a className that is applied to the components + */ + tabContentClassName: PropTypes.string, + + /** + * Provide the type of Tab + */ + type: PropTypes.oneOf(['default', 'container']), +}; + +export default Tabs; From 72731190d6bf854b09e3cdb5785799821908970f Mon Sep 17 00:00:00 2001 From: Taylor Jones Date: Tue, 19 Oct 2021 14:19:30 -0500 Subject: [PATCH 10/15] Remove external/outside margin from components (#9830) * fix(form): remove fieldset margin * fix(form): remove fileuploader margin * fix(form): remove label margin * fix(notifications): remove external margin * fix(structured-list): remove external margin * chore: put component margin removal behind flag * chore: add v11 flag env variable to sass compilation config Co-authored-by: Josh Black --- .../file-uploader/_file-uploader.scss | 5 ++++- .../components/src/components/form/_form.scss | 21 +++++++++++++------ .../notification/_inline-notification.scss | 7 +++++-- .../notification/_toast-notification.scss | 15 ++++++++----- .../structured-list/_structured-list.scss | 5 ++++- packages/react/.storybook/main.js | 4 +++- .../src/components/FormGroup/FormGroup.js | 3 ++- .../file-uploader/_file-uploader.scss | 5 ++++- .../styles/scss/components/form/_form.scss | 21 +++++++++++++------ .../_actionable-notification.scss | 7 +++++-- .../notification/_inline-notification.scss | 7 +++++-- .../notification/_toast-notification.scss | 15 ++++++++----- .../structured-list/_structured-list.scss | 5 ++++- 13 files changed, 86 insertions(+), 34 deletions(-) diff --git a/packages/components/src/components/file-uploader/_file-uploader.scss b/packages/components/src/components/file-uploader/_file-uploader.scss index 1d997c4d0600..bb4b63e24c7e 100644 --- a/packages/components/src/components/file-uploader/_file-uploader.scss +++ b/packages/components/src/components/file-uploader/_file-uploader.scss @@ -57,7 +57,10 @@ display: inline-block; width: 100%; max-width: rem(320px); - margin-bottom: $carbon--spacing-03; + @if not feature-flag-enabled('enable-v11-release') { + margin-bottom: $carbon--spacing-03; + } + color: $link-01; cursor: pointer; outline: 2px solid transparent; diff --git a/packages/components/src/components/form/_form.scss b/packages/components/src/components/form/_form.scss index 17715c9e33f8..f00ae8ef4124 100644 --- a/packages/components/src/components/form/_form.scss +++ b/packages/components/src/components/form/_form.scss @@ -18,11 +18,15 @@ .#{$prefix}--fieldset { @include reset; - margin-bottom: $carbon--spacing-07; + @if not feature-flag-enabled('enable-v11-release') { + margin-bottom: $carbon--spacing-07; + } } - .#{$prefix}--fieldset--no-margin { - margin-bottom: 0; + @if not feature-flag-enabled('enable-v11-release') { + .#{$prefix}--fieldset--no-margin { + margin-bottom: 0; + } } .#{$prefix}--form-item { @@ -42,7 +46,10 @@ @include type-style('label-01'); display: inline-block; - margin-bottom: $carbon--spacing-03; + @if not feature-flag-enabled('enable-v11-release') { + margin-bottom: $carbon--spacing-03; + } + color: $text-02; font-weight: $input-label-weight; line-height: 1rem; @@ -125,8 +132,10 @@ display: block; } - .#{$prefix}--form--fluid .#{$prefix}--fieldset { - margin: 0; + @if not feature-flag-enabled('enable-v11-release') { + .#{$prefix}--form--fluid .#{$prefix}--fieldset { + margin: 0; + } } .#{$prefix}--form--fluid input[data-invalid] { diff --git a/packages/components/src/components/notification/_inline-notification.scss b/packages/components/src/components/notification/_inline-notification.scss index 17cbde33b4c4..f58bf988467d 100644 --- a/packages/components/src/components/notification/_inline-notification.scss +++ b/packages/components/src/components/notification/_inline-notification.scss @@ -33,8 +33,11 @@ height: auto; min-height: rem(48px); flex-wrap: wrap; - margin-top: $carbon--spacing-05; - margin-bottom: $carbon--spacing-05; + @if not feature-flag-enabled('enable-v11-release') { + margin-top: $carbon--spacing-05; + margin-bottom: $carbon--spacing-05; + } + color: $inverse-01; @include carbon--breakpoint(md) { diff --git a/packages/components/src/components/notification/_toast-notification.scss b/packages/components/src/components/notification/_toast-notification.scss index 1fb6fdaa305d..2c4cf3d76b02 100644 --- a/packages/components/src/components/notification/_toast-notification.scss +++ b/packages/components/src/components/notification/_toast-notification.scss @@ -29,14 +29,19 @@ width: rem(288px); height: auto; padding-left: $carbon--spacing-05; - margin-top: $carbon--spacing-03; - margin-right: $carbon--spacing-05; - margin-bottom: $carbon--spacing-03; + @if not feature-flag-enabled('enable-v11-release') { + margin-top: $carbon--spacing-03; + margin-right: $carbon--spacing-05; + margin-bottom: $carbon--spacing-03; + } + box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2); color: $inverse-01; - &:first-child { - margin-top: $carbon--spacing-05; + @if not feature-flag-enabled('enable-v11-release') { + &:first-child { + margin-top: $carbon--spacing-05; + } } @include carbon--breakpoint(max) { diff --git a/packages/components/src/components/structured-list/_structured-list.scss b/packages/components/src/components/structured-list/_structured-list.scss index f07bf8b9ed23..a19bbcbf7dae 100644 --- a/packages/components/src/components/structured-list/_structured-list.scss +++ b/packages/components/src/components/structured-list/_structured-list.scss @@ -32,7 +32,10 @@ display: table; width: 100%; - margin-bottom: 5rem; + @if not feature-flag-enabled('enable-v11-release') { + margin-bottom: 5rem; + } + background-color: transparent; border-collapse: collapse; border-spacing: 0; diff --git a/packages/react/.storybook/main.js b/packages/react/.storybook/main.js index 4d9fa461553e..41be2da8f11c 100644 --- a/packages/react/.storybook/main.js +++ b/packages/react/.storybook/main.js @@ -13,7 +13,7 @@ const customProperties = require('postcss-custom-properties'); const rtlcss = require('rtlcss'); const { - CARBON_ENABLE_V11_RELEASE, + CARBON_ENABLE_V11_RELEASE = 'false', CARBON_REACT_STORYBOOK_USE_CUSTOM_PROPERTIES = 'false', CARBON_REACT_STORYBOOK_USE_RTL, CARBON_REACT_STORYBOOK_USE_SASS_LOADER, @@ -69,6 +69,7 @@ module.exports = { $feature-flags: ( ui-shell: true, enable-css-custom-properties: ${CARBON_REACT_STORYBOOK_USE_CUSTOM_PROPERTIES}, + enable-v11-release: ${CARBON_ENABLE_V11_RELEASE}, ); ${content} `; @@ -88,6 +89,7 @@ module.exports = { $feature-flags: ( ui-shell: true, enable-css-custom-properties: ${CARBON_REACT_STORYBOOK_USE_CUSTOM_PROPERTIES}, + enable-v11-release: ${CARBON_ENABLE_V11_RELEASE}, ); `, implementation: require('sass'), diff --git a/packages/react/src/components/FormGroup/FormGroup.js b/packages/react/src/components/FormGroup/FormGroup.js index f2cd065863d5..d476c4bd4d50 100644 --- a/packages/react/src/components/FormGroup/FormGroup.js +++ b/packages/react/src/components/FormGroup/FormGroup.js @@ -19,7 +19,7 @@ const FormGroup = ({ className, message, messageText, - hasMargin, + hasMargin, // TODO - remove in v11 ...other }) => { const prefix = usePrefix(); @@ -27,6 +27,7 @@ const FormGroup = ({ const classNamesLegend = classnames(`${prefix}--label`, [ enabled ? null : className, ]); + // TODO - remove `fieldset--no-margin` in v11 const classNamesFieldset = classnames(`${prefix}--fieldset`, className, { [`${prefix}--fieldset--no-margin`]: !hasMargin, }); diff --git a/packages/styles/scss/components/file-uploader/_file-uploader.scss b/packages/styles/scss/components/file-uploader/_file-uploader.scss index 1f7a90661459..d093294b83df 100644 --- a/packages/styles/scss/components/file-uploader/_file-uploader.scss +++ b/packages/styles/scss/components/file-uploader/_file-uploader.scss @@ -62,7 +62,10 @@ display: inline-block; width: 100%; max-width: rem(320px); - margin-bottom: $spacing-03; + @if not enabled('enable-v11-release') { + margin-bottom: $spacing-03; + } + color: $link-primary; cursor: pointer; outline: 2px solid transparent; diff --git a/packages/styles/scss/components/form/_form.scss b/packages/styles/scss/components/form/_form.scss index 1db3071bcad7..bee4c969ac82 100644 --- a/packages/styles/scss/components/form/_form.scss +++ b/packages/styles/scss/components/form/_form.scss @@ -22,11 +22,15 @@ $input-label-weight: 400 !default; .#{$prefix}--fieldset { @include reset; - margin-bottom: $spacing-07; + @if not enabled('enable-v11-release') { + margin-bottom: $spacing-07; + } } - .#{$prefix}--fieldset--no-margin { - margin-bottom: 0; + @if not enabled('enable-v11-release') { + .#{$prefix}--fieldset--no-margin { + margin-bottom: 0; + } } .#{$prefix}--form-item { @@ -46,7 +50,10 @@ $input-label-weight: 400 !default; @include type-style('label-01'); display: inline-block; - margin-bottom: $spacing-03; + @if not enabled('enable-v11-release') { + margin-bottom: $spacing-03; + } + color: $text-secondary; font-weight: $input-label-weight; line-height: 1rem; @@ -129,8 +136,10 @@ $input-label-weight: 400 !default; display: block; } - .#{$prefix}--form--fluid .#{$prefix}--fieldset { - margin: 0; + @if not enabled('enable-v11-release') { + .#{$prefix}--form--fluid .#{$prefix}--fieldset { + margin: 0; + } } .#{$prefix}--form--fluid input[data-invalid] { diff --git a/packages/styles/scss/components/notification/_actionable-notification.scss b/packages/styles/scss/components/notification/_actionable-notification.scss index 7984f0bdb9c1..deb8d6e6cb42 100644 --- a/packages/styles/scss/components/notification/_actionable-notification.scss +++ b/packages/styles/scss/components/notification/_actionable-notification.scss @@ -36,8 +36,11 @@ height: auto; min-height: rem(48px); flex-wrap: wrap; - margin-top: $spacing-05; - margin-bottom: $spacing-05; + @if not enabled('enable-v11-release') { + margin-top: $spacing-05; + margin-bottom: $spacing-05; + } + color: $text-inverse; @include breakpoint(md) { diff --git a/packages/styles/scss/components/notification/_inline-notification.scss b/packages/styles/scss/components/notification/_inline-notification.scss index 5f281a2cf556..fe15efe2a1d0 100644 --- a/packages/styles/scss/components/notification/_inline-notification.scss +++ b/packages/styles/scss/components/notification/_inline-notification.scss @@ -34,8 +34,11 @@ height: auto; min-height: rem(48px); flex-wrap: wrap; - margin-top: $spacing-05; - margin-bottom: $spacing-05; + @if not enabled('enable-v11-release') { + margin-top: $spacing-05; + margin-bottom: $spacing-05; + } + color: $text-inverse; @include breakpoint(md) { diff --git a/packages/styles/scss/components/notification/_toast-notification.scss b/packages/styles/scss/components/notification/_toast-notification.scss index 80765bcc3a93..c4e6471ef7e7 100644 --- a/packages/styles/scss/components/notification/_toast-notification.scss +++ b/packages/styles/scss/components/notification/_toast-notification.scss @@ -32,14 +32,19 @@ width: rem(288px); height: auto; padding-left: $spacing-05; - margin-top: $spacing-03; - margin-right: $spacing-05; - margin-bottom: $spacing-03; + @if not enabled('enable-v11-release') { + margin-top: $spacing-03; + margin-right: $spacing-05; + margin-bottom: $spacing-03; + } + box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2); color: $text-inverse; - &:first-child { - margin-top: $spacing-05; + @if not enabled('enable-v11-release') { + &:first-child { + margin-top: $spacing-05; + } } @include breakpoint(max) { diff --git a/packages/styles/scss/components/structured-list/_structured-list.scss b/packages/styles/scss/components/structured-list/_structured-list.scss index 08a64f15cc9d..ed2c72bb94bc 100644 --- a/packages/styles/scss/components/structured-list/_structured-list.scss +++ b/packages/styles/scss/components/structured-list/_structured-list.scss @@ -36,7 +36,10 @@ display: table; width: 100%; - margin-bottom: 5rem; + @if not enabled('enable-v11-release') { + margin-bottom: 5rem; + } + background-color: transparent; border-collapse: collapse; border-spacing: 0; From 3f7fbdf5b1dfd45e9c2061bc65890534f4c25ddf Mon Sep 17 00:00:00 2001 From: Kin Ueng Date: Wed, 20 Oct 2021 12:09:38 -0500 Subject: [PATCH 11/15] fix(button): hcm for ghost icon color contrast (#9904) * fix(button): hcm for ghost icon color contrast - #9903 * fix(button): hcm iconOnly fill fix, mirror to styles package Co-authored-by: Taylor Jones Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/components/src/components/button/_button.scss | 9 +++++++++ packages/styles/scss/components/button/_button.scss | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/packages/components/src/components/button/_button.scss b/packages/components/src/components/button/_button.scss index 307d9914392d..621372083de3 100644 --- a/packages/components/src/components/button/_button.scss +++ b/packages/components/src/components/button/_button.scss @@ -523,6 +523,15 @@ .#{$prefix}--btn:focus { @include high-contrast-mode('focus'); } + + // Windows HCM fix + // stylelint-disable-next-line no-duplicate-selectors + .#{$prefix}--btn--ghost.#{$prefix}--btn--icon-only + .#{$prefix}--btn__icon + path:not([data-icon-path]):not([fill='none']), + .#{$prefix}--btn--ghost.#{$prefix}--btn--icon-only .#{$prefix}--btn__icon { + @include high-contrast-mode('icon-fill'); + } } @include exports('button') { diff --git a/packages/styles/scss/components/button/_button.scss b/packages/styles/scss/components/button/_button.scss index 6b32ccdae45b..d89b56c32fc1 100644 --- a/packages/styles/scss/components/button/_button.scss +++ b/packages/styles/scss/components/button/_button.scss @@ -525,4 +525,13 @@ .#{$prefix}--btn:focus { @include high-contrast-mode('focus'); } + + // Windows HCM fix + // stylelint-disable-next-line no-duplicate-selectors + .#{$prefix}--btn--ghost.#{$prefix}--btn--icon-only + .#{$prefix}--btn__icon + path:not([data-icon-path]):not([fill='none']), + .#{$prefix}--btn--ghost.#{$prefix}--btn--icon-only .#{$prefix}--btn__icon { + @include high-contrast-mode('icon-fill'); + } } From 84de2dc35cb337b9e7fd60e7fe0535449ae730ce Mon Sep 17 00:00:00 2001 From: Taylor Jones Date: Wed, 20 Oct 2021 15:41:41 -0500 Subject: [PATCH 12/15] feat(multiselect): allow disabled listbox items (#9859) * feat(multiselect): allow disabled listbox items * fix(listbox): use disabled-02 instead of disabled-03 for items Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../MultiSelect/MultiSelect.stories.js | 3 +- .../src/components/list-box/_list-box.scss | 28 +++++++++++++++++++ .../MultiSelect/MultiSelect-story.js | 3 +- .../src/components/MultiSelect/MultiSelect.js | 1 + .../scss/components/list-box/_list-box.scss | 28 +++++++++++++++++++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/packages/carbon-react/src/components/MultiSelect/MultiSelect.stories.js b/packages/carbon-react/src/components/MultiSelect/MultiSelect.stories.js index ee8df2d982fd..d30f81f1ca0b 100644 --- a/packages/carbon-react/src/components/MultiSelect/MultiSelect.stories.js +++ b/packages/carbon-react/src/components/MultiSelect/MultiSelect.stories.js @@ -20,7 +20,8 @@ const items = [ }, { id: 'downshift-1-item-2', - text: 'Option 3', + text: 'Option 3 - a disabled item', + disabled: true, }, { id: 'downshift-1-item-3', diff --git a/packages/components/src/components/list-box/_list-box.scss b/packages/components/src/components/list-box/_list-box.scss index 32cb93a25edb..61b22c191879 100644 --- a/packages/components/src/components/list-box/_list-box.scss +++ b/packages/components/src/components/list-box/_list-box.scss @@ -658,6 +658,34 @@ $list-box-menu-width: rem(300px); color: $disabled-02; } + .#{$prefix}--list-box__menu-item[disabled], + .#{$prefix}--list-box__menu-item[disabled] *, + .#{$prefix}--list-box__menu-item[disabled]:hover { + color: $disabled-02; + cursor: not-allowed; + outline: none; + } + + .#{$prefix}--list-box__menu-item[disabled]:hover { + background-color: revert; + } + + .#{$prefix}--list-box__menu-item[disabled] + .#{$prefix}--checkbox-label::before { + border-color: $disabled-02; + } + + .#{$prefix}--list-box__menu-item[disabled] + .#{$prefix}--list-box__menu-item__option { + border-top-color: $ui-03; + } + + .#{$prefix}--list-box__menu-item[disabled]:hover + + .#{$prefix}--list-box__menu-item + .#{$prefix}--list-box__menu-item__option { + border-top-color: $ui-03; + } + .#{$prefix}--list-box.#{$prefix}--list-box--inline .#{$prefix}--list-box__menu-item__option { margin: 0 $carbon--spacing-03; diff --git a/packages/react/src/components/MultiSelect/MultiSelect-story.js b/packages/react/src/components/MultiSelect/MultiSelect-story.js index 7b6189191402..5872c25c574d 100644 --- a/packages/react/src/components/MultiSelect/MultiSelect-story.js +++ b/packages/react/src/components/MultiSelect/MultiSelect-story.js @@ -32,7 +32,8 @@ const items = [ }, { id: 'downshift-1-item-2', - text: 'Option 3', + text: 'Option 3 - a disabled item', + disabled: true, }, { id: 'downshift-1-item-3', diff --git a/packages/react/src/components/MultiSelect/MultiSelect.js b/packages/react/src/components/MultiSelect/MultiSelect.js index 1f38ef456a2c..4524192e85e4 100644 --- a/packages/react/src/components/MultiSelect/MultiSelect.js +++ b/packages/react/src/components/MultiSelect/MultiSelect.js @@ -282,6 +282,7 @@ const MultiSelect = React.forwardRef(function MultiSelect( // we don't want Downshift to set aria-selected for us // we also don't want to set 'false' for reader verbosity's sake ['aria-selected']: isChecked ? true : null, + disabled: item?.disabled, }); const itemText = itemToString(item); const isChecked = diff --git a/packages/styles/scss/components/list-box/_list-box.scss b/packages/styles/scss/components/list-box/_list-box.scss index 797fa331cdec..c3e863d32326 100644 --- a/packages/styles/scss/components/list-box/_list-box.scss +++ b/packages/styles/scss/components/list-box/_list-box.scss @@ -668,6 +668,34 @@ $list-box-menu-width: rem(300px); color: $text-disabled; } + .#{$prefix}--list-box__menu-item[disabled], + .#{$prefix}--list-box__menu-item[disabled] *, + .#{$prefix}--list-box__menu-item[disabled]:hover { + color: $text-disabled; + cursor: not-allowed; + outline: none; + } + + .#{$prefix}--list-box__menu-item[disabled]:hover { + background-color: revert; + } + + .#{$prefix}--list-box__menu-item[disabled] + .#{$prefix}--checkbox-label::before { + border-color: $text-disabled; + } + + .#{$prefix}--list-box__menu-item[disabled] + .#{$prefix}--list-box__menu-item__option { + border-top-color: $border-subtle; + } + + .#{$prefix}--list-box__menu-item[disabled]:hover + + .#{$prefix}--list-box__menu-item + .#{$prefix}--list-box__menu-item__option { + border-top-color: $border-subtle; + } + .#{$prefix}--list-box.#{$prefix}--list-box--inline .#{$prefix}--list-box__menu-item__option { margin: 0 $spacing-03; From 559412c9ade325337d1bfb9f0e995abdab853ddf Mon Sep 17 00:00:00 2001 From: "@RianTavaresOn" Date: Thu, 21 Oct 2021 12:15:30 -0300 Subject: [PATCH 13/15] feat(HeaderMenu): include isCurrentPage props to HeaderMenu component (#9785) * feat(HeaderMenu): include isCurrentPage props to HeaderMenu component set HeaderMenu as active when selected, contribute to the UX and accessibility * chore: update storybook to show example of isCurrentPage on sub-link Co-authored-by: Rian Tavares Co-authored-by: Taylor Jones --- .all-contributorsrc | 10 ++++++++++ README.md | 1 + .../src/components/ui-shell/_header.scss | 19 +++++++++++++++++++ .../src/components/UIShell/HeaderMenu.js | 8 +++++++- .../src/components/UIShell/UIShell-story.js | 10 +++++----- .../components/ui-shell/header/_header.scss | 19 +++++++++++++++++++ 6 files changed, 61 insertions(+), 6 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 438d1bb8bd25..92e7b8f4fbf8 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -802,6 +802,16 @@ "code" ] }, + { + "login": "RianTavares", + "name": "@RianTavaresOn", + "avatar_url": "https://avatars.githubusercontent.com/u/8935295?v=4", + "profile": "https://riantavares.github.io/", + "contributions": [ + "code", + "design" + ] + }, { "login": "ColbyJohnIBM", "name": "ColbyJohnIBM", diff --git a/README.md b/README.md index 935208018c02..a3911db05b94 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,7 @@ check out our [Contributing Guide](/.github/CONTRIBUTING.md) and our
    Adam Alston

    📖
    Krithika S Udupa

    📖
    Eshin Griffith

    💻 +
    @RianTavaresOn

    💻 🎨
    ColbyJohnIBM

    💻 diff --git a/packages/components/src/components/ui-shell/_header.scss b/packages/components/src/components/ui-shell/_header.scss index 22e5f21f5b34..77118b94f71b 100644 --- a/packages/components/src/components/ui-shell/_header.scss +++ b/packages/components/src/components/ui-shell/_header.scss @@ -245,6 +245,25 @@ position: relative; } + .#{$prefix}--header__submenu--current::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + border-bottom: 3px solid $border-interactive; + content: ''; + } + + .#{$prefix}--header__submenu--current:focus { + border: 2px solid $focus; + } + + .#{$prefix}--header__submenu--current:focus::after { + border: 0; + } + .#{$prefix}--header__menu-title[aria-haspopup='true'] { position: relative; } diff --git a/packages/react/src/components/UIShell/HeaderMenu.js b/packages/react/src/components/UIShell/HeaderMenu.js index ac49ec9d930f..0f7792aec7c7 100644 --- a/packages/react/src/components/UIShell/HeaderMenu.js +++ b/packages/react/src/components/UIShell/HeaderMenu.js @@ -160,6 +160,7 @@ class HeaderMenu extends React.Component { render() { const prefix = this.context; const { + isCurrentPage, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, className: customClassName, @@ -174,7 +175,12 @@ class HeaderMenu extends React.Component { 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, }; - const className = cx(`${prefix}--header__submenu`, customClassName); + const className = cx({ + [`${prefix}--header__submenu`]: true, + [customClassName]: true, + [`${prefix}--header__submenu--current`]: isCurrentPage, + }); + // Notes on eslint comments and based on the examples in: // https://www.w3.org/TR/wai-aria-practices/examples/menubar/menubar-1/menubar-1.html# // - The focus is handled by the menuitem, onMouseOver is for mouse diff --git a/packages/react/src/components/UIShell/UIShell-story.js b/packages/react/src/components/UIShell/UIShell-story.js index f202fbce11f6..abf309dcb68c 100644 --- a/packages/react/src/components/UIShell/UIShell-story.js +++ b/packages/react/src/components/UIShell/UIShell-story.js @@ -203,14 +203,14 @@ export const HeaderBaseWNavigation = withReadme(readme, () => ( [Platform] - - Link 1 - + Link 1 Link 2 Link 3 - + Sub-link 1 - Sub-link 2 + + Sub-link 2 + Sub-link 3 diff --git a/packages/styles/scss/components/ui-shell/header/_header.scss b/packages/styles/scss/components/ui-shell/header/_header.scss index 3809b2602699..b88dcda6f355 100644 --- a/packages/styles/scss/components/ui-shell/header/_header.scss +++ b/packages/styles/scss/components/ui-shell/header/_header.scss @@ -269,6 +269,25 @@ position: relative; } + .#{$prefix}--header__submenu--current::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + border-bottom: 3px solid $border-interactive; + content: ''; + } + + .#{$prefix}--header__submenu--current:focus { + border: 2px solid $focus; + } + + .#{$prefix}--header__submenu--current:focus::after { + border: 0; + } + .#{$prefix}--header__menu-title[aria-haspopup='true'] { position: relative; } From a9c13fffe27b61c5662b785af0010489caa18ae1 Mon Sep 17 00:00:00 2001 From: Scott Strubberg Date: Thu, 21 Oct 2021 12:21:41 -0500 Subject: [PATCH 14/15] feat(modal): deprecate iconDescription (#9828) * feat(modal): deprecate iconDescription new tests * feat(modal): update test co-authored: @aledavila * feat(modal): updated snappy * Update packages/react/src/components/Modal/Modal-test.js Co-authored-by: DAK <40970507+dakahn@users.noreply.github.com> * feat(modal): added test * feat(modal): updated snappy * feat(Modal): aria lable on the close icon * feat(Modal): updated wrapper test Co-authored-by: DAK <40970507+dakahn@users.noreply.github.com> --- .../__snapshots__/PublicAPI-test.js.snap | 5 +---- .../react/src/components/Modal/Modal-story.js | 1 - .../react/src/components/Modal/Modal-test.js | 17 ++++++----------- packages/react/src/components/Modal/Modal.js | 14 +++++++++----- .../__snapshots__/ModalWrapper-test.js.snap | 17 ++++++++++------- 5 files changed, 26 insertions(+), 28 deletions(-) diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index 6223d424aed7..bcf4df344ccc 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -3811,7 +3811,6 @@ Map { "Modal" => Object { "defaultProps": Object { "hasScrollingContent": false, - "iconDescription": "Close", "modalHeading": "", "modalLabel": "", "onKeyDown": [Function], @@ -3841,9 +3840,7 @@ Map { "hasScrollingContent": Object { "type": "bool", }, - "iconDescription": Object { - "type": "string", - }, + "iconDescription": [Function], "id": Object { "type": "string", }, diff --git a/packages/react/src/components/Modal/Modal-story.js b/packages/react/src/components/Modal/Modal-story.js index 61351855588c..86556df7f226 100644 --- a/packages/react/src/components/Modal/Modal-story.js +++ b/packages/react/src/components/Modal/Modal-story.js @@ -68,7 +68,6 @@ const props = { '[data-modal-primary-focus]' ), size: select('Size (size)', sizes, 'md'), - iconDescription: text('Close icon description (iconDescription)', 'Close'), onBlur: action('onBlur'), onClick: action('onClick'), onFocus: action('onFocus'), diff --git a/packages/react/src/components/Modal/Modal-test.js b/packages/react/src/components/Modal/Modal-test.js index e860715e1db9..872974008ce9 100644 --- a/packages/react/src/components/Modal/Modal-test.js +++ b/packages/react/src/components/Modal/Modal-test.js @@ -47,19 +47,14 @@ describe('Modal', () => { expect(getModal(modal).props().id).toEqual('modal-1'); }); - it('has the expected default iconDescription', () => { - expect(mounted.props().iconDescription).toEqual('Close'); + it('should not place the svg icon in the accessibility tree', () => { + const ariaHidden = mounted.find(Close20).props()['aria-hidden']; + expect(ariaHidden).toEqual('true'); }); - it('adds new iconDescription when passed via props', () => { - mounted.setProps({ iconDescription: 'new description' }); - expect(mounted.props().iconDescription).toEqual('new description'); - }); - - it('should have iconDescription match Icon component description prop', () => { - const description = mounted.find(Close20).props()['aria-label']; - const matches = mounted.props().iconDescription === description; - expect(matches).toEqual(true); + it("icon isn't a focusable tab stop", () => { + const icon = mounted.find(Close20).props().tabIndex; + expect(icon).toEqual('-1'); }); it('enables primary button by default', () => { diff --git a/packages/react/src/components/Modal/Modal.js b/packages/react/src/components/Modal/Modal.js index 012baa8e1216..66c61af0a479 100644 --- a/packages/react/src/components/Modal/Modal.js +++ b/packages/react/src/components/Modal/Modal.js @@ -80,7 +80,10 @@ export default class Modal extends Component { /** * Provide a description for "close" icon that can be read by screen readers */ - iconDescription: PropTypes.string, + iconDescription: deprecate( + PropTypes.string, + 'The iconDescription prop is no longer needed and can be safely removed. This prop will be removed in the next major release of Carbon.' + ), /** * Specify the DOM element ID of the top-level node. @@ -220,7 +223,6 @@ export default class Modal extends Component { primaryButtonDisabled: false, onKeyDown: () => {}, passiveModal: false, - iconDescription: 'Close', modalHeading: '', modalLabel: '', preventCloseOnClickOutside: false, @@ -417,11 +419,13 @@ export default class Modal extends Component { className={this.modalCloseButtonClass} type="button" onClick={onRequestClose} - title={iconDescription} - aria-label={iconDescription} + title={ariaLabel ? ariaLabel : iconDescription} + aria-label={ariaLabel ? ariaLabel : iconDescription} ref={this.button}>