Skip to content

Commit 7b3082e

Browse files
committed
fix(Buttons): support overriding data-garden-id
1 parent ec71f03 commit 7b3082e

File tree

7 files changed

+41
-18
lines changed

7 files changed

+41
-18
lines changed

packages/buttons/src/elements/Button.spec.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@ describe('Button', () => {
2424
expect(container.firstChild).toBe(ref.current);
2525
});
2626

27+
describe('`data-garden-id` attribute', () => {
28+
it('sets a default data-garden-id attribute', () => {
29+
const { getByRole } = render(<Button />);
30+
31+
expect(getByRole('button')).toHaveAttribute('data-garden-id', 'buttons.button');
32+
});
33+
34+
it('supports overriding the data-garden-id attribute', () => {
35+
const { getByRole } = render(<Button data-garden-id="myCoolButton" />);
36+
37+
expect(getByRole('button')).toHaveAttribute('data-garden-id', 'myCoolButton');
38+
});
39+
});
40+
2741
describe('Icons', () => {
2842
it('successfully renders start and end icons', () => {
2943
const { getByTestId } = render(

packages/buttons/src/styled/StyledAnchor.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
import styled from 'styled-components';
99
import { retrieveComponentStyles, DEFAULT_THEME } from '@zendeskgarden/react-theming';
1010
import { StyledButton } from './StyledButton';
11+
import { IAnchorProps } from './../types';
1112

1213
const COMPONENT_ID = 'buttons.anchor';
1314

1415
/**
1516
* Accepts all `<a>` props
1617
*/
17-
export const StyledAnchor = styled(StyledButton).attrs(props => ({
18-
'data-garden-id': COMPONENT_ID,
18+
export const StyledAnchor = styled(StyledButton).attrs<IAnchorProps>(props => ({
19+
'data-garden-id': props['data-garden-id'] || COMPONENT_ID,
1920
'data-garden-version': PACKAGE_VERSION,
2021
as: 'a',
2122
dir: props.theme.rtl ? 'rtl' : undefined,
@@ -24,7 +25,7 @@ export const StyledAnchor = styled(StyledButton).attrs(props => ({
2425
}))`
2526
direction: ${props => props.theme.rtl && 'rtl'};
2627
27-
${props => retrieveComponentStyles(COMPONENT_ID, props)};
28+
${props => retrieveComponentStyles(props['data-garden-id'], props)};
2829
`;
2930

3031
StyledAnchor.defaultProps = {

packages/buttons/src/styled/StyledButton.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ const sizeStyles = (props: IButtonProps & ThemeProps<DefaultTheme>) => {
349349
* 3. Shifting :focus-visible from LVHFA order to preserve `text-decoration` on hover
350350
*/
351351
export const StyledButton = styled.button.attrs<IButtonProps>(props => ({
352-
'data-garden-id': COMPONENT_ID,
352+
'data-garden-id': props['data-garden-id'] || COMPONENT_ID,
353353
'data-garden-version': PACKAGE_VERSION,
354354
type: props.type || 'button'
355355
}))<IButtonProps>`

packages/buttons/src/styled/StyledIcon.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
const COMPONENT_ID = 'buttons.icon';
1616

1717
interface IStyledIconProps {
18+
'data-garden-id'?: string;
1819
$isRotated: boolean;
1920
$position?: 'start' | 'end';
2021
}
@@ -36,18 +37,18 @@ const sizeStyles = (props: IStyledIconProps & ThemeProps<DefaultTheme>) => {
3637
);
3738
};
3839

39-
export const StyledIcon = styled(StyledBaseIcon).attrs({
40-
'data-garden-id': COMPONENT_ID,
40+
export const StyledIcon = styled(StyledBaseIcon).attrs<IStyledIconProps>(props => ({
41+
'data-garden-id': props['data-garden-id'] || COMPONENT_ID,
4142
'data-garden-version': PACKAGE_VERSION
42-
})<IStyledIconProps>`
43+
}))<IStyledIconProps>`
4344
transform: ${props => props.$isRotated && `rotate(${props.theme.rtl ? '-' : '+'}180deg)`};
4445
transition:
4546
transform 0.25s ease-in-out,
4647
color 0.25s ease-in-out;
4748
4849
${props => sizeStyles(props)};
4950
50-
${props => retrieveComponentStyles(COMPONENT_ID, props)};
51+
${props => retrieveComponentStyles(props['data-garden-id'], props)};
5152
`;
5253

5354
StyledIcon.defaultProps = {

packages/buttons/src/styled/StyledIconButton.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,17 @@ const iconStyles = (props: IButtonProps & ThemeProps<DefaultTheme>) => {
6969
`;
7070
};
7171

72-
export const StyledIconButton = styled(StyledButton as 'button').attrs({
73-
'data-garden-id': COMPONENT_ID,
72+
export const StyledIconButton = styled(StyledButton).attrs<IButtonProps>(props => ({
73+
'data-garden-id': props['data-garden-id'] || COMPONENT_ID,
7474
'data-garden-version': PACKAGE_VERSION
75-
})<IButtonProps>`
75+
}))`
7676
${props => iconButtonStyles(props)};
7777
7878
& ${StyledIcon} {
7979
${props => iconStyles(props)}
8080
}
8181
82-
${props => retrieveComponentStyles(COMPONENT_ID, props)};
82+
${props => retrieveComponentStyles(props['data-garden-id'], props)};
8383
`;
8484

8585
StyledIconButton.defaultProps = {

packages/buttons/src/styled/StyledSplitButton.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,24 @@
77

88
import styled from 'styled-components';
99
import { DEFAULT_THEME, retrieveComponentStyles } from '@zendeskgarden/react-theming';
10+
import { ISplitButtonProps } from '../types';
1011

1112
const COMPONENT_ID = 'buttons.button_group_view';
1213

1314
/**
1415
* Accepts all `<div>` props
1516
*/
16-
export const StyledSplitButton = styled.div.attrs({
17-
'data-garden-id': COMPONENT_ID,
17+
export const StyledSplitButton = styled.div.attrs<ISplitButtonProps>(props => ({
18+
'data-garden-id': props['data-garden-id'] || COMPONENT_ID,
1819
'data-garden-version': PACKAGE_VERSION
19-
})`
20+
}))<ISplitButtonProps>`
2021
display: inline-flex;
2122
position: relative;
2223
z-index: 0;
2324
direction: ${props => props.theme.rtl && 'rtl'};
2425
white-space: nowrap;
2526
26-
${props => retrieveComponentStyles(COMPONENT_ID, props)};
27+
${props => retrieveComponentStyles(props['data-garden-id'], props)};
2728
`;
2829

2930
StyledSplitButton.defaultProps = {

packages/buttons/src/types/index.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
* found at http://www.apache.org/licenses/LICENSE-2.0.
66
*/
77

8-
import { AnchorHTMLAttributes, ButtonHTMLAttributes, SVGAttributes } from 'react';
8+
import { AnchorHTMLAttributes, ButtonHTMLAttributes, SVGAttributes, HTMLAttributes } from 'react';
99

1010
export const SIZE = ['small', 'medium', 'large'] as const;
1111

1212
export interface IButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
13+
/** @ignore Set identifier to retrieve component styles */
14+
'data-garden-id'?: string;
1315
/** Applies danger styling */
1416
isDanger?: boolean;
1517
/** Specifies the button size */
@@ -52,7 +54,7 @@ export interface IButtonIconProps
5254
SVGAttributes<SVGElement> {}
5355

5456
export interface IAnchorProps
55-
extends Pick<IButtonProps, 'isDanger'>,
57+
extends Pick<IButtonProps, 'isDanger' | 'data-garden-id'>,
5658
AnchorHTMLAttributes<HTMLAnchorElement> {
5759
/**
5860
* Attaches `target="_blank"` and `rel="noopener noreferrer"` to an anchor that
@@ -66,3 +68,7 @@ export interface IAnchorProps
6668
**/
6769
externalIconLabel?: string;
6870
}
71+
72+
export interface ISplitButtonProps
73+
extends HTMLAttributes<HTMLDivElement>,
74+
Pick<IButtonProps, 'data-garden-id'> {}

0 commit comments

Comments
 (0)