Skip to content

Commit

Permalink
fix(Buttons): correctly support overriding default data-garden-id a…
Browse files Browse the repository at this point in the history
…ttribute (#1804)
  • Loading branch information
ze-flo committed May 17, 2024
1 parent 1fc76da commit 12c7917
Show file tree
Hide file tree
Showing 20 changed files with 127 additions and 78 deletions.
15 changes: 15 additions & 0 deletions packages/buttons/src/elements/Button.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import React from 'react';
import { render, renderRtl } from 'garden-test-utils';
import { Button } from './Button';
import TestIcon from '@zendeskgarden/svg-icons/src/16/gear-stroke.svg';
import { COMPONENT_ID } from '../styled/StyledButton';

describe('Button', () => {
it('is rendered as a button', () => {
Expand All @@ -24,6 +25,20 @@ describe('Button', () => {
expect(container.firstChild).toBe(ref.current);
});

describe('`data-garden-id` attribute', () => {
it('sets a default data-garden-id attribute', () => {
const { getByRole } = render(<Button />);

expect(getByRole('button')).toHaveAttribute('data-garden-id', COMPONENT_ID);
});

it('supports overriding the data-garden-id attribute', () => {
const { getByRole } = render(<Button data-garden-id="myCoolButton" />);

expect(getByRole('button')).toHaveAttribute('data-garden-id', 'myCoolButton');
});
});

describe('Icons', () => {
it('successfully renders start and end icons', () => {
const { getByTestId } = render(
Expand Down
9 changes: 9 additions & 0 deletions packages/buttons/src/styled/StyledAnchor.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import React from 'react';
import { render, renderRtl } from 'garden-test-utils';

import { PALETTE } from '@zendeskgarden/react-theming';
import { StyledAnchor } from './StyledAnchor';

Expand Down Expand Up @@ -34,4 +35,12 @@ describe('StyledAnchor', () => {

expect(container.firstChild).toHaveStyleRule('direction', 'rtl');
});

describe('`data-garden-id` attribute', () => {
it('has the correct `data-garden-id`', () => {
const { container } = render(<StyledAnchor />);

expect(container.firstChild).toHaveAttribute('data-garden-id', 'buttons.anchor');
});
});
});
5 changes: 3 additions & 2 deletions packages/buttons/src/styled/StyledAnchor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
import styled from 'styled-components';
import { retrieveComponentStyles, DEFAULT_THEME } from '@zendeskgarden/react-theming';
import { StyledButton } from './StyledButton';
import { IAnchorProps } from './../types';

const COMPONENT_ID = 'buttons.anchor';

/**
* Accepts all `<a>` props
*/
export const StyledAnchor = styled(StyledButton).attrs(props => ({
export const StyledAnchor = styled(StyledButton).attrs<IAnchorProps>(props => ({
'data-garden-id': COMPONENT_ID,
'data-garden-version': PACKAGE_VERSION,
as: 'a',
Expand All @@ -24,7 +25,7 @@ export const StyledAnchor = styled(StyledButton).attrs(props => ({
}))`
direction: ${props => props.theme.rtl && 'rtl'};
${props => retrieveComponentStyles(COMPONENT_ID, props)};
${props => retrieveComponentStyles((props as any)['data-garden-id'], props)};
`;

StyledAnchor.defaultProps = {
Expand Down
4 changes: 2 additions & 2 deletions packages/buttons/src/styled/StyledButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { IButtonProps } from '../types';
import { StyledSplitButton } from './StyledSplitButton';
import { StyledIcon } from './StyledIcon';

const COMPONENT_ID = 'buttons.button';
export const COMPONENT_ID = 'buttons.button';

const getBorderRadius = (props: IButtonProps & ThemeProps<DefaultTheme>) => {
if (props.isPill) {
Expand Down Expand Up @@ -431,7 +431,7 @@ const sizeStyles = (props: IButtonProps & ThemeProps<DefaultTheme>) => {
* 3. Shifting :focus-visible from LVHFA order to preserve `text-decoration` on hover
*/
export const StyledButton = styled.button.attrs<IButtonProps>(props => ({
'data-garden-id': COMPONENT_ID,
'data-garden-id': (props as any)['data-garden-id'] || COMPONENT_ID,
'data-garden-version': PACKAGE_VERSION,
type: props.type || 'button'
}))<IButtonProps>`
Expand Down
12 changes: 12 additions & 0 deletions packages/buttons/src/styled/StyledIcon.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,16 @@ describe('StyledIcon', () => {
}).toThrow();
});
});

describe('`data-garden-id` attribute', () => {
it('has the correct `data-garden-id`', () => {
const { container } = render(
<StyledIcon>
<TestIcon />
</StyledIcon>
);

expect(container.firstChild).toHaveAttribute('data-garden-id', 'buttons.icon');
});
});
});
10 changes: 9 additions & 1 deletion packages/buttons/src/styled/StyledIconButton.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import React from 'react';
import { css } from 'styled-components';
import { render } from 'garden-test-utils';
import { StyledIconButton } from './StyledIconButton';
import { COMPONENT_ID, StyledIconButton } from './StyledIconButton';
import { StyledIcon } from './StyledIcon';
import { PALETTE } from '@zendeskgarden/react-theming';
import { rgba } from 'polished';
Expand Down Expand Up @@ -88,4 +88,12 @@ describe('StyledIconButton', () => {
});
});
});

describe('`data-garden-id` attribute', () => {
it('has the correct `data-garden-id`', () => {
const { container } = render(<StyledIconButton />);

expect(container.firstChild).toHaveAttribute('data-garden-id', COMPONENT_ID);
});
});
});
18 changes: 11 additions & 7 deletions packages/buttons/src/styled/StyledIconButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
import styled, { css, ThemeProps, DefaultTheme } from 'styled-components';
import { retrieveComponentStyles, DEFAULT_THEME, getColor } from '@zendeskgarden/react-theming';
import { IButtonProps } from '../types';
import { StyledButton, getHeight } from './StyledButton';
import { COMPONENT_ID as BTN_COMPONENT_ID, StyledButton, getHeight } from './StyledButton';
import { StyledIcon } from './StyledIcon';

const COMPONENT_ID = 'buttons.icon_button';
export const COMPONENT_ID = 'buttons.icon_button';

const iconColorStyles = ({ theme }: IButtonProps & ThemeProps<DefaultTheme>) => {
const options = { theme, variable: 'foreground.default' };
Expand Down Expand Up @@ -69,17 +69,21 @@ const iconStyles = (props: IButtonProps & ThemeProps<DefaultTheme>) => {
`;
};

export const StyledIconButton = styled(StyledButton as 'button').attrs({
'data-garden-id': COMPONENT_ID,
'data-garden-version': PACKAGE_VERSION
})<IButtonProps>`
export const StyledIconButton = styled(StyledButton).attrs<IButtonProps>(props => {
const externalId: string = (props as any)['data-garden-id'];

return {
'data-garden-id': externalId && externalId !== BTN_COMPONENT_ID ? externalId : COMPONENT_ID,
'data-garden-version': PACKAGE_VERSION
};
})`
${props => iconButtonStyles(props)};
& ${StyledIcon} {
${props => iconStyles(props)}
}
${props => retrieveComponentStyles(COMPONENT_ID, props)};
${props => retrieveComponentStyles((props as any)['data-garden-id'], props)};
`;

StyledIconButton.defaultProps = {
Expand Down
4 changes: 2 additions & 2 deletions packages/buttons/src/styled/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
*/

export * from './StyledAnchor';
export * from './StyledButton';
export { StyledButton } from './StyledButton';
export * from './StyledSplitButton';
export * from './StyledExternalIcon';
export * from './StyledIcon';
export * from './StyledIconButton';
export { StyledIconButton } from './StyledIconButton';
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,20 @@ describe('ColorSwatchDialog', () => {
expect(dialog).toBeNull();
});
});

describe('`data-garden-id` attribute', () => {
it('has the correct `data-garden-id`', () => {
const { getByRole } = render(
<ColorSwatchDialog
name="test"
colors={colors}
buttonProps={{
'aria-label': 'Choose your favorite color'
}}
/>
);

expect(getByRole('button')).toHaveAttribute('data-garden-id', 'buttons.button');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,15 @@
*/

import styled from 'styled-components';
import { retrieveComponentStyles, DEFAULT_THEME } from '@zendeskgarden/react-theming';
import { DEFAULT_THEME } from '@zendeskgarden/react-theming';
import { Button } from '@zendeskgarden/react-buttons';

const COMPONENT_ID = 'colorpickers.colordialog_button';

/**
* 1. IE11 group width override.
* 2. Input group border overrides.
*/
export const StyledButton = styled(Button as any).attrs({
isNeutral: true,
'data-garden-id': COMPONENT_ID,
'data-garden-version': PACKAGE_VERSION
})`
padding: 0;
Expand All @@ -32,8 +29,6 @@ export const StyledButton = styled(Button as any).attrs({
${props => props.theme.borderRadii.md} !important; /* [2] */
/* stylelint-enable */
}
${props => retrieveComponentStyles(COMPONENT_ID, props)};
`;

StyledButton.defaultProps = {
Expand Down
11 changes: 11 additions & 0 deletions packages/dropdowns/src/elements/menu/Menu.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -659,4 +659,15 @@ describe('Menu', () => {
expect(getByTestId('grape')).toHaveAttribute('aria-checked', 'true');
});
});

describe('`data-garden-id` attribute', () => {
it('has the correct `data-garden-id`', async () => {
const { getByRole } = render(<TestMenu button="click me" />);

await floating();
const button = getByRole('button');

expect(button).toHaveAttribute('data-garden-id', 'buttons.button');
});
});
});
11 changes: 5 additions & 6 deletions packages/dropdowns/src/elements/menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ import { mergeRefs } from 'react-merge-refs';
import { ThemeContext } from 'styled-components';
import { useMenu } from '@zendeskgarden/container-menu';
import { DEFAULT_THEME, useWindow } from '@zendeskgarden/react-theming';
import { IButtonProps } from '@zendeskgarden/react-buttons';
import { Button, IButtonProps } from '@zendeskgarden/react-buttons';
import { IMenuProps, PLACEMENT } from '../../types';
import { MenuContext } from '../../context/useMenuContext';
import { toItems } from './utils';
import { MenuList } from './MenuList';
import { StyledButton } from '../../views';
import ChevronIcon from '@zendeskgarden/svg-icons/src/16/chevron-down-stroke.svg';

/**
Expand Down Expand Up @@ -87,12 +86,12 @@ export const Menu = forwardRef<HTMLUListElement, IMenuProps>(
typeof button === 'function' ? (
button(triggerProps)
) : (
<StyledButton {...triggerProps}>
<Button {...triggerProps}>
{button}
<StyledButton.EndIcon isRotated={isExpanded}>
<Button.EndIcon isRotated={isExpanded}>
<ChevronIcon />
</StyledButton.EndIcon>
</StyledButton>
</Button.EndIcon>
</Button>
);

const contextValue = useMemo(
Expand Down
1 change: 0 additions & 1 deletion packages/dropdowns/src/views/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,4 @@ export * from './menu/StyledItemGroup';
export * from './menu/StyledItemIcon';
export * from './menu/StyledItemMeta';
export * from './menu/StyledItemTypeIcon';
export * from './menu/StyledButton';
export * from './menu/StyledSeparator';
23 changes: 0 additions & 23 deletions packages/dropdowns/src/views/menu/StyledButton.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,12 @@ describe('SplitterButton', () => {

expect(getByLabelText('toggle a').querySelector('svg')).toBeDefined();
});

describe('`data-garden-id` attribute', () => {
it('has the correct `data-garden-id`', () => {
const { getByLabelText } = render(<UncontrolledTestSplitter />);

expect(getByLabelText('toggle a')).toHaveAttribute('data-garden-id', 'buttons.icon_button');
});
});
});
7 changes: 1 addition & 6 deletions packages/grid/src/styled/pane/StyledPaneSplitterButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
*/

import styled, { css, ThemeProps, DefaultTheme } from 'styled-components';
import { retrieveComponentStyles, DEFAULT_THEME } from '@zendeskgarden/react-theming';
import { DEFAULT_THEME } from '@zendeskgarden/react-theming';
import { ChevronButton } from '@zendeskgarden/react-buttons';
import { Orientation } from '../../types';

const COMPONENT_ID = 'pane.splitter_button';

interface IStyledSplitterButtonProps {
orientation: Orientation;
isRotated: boolean;
Expand Down Expand Up @@ -52,7 +50,6 @@ const transformStyles = (props: IStyledSplitterButtonProps & ThemeProps<DefaultT
};

export const StyledPaneSplitterButton = styled(ChevronButton).attrs<IStyledSplitterButtonProps>({
'data-garden-id': COMPONENT_ID,
'data-garden-version': PACKAGE_VERSION,
isBasic: true,
isPill: true,
Expand All @@ -61,8 +58,6 @@ export const StyledPaneSplitterButton = styled(ChevronButton).attrs<IStyledSplit
${sizeStyles};
${transformStyles};
${props => retrieveComponentStyles(COMPONENT_ID, props)};
`;

StyledPaneSplitterButton.defaultProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,12 @@ describe('StyledGlobalAlertButton', () => {
}[type]
);
});

describe('`data-garden-id` attribute', () => {
it('has the correct `data-garden-id`', () => {
const { container } = render(<StyledGlobalAlertButton alertType="info" />);

expect(container.firstChild).toHaveAttribute('data-garden-id', 'buttons.button');
});
});
});
Loading

0 comments on commit 12c7917

Please sign in to comment.