Skip to content

Commit dfd65e6

Browse files
committed
feat: new DropdownMenu component
1 parent cd1ee71 commit dfd65e6

27 files changed

Lines changed: 2739 additions & 80 deletions

File tree

src/components/Accordion/__snapshots__/index.spec.jsx.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ exports[`<Accordion /> should have default props 1`] = `
1919
data-test-selector="panel-1"
2020
data-testid="panel-wrapper"
2121
>
22-
<div
22+
<button
2323
class="panel-component-header clearfix"
2424
data-testid="panel-header"
2525
>
2626
Panel 1
27-
</div>
27+
</button>
2828
<div
2929
class="panel-component-content-wrapper animate"
3030
style="height: 0px;"

src/components/Button/index.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ export type ButtonVariant = 'solid' | 'borderless' | 'inverse' | 'link';
66

77
export type ButtonSize = 'medium' | 'large';
88

9+
export type ButtonIconPosition = 'left' | 'right';
10+
911
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
1012
isLoading?: boolean;
1113
color?: ButtonColor;
1214
variant?: ButtonVariant;
1315
size?: ButtonSize;
16+
iconPosition?: ButtonIconPosition;
1417
/**
1518
* @deprecated
1619
* Please use the `color` prop instead.

src/components/Button/index.jsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const buttonSharedClasses = ({ size, inverse, variant, fullWidth, round,
1717
disabled: disabled,
1818
});
1919

20-
const Button = (props) => {
20+
const Button = React.forwardRef((props, ref) => {
2121
const {
2222
color = 'default',
2323
size,
@@ -30,6 +30,7 @@ const Button = (props) => {
3030
disabled,
3131
dts,
3232
isLoading,
33+
iconPosition = 'left',
3334
inverse, // deprecated
3435
theme, // deprecated
3536
...rest
@@ -68,9 +69,12 @@ const Button = (props) => {
6869
<Spinner size={size === 'large' ? 'medium' : 'small'} />
6970
</div>
7071
) : null;
71-
72+
const renderIcon = () => (
73+
<span className={classNames('aui-icon-container', { 'is-loading': isLoading && !round })}>{icon}</span>
74+
);
7275
return (
7376
<button
77+
ref={ref}
7478
data-testid="button-wrapper"
7579
type="button"
7680
{...expandDts(dts)}
@@ -81,27 +85,28 @@ const Button = (props) => {
8185
{renderSpinner()}
8286
{
8387
<>
84-
{icon && (
85-
<span className={classNames('aui-icon-container', { 'is-loading': isLoading && !round })}>{icon}</span>
86-
)}
88+
{icon && iconPosition === 'left' && renderIcon()}
8789
{children && (
8890
<span className={classNames('aui-children-container', { 'is-loading': isLoading })}>{children}</span>
8991
)}
92+
{icon && iconPosition === 'right' && renderIcon()}
9093
</>
9194
}
9295
</button>
9396
);
94-
};
97+
});
9598

9699
export const colors = ['default', 'primary', 'secondary', 'success', 'danger', 'warning', 'info'];
97100
export const variants = ['solid', 'borderless', 'inverse', 'link'];
98101
export const sizes = ['medium', 'large'];
102+
export const positions = ['left', 'right'];
99103

100104
Button.propTypes = {
101105
isLoading: PropTypes.bool,
102106
color: PropTypes.oneOf(colors),
103107
variant: PropTypes.oneOf(variants),
104108
size: PropTypes.oneOf(sizes),
109+
iconPosition: PropTypes.oneOf(positions),
105110
/**
106111
* @deprecated
107112
* Please use the `color` prop instead.
@@ -121,4 +126,6 @@ Button.propTypes = {
121126
children: PropTypes.node,
122127
};
123128

129+
Button.displayName = 'Button';
130+
124131
export default Button;

src/components/Button/styles.css

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ $color-secondary-active: $color-teal-700;
9595
border-color: $color-primary-strong;
9696
}
9797

98-
&:active {
98+
&:active,
99+
&.active {
99100
color: $color-text-inverse;
100101
background-color: $color-primary-active;
101102
border-color: $color-primary-active;
@@ -113,7 +114,8 @@ $color-secondary-active: $color-teal-700;
113114
border-color: $color-secondary-strong;
114115
}
115116

116-
&:active {
117+
&:active,
118+
&.active {
117119
color: $color-text-inverse;
118120
background-color: $color-secondary-active;
119121
border-color: $color-secondary-active;
@@ -131,7 +133,8 @@ $color-secondary-active: $color-teal-700;
131133
border-color: $color-success-strong;
132134
}
133135

134-
&:active {
136+
&:active,
137+
&.active {
135138
color: $color-text-inverse;
136139
background-color: $color-success-active;
137140
border-color: $color-success-active;
@@ -149,7 +152,8 @@ $color-secondary-active: $color-teal-700;
149152
border-color: $color-info-strong;
150153
}
151154

152-
&:active {
155+
&:active,
156+
&.active {
153157
color: $color-text-inverse;
154158
background-color: $color-info-active;
155159
border-color: $color-info-active;
@@ -167,7 +171,8 @@ $color-secondary-active: $color-teal-700;
167171
border-color: $color-warning-strong;
168172
}
169173

170-
&:active {
174+
&:active,
175+
&.active {
171176
color: $color-text-inverse;
172177
background-color: $color-warning-active;
173178
border-color: $color-warning-active;
@@ -185,7 +190,8 @@ $color-secondary-active: $color-teal-700;
185190
border-color: $color-danger-strong;
186191
}
187192

188-
&:active {
193+
&:active,
194+
&.active {
189195
color: $color-text-inverse;
190196
background-color: $color-danger-active;
191197
border-color: $color-danger-active;
@@ -206,7 +212,8 @@ $color-secondary-active: $color-teal-700;
206212
border-color: $color-grey-500;
207213
}
208214

209-
&:active {
215+
&:active,
216+
&.active {
210217
color: $color-text-inverse;
211218
background-color: $color-grey-400;
212219
border-color: $color-grey-500;
@@ -227,7 +234,8 @@ $color-secondary-active: $color-teal-700;
227234
border-color: $color-grey-500;
228235
}
229236

230-
&:active {
237+
&:active,
238+
&.active {
231239
background-color: $color-default-active;
232240
border-color: $color-grey-500;
233241
}

src/components/ButtonGroup/index.jsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ import _ from 'lodash';
22
import React from 'react';
33
import PropTypes from 'prop-types';
44
import Button from '../Button';
5+
import DropdownMenu from '../DropdownMenu';
56
import { expandDts } from '../../utils';
67
import './styles.css';
78

9+
const buttonNames = [Button.displayName, DropdownMenu.Trigger.displayName];
10+
811
class ButtonGroup extends React.PureComponent {
912
injectProps(children) {
1013
return React.Children.map(children, (child) => {
@@ -16,18 +19,18 @@ class ButtonGroup extends React.PureComponent {
1619
...(this.props.size ? { size: this.props.size } : {}),
1720
};
1821

19-
const childNodes = React.Children.map(child.props.children, (childNode) =>
20-
React.isValidElement(childNode)
22+
const childNodes = React.Children.map(child.props.children, (childNode) => {
23+
return React.isValidElement(childNode)
2124
? React.cloneElement(childNode, {
2225
...childNode.props,
23-
...(childNode.type.name === Button.name ? buttonProps : {}),
26+
...(buttonNames.includes(childNode.type.displayName) ? buttonProps : {}),
2427
})
25-
: childNode
26-
);
28+
: childNode;
29+
});
2730

2831
return React.cloneElement(child, {
2932
...child.props,
30-
...(child.type.name === Button.name ? buttonProps : {}),
33+
...(buttonNames.includes(child.type.displayName) ? buttonProps : {}),
3134
...(!_.isEmpty(childNodes) ? { children: childNodes.length === 1 ? childNodes[0] : childNodes } : {}),
3235
});
3336
}

src/components/ButtonGroup/index.spec.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,12 @@ describe('<ButtonGroup />', () => {
4242
const { getByTestId } = render(
4343
<ButtonGroup disabled size="large">
4444
<div>
45-
<div>foo</div>
45+
<div data-testid="foo">foo</div>
4646
<Button color="primary">Test1</Button>
4747
</div>
4848
</ButtonGroup>
4949
);
50+
expect(getByTestId('foo')).toBeEnabled();
5051
expect(getByTestId('button-wrapper')).toBeDisabled();
5152
expect(getByTestId('button-wrapper')).toHaveClass('aui-large');
5253
});

src/components/Checkbox/index.d.ts

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,12 @@
11
import * as React from 'react';
22

3+
export type CheckboxValue = string | number;
4+
35
export type CheckboxVariant = 'default' | 'box';
46

57
export type CheckboxChecked = boolean | 'partial';
68

7-
export type CheckboxValue = string | number;
8-
99
export interface CheckboxProps {
10-
/**
11-
* name for the checkbox input
12-
*/
13-
name?: string;
14-
variant?: CheckboxVariant;
15-
/**
16-
* @function onChange called when checkBox onChange event is fired
17-
* @param {string|boolean} nextState - the checked state
18-
* @param {string} name - the checkbox name
19-
* @param {string|number} value - the checkbox value
20-
*/
21-
onChange?: (...args: any[]) => any;
22-
onKeyDown?: (...args: any[]) => any;
23-
/**
24-
* checked status of the input checkBox: oneOf([true, false, 'partial']
25-
*/
26-
checked?: CheckboxChecked;
27-
/**
28-
* @deprecated
29-
*/
30-
size?: number;
31-
/**
32-
* @deprecated
33-
*/
34-
inline?: boolean;
3510
/**
3611
* checkBox input value
3712
*/
@@ -61,6 +36,31 @@ export interface CheckboxProps {
6136
* determines if the checkbox is disabled
6237
*/
6338
disabled?: boolean;
39+
/**
40+
* name for the checkbox input
41+
*/
42+
name?: string;
43+
variant?: CheckboxVariant;
44+
/**
45+
* @function onChange called when checkBox onChange event is fired
46+
* @param {string|boolean} nextState - the checked state
47+
* @param {string} name - the checkbox name
48+
* @param {string|number} value - the checkbox value
49+
*/
50+
onChange?: (...args: any[]) => any;
51+
onKeyDown?: (...args: any[]) => any;
52+
/**
53+
* checked status of the input checkBox: oneOf([true, false, 'partial']
54+
*/
55+
checked?: CheckboxChecked;
56+
/**
57+
* @deprecated
58+
*/
59+
size?: number;
60+
/**
61+
* @deprecated
62+
*/
63+
inline?: boolean;
6464
}
6565

6666
declare const Checkbox: React.FC<CheckboxProps>;

src/components/Checkbox/index.jsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ const Checkbox = ({
4949

5050
return (
5151
<div
52+
role="checkbox"
5253
{...rest}
5354
data-testid="checkbox"
54-
role="checkbox"
5555
aria-disabled={disabled ? 'true' : undefined}
5656
aria-checked={checked === 'partial' ? 'mixed' : ariaChecked}
5757
className={classnames(
@@ -135,8 +135,7 @@ export const shareCheckboxPropTypes = {
135135
disabled: PropTypes.bool,
136136
};
137137

138-
Checkbox.propTypes = {
139-
...shareCheckboxPropTypes,
138+
export const checkboxPropTypes = {
140139
/**
141140
* name for the checkbox input
142141
*/
@@ -164,4 +163,9 @@ Checkbox.propTypes = {
164163
inline: PropTypes.bool,
165164
};
166165

166+
Checkbox.propTypes = {
167+
...shareCheckboxPropTypes,
168+
...checkboxPropTypes,
169+
};
170+
167171
export default Checkbox;

src/components/CheckboxGroup/index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ export type CheckboxGroupOrientation = 'vertical' | 'horizontal';
5252
export type CheckboxGroupVariant = 'default' | 'box';
5353

5454
export interface CheckboxGroupProps {
55-
value?: any[];
56-
name?: string;
55+
value: any[];
56+
name: string;
5757
/**
5858
* @function onChange
5959
* @param {array} newValue - the new checkboxGroup value

src/components/CheckboxGroup/index.jsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ const CheckboxGroupAll = ({ className, label = 'All', values, ...rest }) => {
4949
/>
5050
);
5151
};
52-
53-
CheckboxGroupAll.propTypes = {
52+
export const checkboxGroupAllPropTypes = {
5453
label: PropTypes.node,
5554
className: PropTypes.string,
5655
/**
@@ -59,6 +58,10 @@ CheckboxGroupAll.propTypes = {
5958
values: PropTypes.array.isRequired,
6059
};
6160

61+
CheckboxGroupAll.propTypes = {
62+
...checkboxGroupAllPropTypes,
63+
};
64+
6265
const CheckboxGroup = ({
6366
name,
6467
value,
@@ -98,9 +101,9 @@ const CheckboxGroup = ({
98101
);
99102
};
100103

101-
CheckboxGroup.propTypes = {
102-
value: PropTypes.array,
103-
name: PropTypes.string,
104+
export const checkboxGroupPropTypes = {
105+
value: PropTypes.array.isRequired,
106+
name: PropTypes.string.isRequired,
104107
/**
105108
* @function onChange
106109
* @param {array} newValue - the new checkboxGroup value
@@ -131,5 +134,8 @@ CheckboxGroup.Item = CheckboxGroupItem;
131134
CheckboxGroup.All = CheckboxGroupAll;
132135

133136
export { useCheckboxGroup } from './CheckboxGroupContext';
137+
CheckboxGroup.propTypes = {
138+
...checkboxGroupPropTypes,
139+
};
134140

135141
export default CheckboxGroup;

0 commit comments

Comments
 (0)