Skip to content

Commit 2c64259

Browse files
Ming Xiaoreidmit
authored andcommitted
Bring dropdown and checkbox dropdown into PUI [#154075625]
Signed-off-by: Reid Mitchell <rmitchell@pivotal.io>
1 parent 810c40c commit 2c64259

File tree

17 files changed

+541
-444
lines changed

17 files changed

+541
-444
lines changed

spec/pivotal-ui-react/dropdown/dropdown-item_spec.js

Lines changed: 88 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,148 @@
11
import '../spec_helper';
22
import {DropdownItem} from '../../../src/react/dropdowns';
33

4-
import {findByClass, findByTag, clickOn} from '../spec_helper';
5-
64
describe('DropdownItem', () => {
7-
let result;
8-
const renderComponent = props => ReactDOM.render(
9-
<DropdownItem {...props}>DropdownItem Text</DropdownItem>, root
10-
);
11-
12-
it('passes through header', () => {
13-
result = renderComponent({header: true});
14-
expect(findByClass(result, 'dropdown-header')).toContainText('DropdownItem Text');
15-
});
5+
let subject;
166

17-
it('passes through divider', () => {
18-
result = renderComponent({divider: true});
19-
expect(findByClass(result, 'divider')).toBeDefined();
7+
beforeEach(() => {
8+
subject = ReactDOM.render(<DropdownItem>DropdownItem Text</DropdownItem>, root);
209
});
2110

22-
it('passes through className and style to the li ', () => {
23-
result = renderComponent({
24-
className: 'test-item-class',
25-
style: {opacity: '0.5'}
11+
describe('header', () => {
12+
beforeEach(() => {
13+
subject::setProps({header: true});
2614
});
2715

28-
const listItem = findByTag(result, 'li');
29-
expect(listItem).toHaveClass('test-item-class');
30-
expect(listItem).toHaveCss({opacity: '0.5'});
16+
it('passes through header', () => {
17+
expect('#root .dropdown-header').toContainText('DropdownItem Text');
18+
});
3119
});
3220

33-
it('passes through id to the anchor if an href is provided', () => {
34-
result = renderComponent({id: 'test-item-id'});
21+
describe('divider', () => {
22+
beforeEach(() => {
23+
subject::setProps({divider: true});
24+
});
3525

36-
let listItem = findByTag(result, 'li');
37-
expect(listItem).not.toHaveAttr('id');
26+
it('passes through divider', () => {
27+
expect('#root .divider').toExist();
28+
});
29+
});
3830

39-
result = renderComponent({id: 'test-item-id', href: 'test'});
31+
describe('className', () => {
32+
beforeEach(() => {
33+
subject::setProps({className: 'test-item-class'});
34+
});
4035

41-
listItem = findByTag(result, 'li');
42-
expect(listItem).not.toHaveAttr('id');
43-
expect(listItem.querySelector('a')).toHaveAttr('id', 'test-item-id');
36+
it('passes through className to the li', () => {
37+
expect('#root li').toHaveClass('test-item-class');
38+
});
4439
});
4540

46-
it('passes through href and target to the anchor', () => {
47-
result = renderComponent({href: 'test', target: '_blank'});
48-
expect(findByTag(result, 'a')).toHaveAttr('href', 'test');
49-
expect(findByTag(result, 'a')).toHaveAttr('target', '_blank');
41+
describe('style', () => {
42+
beforeEach(() => {
43+
subject::setProps({style: {opacity: '0.5'}});
44+
});
45+
46+
it('passes through style to the li', () => {
47+
expect('#root li').toHaveCss({opacity: '0.5'});
48+
});
5049
});
5150

52-
describe('onSelect handling', () => {
53-
let handleSelectSpy;
51+
describe('id', () => {
52+
beforeEach(() => {
53+
subject::setProps({id: 'test-item-id'});
54+
});
55+
5456
describe('with href', () => {
55-
it('passes through onSelect on anchor click', () => {
56-
handleSelectSpy = jasmine.createSpy('handleSelect');
57-
const eventKey = '1';
58-
result = renderComponent({href: 'test', onSelect: handleSelectSpy, eventKey});
57+
beforeEach(() => {
58+
subject::setProps({href: 'test'});
59+
});
5960

60-
clickOn(findByTag(result, 'a'));
61-
expect(handleSelectSpy).toHaveBeenCalled();
61+
it('passes through id to the anchor', () => {
62+
expect('#root li a').toHaveAttr('id', 'test-item-id');
6263
});
6364
});
6465

6566
describe('without href', () => {
66-
it('passes through onSelect on list item click', () => {
67-
handleSelectSpy = jasmine.createSpy('handleSelect');
68-
const eventKey = '1';
69-
result = renderComponent({onSelect: handleSelectSpy, eventKey});
70-
71-
clickOn(findByTag(result, 'li'));
72-
expect(handleSelectSpy).toHaveBeenCalled();
67+
it('does not pass through id to the anchor', () => {
68+
expect('#root li').not.toHaveAttr('id');
69+
expect('#root li a').not.toExist();
7370
});
7471
});
72+
});
7573

76-
describe('with disabled prop', () => {
77-
it('does not call onSelect handler', () => {
78-
handleSelectSpy = jasmine.createSpy('handleSelect');
79-
result = renderComponent({href: 'test', onSelect: handleSelectSpy, disabled: true});
74+
describe('with href and target', () => {
75+
beforeEach(() => {
76+
subject::setProps({href: 'test', target: '_blank'});
77+
});
78+
79+
it('passes through href and target to the anchor', () => {
80+
expect('#root a').toHaveAttr('href', 'test');
81+
expect('#root a').toHaveAttr('target', '_blank');
82+
});
83+
});
8084

81-
expect(findByTag(result, 'li')).toHaveClass('disabled');
82-
expect(findByTag(result, 'a')).toHaveAttr('disabled');
85+
describe('onSelect handling', () => {
86+
let handleSelectSpy;
87+
const eventKey = '1';
88+
89+
beforeEach(() => {
90+
handleSelectSpy = jasmine.createSpy('handleSelect');
91+
subject::setProps({onSelect: handleSelectSpy, eventKey});
92+
});
8393

84-
clickOn(findByTag(result, 'a'));
94+
describe('when li is clicked', () => {
95+
beforeEach(() => {
96+
$('#root li').click();
97+
});
8598

86-
expect(handleSelectSpy).not.toHaveBeenCalled();
99+
it('calls onSelect on li click', () => {
100+
expect(handleSelectSpy).toHaveBeenCalledWith(jasmine.any(Object), eventKey);
87101
});
88102
});
89103
});
90104

91105
describe('onClick handling', () => {
92106
let handleClickSpy;
93-
describe('with href', () => {
94-
it('passes through onClick on anchor click', () => {
95-
handleClickSpy = jasmine.createSpy('handleClick');
96-
result = renderComponent({href: 'test', onClick: handleClickSpy});
97107

98-
clickOn(findByTag(result, 'a'));
99-
expect(handleClickSpy).toHaveBeenCalled();
100-
});
108+
beforeEach(() => {
109+
handleClickSpy = jasmine.createSpy('handleClick');
110+
subject::setProps({onClick: handleClickSpy});
101111
});
102112

103-
describe('without href', () => {
104-
it('passes through onClick on list item click', () => {
105-
handleClickSpy = jasmine.createSpy('handleClick');
106-
result = renderComponent({onClick: handleClickSpy});
113+
describe('when li is clicked', () => {
114+
beforeEach(() => {
115+
$('#root li').click();
116+
});
107117

108-
clickOn(findByTag(result, 'li'));
109-
expect(handleClickSpy).toHaveBeenCalled();
118+
it('calls onClick on li click', () => {
119+
expect(handleClickSpy).toHaveBeenCalledWith(jasmine.any(Object));
110120
});
111121
});
112122

113123
describe('with disabled prop', () => {
114-
it('does not call onClick handler', () => {
115-
handleClickSpy = jasmine.createSpy('handleClick');
116-
result = renderComponent({href: 'test', onClick: handleClickSpy, disabled: true});
117-
118-
expect(findByTag(result, 'li')).toHaveClass('disabled');
119-
expect(findByTag(result, 'a')).toHaveAttr('disabled');
124+
beforeEach(() => {
125+
subject::setProps({href: 'test', disabled: true});
126+
});
120127

121-
clickOn(findByTag(result, 'a'));
128+
it('does not call onClick handler', () => {
129+
expect('#root li').toHaveClass('disabled');
130+
expect('#root a').toHaveAttr('disabled');
131+
$('#root a').click();
122132

123133
expect(handleClickSpy).not.toHaveBeenCalled();
124134
});
125135
});
126136
});
127137

128-
129138
describe('when an a tag is passed in as a child', () => {
130139
beforeEach(() => {
131-
result = ReactDOM.render(
140+
subject = ReactDOM.render(
132141
<DropdownItem><a href="custom">link</a></DropdownItem>, root
133142
);
134143

135144
it('renders the child link', () => {
136-
const listItem = findByTag(result, 'li');
137-
expect(listItem.querySelector('a')).toHaveAttr('id', 'custom');
145+
expect('#root li a').toHaveAttr('id', 'custom');
138146
});
139147
});
140148
});

spec/pivotal-ui-react/dropdown/dropdown_spec.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ describe('Dropdown', () => {
2727
});
2828

2929
it('correctly styles the dropdown-toggle, and adds a chevron icon', () => {
30-
expect('.dropdown-toggle').toHaveText('Dropping');
31-
expect('.dropdown-toggle').toHaveClass('test-btn-class');
32-
expect('.dropdown-toggle').toHaveAttr('aria-haspopup', 'true');
33-
expect('.dropdown-toggle').toHaveAttr('aria-label', 'Nessun Dorma');
30+
expect('.dropdown button').toHaveText('Dropping');
31+
expect('.dropdown button').toHaveClass('test-btn-class');
32+
expect('.dropdown button').toHaveAttr('aria-haspopup', 'true');
33+
expect('.dropdown button').toHaveAttr('aria-label', 'Nessun Dorma');
3434

3535
expect('.icon-chevron_down').toExist();
3636
});

spec/pivotal-ui-react/notification/notification_spec.js renamed to spec/pivotal-ui-react/notifications/notifications_spec.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import '../spec_helper';
22
import {Notifications, NotificationItem, AlertNotifications} from '../../../src/react/notifications';
33

4-
5-
describe('Notification', () => {
4+
describe('Notifications', () => {
65
const props = {
76
className: 'test-class',
87
id: 'test-id',

src/css/buttons/buttons.scss

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,7 @@
3535
&:hover,
3636
&:focus,
3737
&:hover:focus {
38-
3938
outline: none;
40-
.icon {
41-
42-
}
4339
}
4440

4541
// Button Content Rules

src/css/dropdowns/dropdown-flat.scss

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
@import "../pui-variables";
2+
3+
.dropdown.dropdown-flat {
4+
5+
.dropdown-toggle {
6+
border: 1px solid transparent;
7+
background-color: transparent;
8+
text-transform: uppercase;
9+
color: $btn-default-color;
10+
font-weight: $btn-font-weight;
11+
letter-spacing: $btn-letter-spacing;
12+
}
13+
14+
&.dropdown-open {
15+
.dropdown-toggle {
16+
border: 1px solid transparent;
17+
}
18+
}
19+
}

src/css/dropdowns/dropdown-lg.scss

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
@import "../pui-variables";
2+
3+
.dropdown.dropdown-lg {
4+
.dropdown-icon-col {
5+
height: 40px;
6+
7+
.dropdown-toggle {
8+
width: 40px;
9+
}
10+
}
11+
12+
.dropdown-toggle {
13+
height: ($base-unit*5);
14+
line-height: ($base-unit*5) - 2px;
15+
font-size: 16px;
16+
}
17+
18+
a.dropdown-label {
19+
height: ($base-unit*5);
20+
line-height: ($base-unit*5) - 2px;
21+
font-size: 16px;
22+
}
23+
24+
.dropdown-menu {
25+
li {
26+
padding: $base-unit;
27+
line-height: 24px;
28+
font-size: 16px;
29+
}
30+
}
31+
32+
&.dropdown-split .dropdown-toggle {
33+
width: 40px;
34+
}
35+
36+
.icon-toggle {
37+
font-size: 20px;
38+
}
39+
40+
&.dropdown-icon-only:not(.dropdown-split) {
41+
width: 40px;
42+
}
43+
}

src/css/dropdowns/dropdown-link.scss

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
@import "../pui-variables";
2+
3+
.dropdown.dropdown-link {
4+
width: initial;
5+
white-space: nowrap;
6+
7+
.dropdown-toggle, .dropdown-icon-col {
8+
border: 1px solid transparent;
9+
color: $link-color;
10+
background-color: transparent;
11+
}
12+
13+
.icon-toggle svg {
14+
fill: $link-color;
15+
}
16+
}

src/css/dropdowns/dropdown-sm.scss

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
@import "../pui-variables";
2+
3+
.dropdown.dropdown-sm {
4+
.dropdown-icon-col {
5+
height: 24px;
6+
}
7+
8+
.dropdown-toggle {
9+
height: ($base-unit*3);
10+
line-height: ($base-unit*3) - 2px;
11+
font-size: 12px;
12+
}
13+
14+
a.dropdown-label {
15+
height: ($base-unit*3);
16+
line-height: ($base-unit*3) - 2px;
17+
font-size: 12px;
18+
}
19+
20+
.dropdown-menu {
21+
li {
22+
padding: $base-unit;
23+
line-height: 16px;
24+
font-size: 12px;
25+
}
26+
}
27+
28+
&.dropdown-split .dropdown-toggle {
29+
width: 24px;
30+
padding: 11px;
31+
}
32+
33+
.icon-toggle {
34+
font-size: 14px;
35+
}
36+
37+
&.dropdown-icon-only:not(.dropdown-split) {
38+
width: 24px;
39+
}
40+
}

0 commit comments

Comments
 (0)