From 906f579854795733d4df2f80a4b970857af0fb32 Mon Sep 17 00:00:00 2001 From: Muhammad Mustafa Asif Date: Fri, 19 Jul 2024 12:43:57 +0200 Subject: [PATCH] feat(dropdown-menu): allow data attributes in dropdown component (#2855) * feat(dropdown-menu): allow data attributes in dropdown component * chore(changeset): added a changeset file for allowing data attributes to be passed down the dropdown component * feat(dropdown-menu): allow data attributes to pass through DropdownListMenuItem * feat: updated changeset file, added a data attributes test in AccessibleButton and updated the data attributes test in DropdownMenu --------- Co-authored-by: Douglas Egiemeh --- .changeset/calm-laws-kick.md | 6 +++ .../src/accessible-button.spec.js | 4 ++ .../src/accessible-button.tsx | 7 +++- .../dropdown-menu/src/dropdown-menu.spec.tsx | 41 +++++++++++++++++++ .../dropdown-menu/src/dropdown-menu.tsx | 2 + .../src/menu/dropdown-menu-list-item.tsx | 2 + .../src/menu/dropdown-menu-menu.tsx | 4 ++ 7 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 .changeset/calm-laws-kick.md diff --git a/.changeset/calm-laws-kick.md b/.changeset/calm-laws-kick.md new file mode 100644 index 0000000000..8800fe6b95 --- /dev/null +++ b/.changeset/calm-laws-kick.md @@ -0,0 +1,6 @@ +--- +'@commercetools-uikit/accessible-button': minor +'@commercetools-uikit/dropdown-menu': minor +--- + +Supports forwarding data-attributes to AccessibleButton and DropdownMenu components \ No newline at end of file diff --git a/packages/components/buttons/accessible-button/src/accessible-button.spec.js b/packages/components/buttons/accessible-button/src/accessible-button.spec.js index 9926a0d26c..db444b8905 100644 --- a/packages/components/buttons/accessible-button/src/accessible-button.spec.js +++ b/packages/components/buttons/accessible-button/src/accessible-button.spec.js @@ -54,6 +54,10 @@ describe('rendering', () => { 'true' ); }); + it('should pass data attributes', () => { + render(); + expect(screen.getByTestId('accessible-button')).toBeInTheDocument(); + }); describe('type variations', () => { it('should render a button of type "button"', () => { render(); diff --git a/packages/components/buttons/accessible-button/src/accessible-button.tsx b/packages/components/buttons/accessible-button/src/accessible-button.tsx index 400f4c6159..1e0697ad47 100644 --- a/packages/components/buttons/accessible-button/src/accessible-button.tsx +++ b/packages/components/buttons/accessible-button/src/accessible-button.tsx @@ -11,7 +11,11 @@ import { } from 'react'; import { isValidElementType } from 'react-is'; import omit from 'lodash/omit'; -import { filterAriaAttributes, warning } from '@commercetools-uikit/utils'; +import { + filterAriaAttributes, + filterDataAttributes, + warning, +} from '@commercetools-uikit/utils'; import { designTokens } from '@commercetools-uikit/design-system'; import { css } from '@emotion/react'; import styled from '@emotion/styled'; @@ -177,6 +181,7 @@ const AccessibleButton = forwardRef( {...omit(props.buttonAttributes, propsToOmit)} {...buttonProps} {...filterAriaAttributes(props)} + {...filterDataAttributes(props)} > {props.children} diff --git a/packages/components/dropdowns/dropdown-menu/src/dropdown-menu.spec.tsx b/packages/components/dropdowns/dropdown-menu/src/dropdown-menu.spec.tsx index d101744da7..dbda07c4a2 100644 --- a/packages/components/dropdowns/dropdown-menu/src/dropdown-menu.spec.tsx +++ b/packages/components/dropdowns/dropdown-menu/src/dropdown-menu.spec.tsx @@ -74,4 +74,45 @@ describe('DropdownMenu', () => { }); expect(await screen.findByText('Content')).not.toBeVisible(); }); + + it('should pass data attributes without menuType', async () => { + await render( + + } + > + + Option 1 + + + ); + + // Check that the data-testid attributes are passed down + expect(screen.getByTestId('trigger-element')).toBeInTheDocument(); + expect(screen.getByTestId('dropdown-container')).toBeInTheDocument(); + expect(screen.getByTestId('list-item')).toBeInTheDocument(); + }); + + it('should pass data attributes with menuType="list"', async () => { + await render( + + } + > + + Option 1 + + + ); + + // Check that the data-testid attributes are passed down + expect(screen.getByTestId('trigger-element')).toBeInTheDocument(); + expect(screen.getByTestId('dropdown-container')).toBeInTheDocument(); + expect(screen.getByTestId('list-item')).toBeInTheDocument(); + }); }); diff --git a/packages/components/dropdowns/dropdown-menu/src/dropdown-menu.tsx b/packages/components/dropdowns/dropdown-menu/src/dropdown-menu.tsx index 5ed6117670..a74744fbf9 100644 --- a/packages/components/dropdowns/dropdown-menu/src/dropdown-menu.tsx +++ b/packages/components/dropdowns/dropdown-menu/src/dropdown-menu.tsx @@ -7,6 +7,7 @@ import { type ReactNode, type RefObject, } from 'react'; +import { filterDataAttributes } from '@commercetools-uikit/utils'; import { useToggleState } from '@commercetools-uikit/hooks'; import { type TMaxProp } from '@commercetools-uikit/constraints'; import styled from '@emotion/styled'; @@ -158,6 +159,7 @@ function DropdownMenu(props: TDropdownMenuProps) { menuPosition={props.menuPosition!} menuMaxHeight={props.menuMaxHeight} triggerElementRef={triggerRef} + {...filterDataAttributes(props)} > {props.children} diff --git a/packages/components/dropdowns/dropdown-menu/src/menu/dropdown-menu-list-item.tsx b/packages/components/dropdowns/dropdown-menu/src/menu/dropdown-menu-list-item.tsx index d5b1311cf6..dbb14d093c 100644 --- a/packages/components/dropdowns/dropdown-menu/src/menu/dropdown-menu-list-item.tsx +++ b/packages/components/dropdowns/dropdown-menu/src/menu/dropdown-menu-list-item.tsx @@ -2,6 +2,7 @@ import { css } from '@emotion/react'; import AccessibleButton from '@commercetools-uikit/accessible-button'; import { designTokens } from '@commercetools-uikit/design-system'; import { useDropdownMenuContext } from '../context/dropdown-menu-context'; +import { filterDataAttributes } from '@commercetools-uikit/utils'; function getDropdownListMenuItemStyles(props: TDropdownListMenuItemProps) { return [ @@ -48,6 +49,7 @@ function DropdownListMenuItem(props: TDropdownListMenuItemProps) { }} isDisabled={props.isDisabled} css={getDropdownListMenuItemStyles(props)} + {...filterDataAttributes(props)} > {props.children} diff --git a/packages/components/dropdowns/dropdown-menu/src/menu/dropdown-menu-menu.tsx b/packages/components/dropdowns/dropdown-menu/src/menu/dropdown-menu-menu.tsx index b271d7447f..f54a5af008 100644 --- a/packages/components/dropdowns/dropdown-menu/src/menu/dropdown-menu-menu.tsx +++ b/packages/components/dropdowns/dropdown-menu/src/menu/dropdown-menu-menu.tsx @@ -9,6 +9,7 @@ import { css } from '@emotion/react'; import { designTokens } from '@commercetools-uikit/design-system'; import Constraints, { type TMaxProp } from '@commercetools-uikit/constraints'; import SpacingsStack from '@commercetools-uikit/spacings-stack'; +import { filterDataAttributes } from '@commercetools-uikit/utils'; // We declare this style properties here because we need them both for initial component styling // but also for calculating the default max height of the dropdown menu so we make sure it fits @@ -184,6 +185,7 @@ function DropdownBaseMenu(props: TDropdownBaseMenuProps) { css={getDropdownMenuBaseStyles(props)} style={props.customStyles} ref={menuRef} + {...filterDataAttributes(props)} > {props.children} @@ -209,6 +211,7 @@ export const DropdownContentMenu = (props: TDropdownContentMenuProps) => { menuPosition={props.menuPosition} menuMaxHeight={props.menuMaxHeight} triggerElementRef={props.triggerElementRef} + {...filterDataAttributes(props)} > {props.children} @@ -231,6 +234,7 @@ export const DropdownListMenu = (props: TDropdownListMenuProps) => { menuPosition={props.menuPosition} menuMaxHeight={props.menuMaxHeight} triggerElementRef={props.triggerElementRef} + {...filterDataAttributes(props)} > {props.children}