Skip to content

Commit a9b8b6c

Browse files
author
Vic G
authored
Merge pull request #1523 from maxceem/issue-1497
Issue #1497 - Dropdown menu doesn't take viewport bounds into consideration.
2 parents 7067e7e + 433b29e commit a9b8b6c

File tree

2 files changed

+68
-41
lines changed

2 files changed

+68
-41
lines changed

src/components/ProjectStatus/ProjectStatus.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ $status-height: 20px;
178178
z-index: 2;
179179
transition: 250ms all;
180180

181+
&.dropdown-up {
182+
top: auto;
183+
bottom: 0;
184+
}
185+
181186
.status-header {
182187
@include roboto-medium;
183188
font-size: $tc-label-md;

src/components/ProjectStatus/editableProjectStatus.js

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,68 @@ import {
1111
PROJECT_STATUS_CANCELLED
1212
} from '../../config/constants'
1313

14+
const hocStatusDropdown = (CompositeComponent) => {
15+
class StatusDropdown extends Component {
16+
shouldDropdownUp() {
17+
if (this.refs.dropdown) {
18+
const bounds = this.refs.dropdown.getBoundingClientRect()
19+
const windowHeight = window.innerHeight
20+
21+
return bounds.top > windowHeight / 2
22+
}
23+
24+
return false
25+
}
26+
27+
render() {
28+
const { canEdit, isOpen, handleClick, onItemSelect, showText, withoutLabel, unifiedHeader, status } = this.props
29+
const selected = PROJECT_STATUS.filter((opt) => opt.value === status)[0]
30+
31+
this.shouldDropdownUp()
32+
return (
33+
<div className="project-status-dropdown" ref="dropdown">
34+
<div
35+
className={cn('status-header', 'ps-' + selected.value, { active: isOpen, editable: canEdit })}
36+
onClick={handleClick}
37+
>
38+
<CompositeComponent
39+
status={selected}
40+
showText={showText}
41+
withoutLabel={withoutLabel}
42+
unifiedHeader={unifiedHeader}
43+
/>
44+
{ canEdit && <i className="caret" ><SVGIconImage filePath="arrow-9px-carret-down-normal" /></i> }
45+
</div>
46+
{ isOpen && canEdit &&
47+
<div className={cn('status-dropdown', { 'dropdown-up': this.shouldDropdownUp() })}>
48+
<div className="status-header">Project Status</div>
49+
<ul>
50+
{
51+
PROJECT_STATUS.map((item) =>
52+
<li key={item.value}>
53+
<a
54+
href="javascript:"
55+
className={cn('status-option', 'ps-' + item.value, { active: item.value === status })}
56+
onClick={(e) => {
57+
onItemSelect(item.value, e)
58+
}}
59+
>
60+
<ProjectStatus status={item} showText />
61+
</a>
62+
</li>
63+
)
64+
}
65+
</ul>
66+
</div>
67+
}
68+
</div>
69+
)
70+
}
71+
}
72+
73+
return StatusDropdown
74+
}
75+
1476
const editableProjectStatus = (CompositeComponent) => class extends Component {
1577
constructor(props) {
1678
super(props)
@@ -56,50 +118,10 @@ const editableProjectStatus = (CompositeComponent) => class extends Component {
56118
this.setState({ statusChangeReason : _.get(reason, 'value') })
57119
}
58120

59-
renderDropdown(props) {
60-
const { canEdit, isOpen, handleClick, onItemSelect, showText, withoutLabel, unifiedHeader, status } = props
61-
const selected = PROJECT_STATUS.filter((opt) => opt.value === status)[0]
62-
return (
63-
<div className="project-status-dropdown">
64-
<div className={cn('status-header', 'ps-' + selected.value, { active: isOpen, editable: canEdit })} onClick={handleClick}>
65-
<CompositeComponent
66-
status={selected}
67-
showText={showText}
68-
withoutLabel={withoutLabel}
69-
unifiedHeader={unifiedHeader}
70-
/>
71-
{ canEdit && <i className="caret" ><SVGIconImage filePath="arrow-9px-carret-down-normal" /></i> }
72-
</div>
73-
{ isOpen && canEdit &&
74-
<div className="status-dropdown">
75-
<div className="status-header">Project Status</div>
76-
<ul>
77-
{
78-
PROJECT_STATUS.map((item) =>
79-
<li key={item.value}>
80-
<a
81-
href="javascript:"
82-
className={cn('status-option', 'ps-' + item.value, { active: item.value === status })}
83-
onClick={(e) => {
84-
onItemSelect(item.value, e)
85-
}}
86-
>
87-
<ProjectStatus status={item} showText />
88-
</a>
89-
</li>
90-
)
91-
}
92-
</ul>
93-
</div>
94-
}
95-
</div>
96-
)
97-
}
98-
99121
render() {
100122
const { showStatusChangeDialog, newStatus, statusChangeReason } = this.state
101123
const { canEdit } = this.props
102-
const ProjectStatusDropdown = canEdit ? enhanceDropdown(this.renderDropdown) : this.renderDropdown
124+
const ProjectStatusDropdown = canEdit ? enhanceDropdown(hocStatusDropdown(CompositeComponent)) : hocStatusDropdown(CompositeComponent)
103125
return (
104126
<div className={cn('panel', 'EditableProjectStatus', {'modal-active': showStatusChangeDialog})}>
105127
<div className="modal-overlay"></div>

0 commit comments

Comments
 (0)