Skip to content
This repository was archived by the owner on Oct 23, 2024. It is now read-only.

Commit 559b567

Browse files
committed
Update padding logic for sm/xs button
1 parent 8b55ff8 commit 559b567

File tree

3 files changed

+204
-7
lines changed

3 files changed

+204
-7
lines changed

src/components/Button/Button.style.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ export const ButtonStyled = styled.button<any>`
5959

6060
const sizePads = {
6161
xxs: 0.125,
62-
xs: 0.25,
63-
sm: 0.5,
62+
xs: 0.3125,
63+
sm: 0.625,
6464
md: 0.75,
6565
lg: 1,
6666
xl: 1.25,
@@ -134,24 +134,46 @@ function buttonMotion({ theme }) {
134134

135135
function buttonPadding({ icon, iconOnly, iconPosition, size }) {
136136
return (
137-
!iconOnly && iconButtonPadding(icon, iconPosition, sizePads[size])
137+
!iconOnly &&
138+
iconButtonPadding(icon, iconPosition, sizePads[size], size)
138139
);
139140
}
140141

141-
function iconButtonPadding(icon, iconPosition, pad) {
142+
function iconButtonPadding(icon, iconPosition, pad, size) {
142143
const minHeight = rem(3);
143144
const minWidth = `${pad * 4 + 2}rem`;
144145

146+
// Some button sizes are "off" the padding formula based on design decions
147+
const sizeAdjustments = {
148+
xxs: { left: 0, right: 0 },
149+
xs: { left: 0.065, right: 0.19125 },
150+
sm: { left: -0.125, right: -0.125 },
151+
md: { left: 0, right: 0 },
152+
lg: { left: 0, right: 0 },
153+
xl: { left: 0, right: 0 },
154+
xxl: { left: 0, right: 0 },
155+
};
156+
145157
switch (icon && iconPosition) {
146158
case 'left':
147159
return {
148-
padding: '0 ' + pad + 'rem',
160+
padding:
161+
'0 ' +
162+
(pad + sizeAdjustments[size].right) +
163+
'rem 0 ' +
164+
(pad + sizeAdjustments[size].left) +
165+
'rem',
149166
minHeight,
150167
minWidth,
151168
};
152169
case 'right':
153170
return {
154-
padding: '0 ' + pad + 'rem',
171+
padding:
172+
'0 ' +
173+
(pad + sizeAdjustments[size].right) +
174+
'rem 0 ' +
175+
(pad + sizeAdjustments[size].left) +
176+
'rem',
155177
minHeight,
156178
minWidth,
157179
};
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import '@testing-library/jest-dom';
2+
import {
3+
fireEvent,
4+
render,
5+
RenderOptions,
6+
screen,
7+
} from '@testing-library/react';
8+
import React, { ReactElement } from 'react';
9+
10+
import { ThemeProvider } from 'styled-components';
11+
import { Pencil } from '../../icons';
12+
import { themes } from '../../themes';
13+
import { Button } from './Button';
14+
15+
const Provider = ({ children }) => {
16+
return (
17+
<ThemeProvider theme={themes['light']}>{children}</ThemeProvider>
18+
);
19+
};
20+
21+
const renderWithThemeProvider = (
22+
ui: ReactElement,
23+
options?: Omit<RenderOptions, 'wrapper'>
24+
) => render(ui, { wrapper: Provider, ...options });
25+
26+
describe('Button', () => {
27+
it('Renders button', () => {
28+
renderWithThemeProvider(<Button />);
29+
const button = screen.getByRole('button');
30+
expect(button).toBeInTheDocument();
31+
});
32+
33+
it('Calls onClick handler when clicked', () => {
34+
const handleClick = jest.fn();
35+
const { getByText } = renderWithThemeProvider(
36+
<Button onClick={handleClick}>Click me</Button>
37+
);
38+
const buttonElement = getByText('Click me');
39+
fireEvent.click(buttonElement);
40+
expect(handleClick).toHaveBeenCalledTimes(1);
41+
});
42+
43+
it('Renders button with text child', () => {
44+
const text = 'Click me';
45+
46+
const { getByText } = renderWithThemeProvider(
47+
<Button>{text}</Button>
48+
);
49+
50+
const buttonElement = getByText(text);
51+
expect(buttonElement).toBeInTheDocument();
52+
});
53+
54+
it('Renders button with icon', () => {
55+
renderWithThemeProvider(<Button icon={<Pencil />} />);
56+
const button = screen.getByRole('button');
57+
expect(button.innerHTML).toContain('svg');
58+
});
59+
60+
it('Renders button with icon on the right', () => {
61+
renderWithThemeProvider(
62+
<Button icon={<Pencil />} iconPosition="right">
63+
Hello
64+
</Button>
65+
);
66+
67+
const button = screen.getByRole('button');
68+
expect(button.children[0].tagName.toLocaleLowerCase()).toBe(
69+
'span'
70+
);
71+
});
72+
73+
it('Renders loader', () => {
74+
renderWithThemeProvider(<Button loading />);
75+
const button = screen.getByRole('button');
76+
expect(button.innerHTML).toContain('Loader');
77+
});
78+
79+
it('Sets color of a button', () => {
80+
const color = '#CCCCCC';
81+
renderWithThemeProvider(<Button color={color} />);
82+
const button = screen.getByRole('button');
83+
expect(button).toHaveStyle({ background: color });
84+
});
85+
86+
it('Changes size of a button', () => {
87+
const { rerender } = renderWithThemeProvider(
88+
<Button size="sm" />
89+
);
90+
const button = screen.getByRole('button');
91+
expect(button).toHaveStyle({ fontSize: '0.875rem' });
92+
93+
rerender(<Button size="md" />);
94+
expect(button).toHaveStyle({ fontSize: '0.875rem' });
95+
96+
rerender(<Button size="xs" />);
97+
expect(button).toHaveStyle({ fontSize: '0.75rem' });
98+
99+
rerender(<Button size="lg" />);
100+
expect(button).toHaveStyle({ fontSize: '1rem' });
101+
102+
rerender(<Button size="xl" />);
103+
expect(button).toHaveStyle({ fontSize: '1.125rem' });
104+
});
105+
106+
it('Changes status of a button', () => {
107+
const { rerender } = renderWithThemeProvider(
108+
<Button status="positive" />
109+
);
110+
const button = screen.getByRole('button');
111+
expect(button).toHaveStyle({
112+
background: '#28A878',
113+
});
114+
115+
rerender(<Button status="negative" />);
116+
expect(button).toHaveStyle({ background: '#E22B12' });
117+
});
118+
119+
it('Changes format of a button', () => {
120+
const { rerender } = renderWithThemeProvider(
121+
<Button format="secondary" />
122+
);
123+
const button = screen.getByRole('button');
124+
expect(button).toHaveStyle({
125+
background: '#efefef',
126+
});
127+
128+
rerender(<Button format="soft" />);
129+
expect(button).toHaveStyle({ background: '#23313b' });
130+
});
131+
132+
it('Changes variant of a button', () => {
133+
const { rerender } = renderWithThemeProvider(
134+
<Button variant="dashed" />
135+
);
136+
const button = screen.getByRole('button');
137+
expect(button).toHaveStyle({
138+
borderStyle: 'dashed',
139+
});
140+
141+
rerender(<Button variant="hyperminimal" />);
142+
expect(button).toHaveStyle({ borderColor: 'transparent' });
143+
});
144+
145+
it('Changes element of a button', () => {
146+
const { rerender, container } = renderWithThemeProvider(
147+
<Button element="a" />
148+
);
149+
const buttonAnchor = container.querySelector('a');
150+
expect(buttonAnchor).toBeInTheDocument();
151+
152+
rerender(<Button element="span" />);
153+
const buttonSpan = container.querySelector('span');
154+
expect(buttonSpan).toBeInTheDocument();
155+
156+
const button = container.querySelector('button');
157+
expect(button).not.toBeInTheDocument();
158+
});
159+
160+
it('Renders pill button', () => {
161+
renderWithThemeProvider(<Button pill>Hello</Button>);
162+
const button = screen.getByRole('button');
163+
164+
expect(button).toHaveStyle({
165+
borderRadius: '2rem',
166+
});
167+
});
168+
169+
it('Renders disabled button', () => {
170+
renderWithThemeProvider(<Button disabled>Hello</Button>);
171+
const button = screen.getByRole('button');
172+
173+
expect(button).toHaveAttribute('disabled');
174+
});
175+
});

src/components/Button/Button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ function ButtonComponent({
111111
/>
112112
)}
113113

114-
<Focus parent={ButtonStyled} radius={radius} />
114+
<Focus parent={ButtonStyled} radius={radius} isKeyboardOnly />
115115
</ButtonStyled>
116116
);
117117
}

0 commit comments

Comments
 (0)