gearheads
/
mastodon
Archived
2
0
Fork 0

Make dropdown animations respect their placement (#8292)

* Make dropdown animations respect their placement

Also fix the corner radius on the privacy dropdown button when using top placement

* Fix code style issue
gh/stable
cpsdqs 2018-08-19 17:11:12 +02:00 committed by Eugen Rochko
parent 62cd097414
commit 8fe1f8d4ce
3 changed files with 34 additions and 6 deletions

View File

@ -137,7 +137,7 @@ class DropdownMenu extends React.PureComponent {
// It should not be transformed when mounting because the resulting // It should not be transformed when mounting because the resulting
// size will be used to determine the coordinate of the menu by // size will be used to determine the coordinate of the menu by
// react-overlays // react-overlays
<div className='dropdown-menu' style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}> <div className={`dropdown-menu ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}>
<div className={`dropdown-menu__arrow ${placement}`} style={{ left: arrowOffsetLeft, top: arrowOffsetTop }} /> <div className={`dropdown-menu__arrow ${placement}`} style={{ left: arrowOffsetLeft, top: arrowOffsetTop }} />
<ul> <ul>

View File

@ -28,6 +28,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
style: PropTypes.object, style: PropTypes.object,
items: PropTypes.array.isRequired, items: PropTypes.array.isRequired,
value: PropTypes.string.isRequired, value: PropTypes.string.isRequired,
placement: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
}; };
@ -119,7 +120,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
render () { render () {
const { mounted } = this.state; const { mounted } = this.state;
const { style, items, value } = this.props; const { style, items, placement, value } = this.props;
return ( return (
<Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}> <Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
@ -127,7 +128,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
// It should not be transformed when mounting because the resulting // It should not be transformed when mounting because the resulting
// size will be used to determine the coordinate of the menu by // size will be used to determine the coordinate of the menu by
// react-overlays // react-overlays
<div className='privacy-dropdown__dropdown' style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} role='listbox' ref={this.setRef}> <div className={`privacy-dropdown__dropdown ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} role='listbox' ref={this.setRef}>
{items.map(item => ( {items.map(item => (
<div role='option' tabIndex='0' key={item.value} data-index={item.value} onKeyDown={this.handleKeyDown} onClick={this.handleClick} className={classNames('privacy-dropdown__option', { active: item.value === value })} aria-selected={item.value === value} ref={item.value === value ? this.setFocusRef : null}> <div role='option' tabIndex='0' key={item.value} data-index={item.value} onKeyDown={this.handleKeyDown} onClick={this.handleClick} className={classNames('privacy-dropdown__option', { active: item.value === value })} aria-selected={item.value === value} ref={item.value === value ? this.setFocusRef : null}>
<div className='privacy-dropdown__option__icon'> <div className='privacy-dropdown__option__icon'>
@ -226,7 +227,7 @@ export default class PrivacyDropdown extends React.PureComponent {
const valueOption = this.options.find(item => item.value === value); const valueOption = this.options.find(item => item.value === value);
return ( return (
<div className={classNames('privacy-dropdown', { active: open })} onKeyDown={this.handleKeyDown}> <div className={classNames('privacy-dropdown', placement, { active: open })} onKeyDown={this.handleKeyDown}>
<div className={classNames('privacy-dropdown__value', { active: this.options.indexOf(valueOption) === 0 })}> <div className={classNames('privacy-dropdown__value', { active: this.options.indexOf(valueOption) === 0 })}>
<IconButton <IconButton
className='privacy-dropdown__value-icon' className='privacy-dropdown__value-icon'
@ -247,6 +248,7 @@ export default class PrivacyDropdown extends React.PureComponent {
value={value} value={value}
onClose={this.handleClose} onClose={this.handleClose}
onChange={this.handleChange} onChange={this.handleChange}
placement={placement}
/> />
</Overlay> </Overlay>
</div> </div>

View File

@ -230,7 +230,6 @@
.dropdown-menu { .dropdown-menu {
position: absolute; position: absolute;
transform-origin: 50% 0;
} }
.invisible { .invisible {
@ -1634,6 +1633,22 @@ a.account__display-name {
ul { ul {
list-style: none; list-style: none;
} }
&.left {
transform-origin: 100% 50%;
}
&.top {
transform-origin: 50% 100%;
}
&.bottom {
transform-origin: 50% 0;
}
&.right {
transform-origin: 0 50%;
}
} }
.dropdown-menu__arrow { .dropdown-menu__arrow {
@ -3300,7 +3315,14 @@ a.status-card {
border-radius: 4px; border-radius: 4px;
margin-left: 40px; margin-left: 40px;
overflow: hidden; overflow: hidden;
&.top {
transform-origin: 50% 100%;
}
&.bottom {
transform-origin: 50% 0; transform-origin: 50% 0;
}
} }
.privacy-dropdown__option { .privacy-dropdown__option {
@ -3372,6 +3394,10 @@ a.status-card {
} }
} }
&.top .privacy-dropdown__value {
border-radius: 0 0 4px 4px;
}
.privacy-dropdown__dropdown { .privacy-dropdown__dropdown {
display: block; display: block;
box-shadow: 2px 4px 6px rgba($base-shadow-color, 0.1); box-shadow: 2px 4px 6px rgba($base-shadow-color, 0.1);