From de89214a2e610ab699f92e0ced0a1c3608a6ca3a Mon Sep 17 00:00:00 2001 From: Taylor Jones Date: Mon, 16 Oct 2023 06:13:30 -0500 Subject: [PATCH 1/7] fix(zone): update styles to use the prefix (#14828) --- packages/styles/scss/_zone.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/styles/scss/_zone.scss b/packages/styles/scss/_zone.scss index 5231021ea791..7db95559987e 100644 --- a/packages/styles/scss/_zone.scss +++ b/packages/styles/scss/_zone.scss @@ -36,8 +36,8 @@ $-components: ( @each $name, $theme in $zones { .#{config.$prefix}--#{'' + $name} { - background: var(--cds-background); - color: var(--cds-text-primary); + background-color: custom-property.get-var('background'); + color: custom-property.get-var('text-primary'); @each $key, $value in $theme { @if type-of($value) == color { From 95250c28c240c23e2c67a8f5827756e0e85c42f6 Mon Sep 17 00:00:00 2001 From: Guilherme Datilio Ribeiro Date: Mon, 16 Oct 2023 08:14:40 -0300 Subject: [PATCH 2/7] Add Keyboard Nav AVT test for `MenuButton` (#14842) * test: added avt file * test: added keyboard nav test --- .../MenuButton/MenuButton-test.avt.e2e.js | 137 ++++++++++++++++++ .../MenuButton/MenuButton-test.e2e.js | 15 +- 2 files changed, 139 insertions(+), 13 deletions(-) create mode 100644 e2e/components/MenuButton/MenuButton-test.avt.e2e.js diff --git a/e2e/components/MenuButton/MenuButton-test.avt.e2e.js b/e2e/components/MenuButton/MenuButton-test.avt.e2e.js new file mode 100644 index 000000000000..1069c355dac7 --- /dev/null +++ b/e2e/components/MenuButton/MenuButton-test.avt.e2e.js @@ -0,0 +1,137 @@ +/** + * Copyright IBM Corp. 2023 + * + * 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 { visitStory } = require('../../test-utils/storybook'); + +test.describe('MenuButton @avt', () => { + test('@avt-default-state MenuButton', async ({ page }) => { + await visitStory(page, { + component: 'MenuButton', + id: 'components-menubutton--default', + globals: { + theme: 'white', + }, + }); + await expect(page).toHaveNoACViolations('MenuButton'); + }); + + test('@avt-advanced-states MenuButton with danger', async ({ page }) => { + await visitStory(page, { + component: 'MenuButton', + id: 'components-menubutton--with-danger', + globals: { + theme: 'white', + }, + }); + await expect(page).toHaveNoACViolations('MenuButton-with-danger'); + }); + + test('@avt-advanced-states MenuButton with dividers', async ({ page }) => { + await visitStory(page, { + component: 'MenuButton', + id: 'components-menubutton--with-dividers', + globals: { + theme: 'white', + }, + }); + await expect(page).toHaveNoACViolations('MenuButton-with-dividers'); + }); + + test('@avt-keyboard-nav MenuButton', async ({ page }) => { + await visitStory(page, { + component: 'MenuButton', + id: 'components-menubutton--default', + globals: { + theme: 'white', + }, + }); + + const actionButton = page.getByRole('button', { name: 'Action' }); + await expect(actionButton).toBeVisible(); + + await page.keyboard.press('Tab'); + await expect(actionButton).toBeFocused(); + + // Entering the menu button + await page.keyboard.press('Enter'); + await expect(page.getByRole('menuitem').first()).toBeFocused(); + await page.keyboard.press('ArrowDown'); + await expect(page.getByRole('menuitem').nth(1)).toBeFocused(); + // Skip the disabled item and come back to the first item + await page.keyboard.press('ArrowDown'); + await expect(page.getByRole('menuitem').first()).toBeFocused(); + + // Closing by selecting an item and focusing on the action button + await page.keyboard.press('Enter'); + await expect(actionButton).toBeFocused(); + }); + + test('@avt-keyboard-nav MenuButton with danger', async ({ page }) => { + await visitStory(page, { + component: 'MenuButton', + id: 'components-menubutton--with-danger', + globals: { + theme: 'white', + }, + }); + + const actionButton = page.getByRole('button', { name: 'Action' }); + await expect(actionButton).toBeVisible(); + + await page.keyboard.press('Tab'); + await expect(actionButton).toBeFocused(); + + // Entering the menu button + await page.keyboard.press('Enter'); + await expect(page.getByRole('menuitem').first()).toBeFocused(); + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('ArrowDown'); + + // Validate danger button + await expect(page.getByRole('menuitem').last()).toBeFocused(); + await expect(page.getByText('Danger action')).toBeVisible(); + + // Closing by selecting an item and focusing on the action button + await page.keyboard.press('Enter'); + await expect(actionButton).toBeFocused(); + }); + + test('@avt-keyboard-nav MenuButton with dividers', async ({ page }) => { + await visitStory(page, { + component: 'MenuButton', + id: 'components-menubutton--with-dividers', + globals: { + theme: 'white', + }, + }); + + const actionButton = page.getByRole('button', { name: 'Action' }); + await expect(actionButton).toBeVisible(); + + await page.keyboard.press('Tab'); + await expect(actionButton).toBeFocused(); + + // Entering the menu button + await page.keyboard.press('Enter'); + await expect(page.getByRole('menuitem').first()).toBeFocused(); + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('ArrowDown'); + await expect(page.getByRole('menuitem').last()).toBeFocused(); + expect(page.getByRole('separator')).toBeTruthy(); + + // Closing by selecting an item and focusing on the action button + await page.keyboard.press('Enter'); + await expect(actionButton).toBeFocused(); + }); +}); diff --git a/e2e/components/MenuButton/MenuButton-test.e2e.js b/e2e/components/MenuButton/MenuButton-test.e2e.js index 848c0c92e3ea..b5dbfa94edc9 100644 --- a/e2e/components/MenuButton/MenuButton-test.e2e.js +++ b/e2e/components/MenuButton/MenuButton-test.e2e.js @@ -7,9 +7,9 @@ 'use strict'; -const { expect, test } = require('@playwright/test'); +const { test } = require('@playwright/test'); const { themes } = require('../../test-utils/env'); -const { snapshotStory, visitStory } = require('../../test-utils/storybook'); +const { snapshotStory } = require('../../test-utils/storybook'); test.describe('MenuButton', () => { themes.forEach((theme) => { @@ -23,15 +23,4 @@ test.describe('MenuButton', () => { }); }); }); - - test('accessibility-checker @avt', async ({ page }) => { - await visitStory(page, { - component: 'MenuButton', - id: 'components-menubutton--default', - globals: { - theme: 'white', - }, - }); - await expect(page).toHaveNoACViolations('MenuButton'); - }); }); From f07c9e3fe75a23a34cd156f054f6926c08dac6f5 Mon Sep 17 00:00:00 2001 From: Rajat Date: Mon, 16 Oct 2023 17:06:50 +0530 Subject: [PATCH 3/7] refactor: migrate to ts (#14862) --- .../UIShell/{SideNavDetails.js => SideNavDetails.tsx} | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) rename packages/react/src/components/UIShell/{SideNavDetails.js => SideNavDetails.tsx} (89%) diff --git a/packages/react/src/components/UIShell/SideNavDetails.js b/packages/react/src/components/UIShell/SideNavDetails.tsx similarity index 89% rename from packages/react/src/components/UIShell/SideNavDetails.js rename to packages/react/src/components/UIShell/SideNavDetails.tsx index 5ec7f86c42ac..e5427612a31f 100644 --- a/packages/react/src/components/UIShell/SideNavDetails.js +++ b/packages/react/src/components/UIShell/SideNavDetails.tsx @@ -10,12 +10,18 @@ import PropTypes from 'prop-types'; import React from 'react'; import { usePrefix } from '../../internal/usePrefix'; +export interface SideNavDetailsProps { + children?: React.ReactNode; + className?: string; + title: string; +} + const SideNavDetails = ({ children, className: customClassName, title, ...rest -}) => { +}: SideNavDetailsProps) => { const prefix = usePrefix(); const className = cx(`${prefix}--side-nav__details`, customClassName); return ( From fa9c18c6bc77f27096e1b9fc4a5f1ed4c8573f0f Mon Sep 17 00:00:00 2001 From: Niraj Sah Date: Mon, 16 Oct 2023 19:06:49 +0530 Subject: [PATCH 4/7] feat(component): replaced -> component (#14894) --- .../UIShell/{SideNavDivider.js => SideNavDivider.tsx} | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) rename packages/react/src/components/UIShell/{SideNavDivider.js => SideNavDivider.tsx} (75%) diff --git a/packages/react/src/components/UIShell/SideNavDivider.js b/packages/react/src/components/UIShell/SideNavDivider.tsx similarity index 75% rename from packages/react/src/components/UIShell/SideNavDivider.js rename to packages/react/src/components/UIShell/SideNavDivider.tsx index 09f12aec22b2..e8bc8aa33e02 100644 --- a/packages/react/src/components/UIShell/SideNavDivider.js +++ b/packages/react/src/components/UIShell/SideNavDivider.tsx @@ -10,7 +10,13 @@ import PropTypes from 'prop-types'; import React from 'react'; import { usePrefix } from '../../internal/usePrefix'; -function SideNavDivider({ className }) { +interface SideNavDividerProps { + /** + * Provide an optional class to be applied to the containing node + */ + className?: string; +} +const SideNavDivider: React.FC = ({ className }) => { const prefix = usePrefix(); const classNames = cx(`${prefix}--side-nav__divider`, className); return ( @@ -18,7 +24,7 @@ function SideNavDivider({ className }) {
); -} +}; SideNavDivider.propTypes = { /** From c9ad02ff7566f957fb9ab7aac264098b8db1d1d8 Mon Sep 17 00:00:00 2001 From: Taylor Jones Date: Mon, 16 Oct 2023 13:34:47 -0500 Subject: [PATCH 5/7] chore(ci): reconfigure percy to only snapshot mobile in the white theme (#14886) Co-authored-by: Guilherme Datilio Ribeiro --- .percy.yml | 1 + e2e/test-utils/snapshot.js | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.percy.yml b/.percy.yml index 15ee8384f8c6..a98f025c5512 100644 --- a/.percy.yml +++ b/.percy.yml @@ -1,3 +1,4 @@ +# Percy config version: 2 snapshot: widths: diff --git a/e2e/test-utils/snapshot.js b/e2e/test-utils/snapshot.js index 72cf588c0595..879d267f8ffb 100644 --- a/e2e/test-utils/snapshot.js +++ b/e2e/test-utils/snapshot.js @@ -17,10 +17,21 @@ const { expect } = require('@playwright/test'); async function snapshot(page, context) { const id = getSnapshotId(context); + /** + * Restrict mobile snapshots to only the white theme. There's not really a strong + * reason for snapshotting components across 4 themes in mobile as components don't + * really have different visual states per breakpoint, per theme. + * The overall thinking is that if a bug appears in white, it'll be the same bug + * present in all other themes. + * This configuration overrides any global setting for `widths` in .percy.yml or otherwise. + * See https://github.com/carbon-design-system/carbon/issues/14779 + */ + const widths = context.themes === 'white' ? [1366, 360] : [1366]; + if (process.env.ENABLE_LOCAL_SNAPSHOTS) { expect(await page.screenshot()).toMatchSnapshot(`${id}.png`); } else { - await percySnapshot(page, id); + await percySnapshot(page, id, { widths: widths }); } } From 612f8b942c3184db283384dd9f3c6c89003903ba Mon Sep 17 00:00:00 2001 From: TJ Egan Date: Mon, 16 Oct 2023 15:16:30 -0400 Subject: [PATCH 6/7] fix(Type): update style to use prefix (#14852) --- packages/type/scss/_default-type.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/type/scss/_default-type.scss b/packages/type/scss/_default-type.scss index c2fdc278f5b8..02abcd9f808b 100644 --- a/packages/type/scss/_default-type.scss +++ b/packages/type/scss/_default-type.scss @@ -6,6 +6,7 @@ // @use 'sass:meta'; @use 'styles' as *; +@use 'prefix' as *; /// Include default type styles /// @access public @@ -40,7 +41,7 @@ } a { - color: var(--cds-link-primary, #0062fe); + color: var(--#{$prefix}-link-primary, #0062fe); } em { From 2b69c08fa2e2d0f0b7b78db7eb97242f3998f277 Mon Sep 17 00:00:00 2001 From: Aman Lajpal <42869088+amanlajpal@users.noreply.github.com> Date: Tue, 17 Oct 2023 01:55:36 +0530 Subject: [PATCH 7/7] feat(SkeletonIcon): Add types for `SkeletonIcon` (#14801) * refactor: added TypeScript types to SkeletonIcon * docs: adding myself to contributors list * refactor: added propTypes definition * refactor: using shorthand for className property * fix(SkeletonIcon): move className outside object --------- Co-authored-by: Taylor Jones Co-authored-by: TJ Egan --- .all-contributorsrc | 10 ++++++++++ README.md | 1 + .../{SkeletonIcon.js => SkeletonIcon.tsx} | 18 ++++++++++++++---- 3 files changed, 25 insertions(+), 4 deletions(-) rename packages/react/src/components/SkeletonIcon/{SkeletonIcon.js => SkeletonIcon.tsx} (68%) diff --git a/.all-contributorsrc b/.all-contributorsrc index 6e3ad91a49d7..a39fcda0c3df 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1268,6 +1268,16 @@ "contributions": [ "code" ] + }, + { + "login": "amanlajpal", + "name": "Aman Lajpal", + "avatar_url": "https://avatars.githubusercontent.com/u/42869088?v=4", + "profile": "https://github.com/amanlajpal", + "contributions": [ + "code", + "doc" + ] } ], "commitConvention": "none" diff --git a/README.md b/README.md index 2118c5c3ba11..7699c6db6d57 100644 --- a/README.md +++ b/README.md @@ -254,6 +254,7 @@ check out our [Contributing Guide](/.github/CONTRIBUTING.md) and our
cordesmj

πŸ’»
Aziz Chebbi

πŸ’»
MichaΕ‚ Konopski

πŸ’» +
Aman Lajpal

πŸ’» πŸ“– diff --git a/packages/react/src/components/SkeletonIcon/SkeletonIcon.js b/packages/react/src/components/SkeletonIcon/SkeletonIcon.tsx similarity index 68% rename from packages/react/src/components/SkeletonIcon/SkeletonIcon.js rename to packages/react/src/components/SkeletonIcon/SkeletonIcon.tsx index 9cc519f1e12e..521cafb73ff1 100644 --- a/packages/react/src/components/SkeletonIcon/SkeletonIcon.js +++ b/packages/react/src/components/SkeletonIcon/SkeletonIcon.tsx @@ -4,18 +4,28 @@ * 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'; -const SkeletonIcon = ({ className, ...other }) => { +interface SkeletonIconProps { + /** + * Specify an optional className to add. + */ + className?: string; + + /** + * The CSS styles. + */ + style?: React.CSSProperties; +} + +const SkeletonIcon: React.FC = ({ className, ...other }) => { const prefix = usePrefix(); - const skeletonIconClasses = classNames({ + const skeletonIconClasses = classNames(className, { [`${prefix}--icon--skeleton`]: true, - [className]: className, }); return
;