TimelineQueueButtonHeader: display only when scrolled down

This commit is contained in:
Alex Gleason 2021-10-08 14:34:23 -05:00
parent bba3564ef3
commit 4840a3c751
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
3 changed files with 69 additions and 19 deletions

View file

@ -1,8 +1,9 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { injectIntl } from 'react-intl'; import { injectIntl } from 'react-intl';
import { throttle } from 'lodash';
import classNames from 'classnames'; import classNames from 'classnames';
import SvgIcon from 'soapbox/components/svg_icon'; import Icon from 'soapbox/components/icon';
export default @injectIntl export default @injectIntl
class TimelineQueueButtonHeader extends React.PureComponent { class TimelineQueueButtonHeader extends React.PureComponent {
@ -11,25 +12,68 @@ class TimelineQueueButtonHeader extends React.PureComponent {
onClick: PropTypes.func.isRequired, onClick: PropTypes.func.isRequired,
count: PropTypes.number, count: PropTypes.number,
message: PropTypes.object.isRequired, message: PropTypes.object.isRequired,
threshold: PropTypes.number,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
}; };
static defaultProps = { static defaultProps = {
count: 0, count: 0,
threshold: 400,
}; };
state = {
scrolled: false,
}
componentDidMount() {
this.window = window;
this.documentElement = document.scrollingElement || document.documentElement;
this.attachScrollListener();
}
componentWillUnmount() {
this.detachScrollListener();
}
attachScrollListener() {
this.window.addEventListener('scroll', this.handleScroll);
}
detachScrollListener() {
this.window.removeEventListener('scroll', this.handleScroll);
}
handleScroll = throttle(() => {
const { scrollTop } = (document.scrollingElement || document.documentElement);
const { threshold } = this.props;
if (scrollTop > threshold) {
this.setState({ scrolled: true });
} else {
this.setState({ scrolled: false });
}
}, 150, { trailing: true });
render() { render() {
const { count, message, onClick, intl } = this.props; const { count, message, onClick, intl } = this.props;
const { scrolled } = this.state;
const visible = count > 0 && scrolled;
const classes = classNames('timeline-queue-header', { const classes = classNames('timeline-queue-header', {
'hidden': (count <= 0), 'hidden': !visible,
}); });
return ( return (
<div className={classes}> <div className={classes}>
<a className='timeline-queue-header__btn' onClick={onClick}> <a className='timeline-queue-header__btn' onClick={onClick}>
<SvgIcon src={require('@tabler/icons/icons/arrow-bar-to-up.svg')} /> <Icon src={require('@tabler/icons/icons/arrow-bar-to-up.svg')} />
{(count > 0) && intl.formatMessage(message, { count })} {(count > 0) && (
<div className='timeline-queue-header__label'>
{intl.formatMessage(message, { count })}
</div>
)}
</a> </a>
</div> </div>
); );

View file

@ -29,9 +29,11 @@
} }
.pinned-hosts-picker { .pinned-hosts-picker {
margin-left: 10px; padding: 10px 0 0 10px;
display: inline-flex; display: inline-flex;
flex-wrap: wrap; flex-wrap: wrap;
background: var(--foreground-color);
border-bottom: 1px solid hsla(var(--primary-text-color_hsl), 0.2);
.pinned-host { .pinned-host {
margin-right: 10px; margin-right: 10px;

View file

@ -1,35 +1,35 @@
.timeline-queue-header { .timeline-queue-header {
display: flex; display: flex;
align-self: center;
align-items: center; align-items: center;
justify-content: space-evenly; justify-content: space-evenly;
max-height: 30px; height: 30px;
position: sticky; position: fixed;
top: 60px; top: 60px;
margin: 0 auto; margin: 0 auto;
margin-bottom: 8px;
background-color: var(--brand-color); background-color: var(--brand-color);
color: #fff; color: #fff;
border-bottom: 1px solid;
border-top: 1px solid;
border-color: var(--brand-color--faint);
border-radius: 100px; border-radius: 100px;
transition: max-height 150ms ease; transition: 150ms ease;
overflow: hidden; overflow: hidden;
opacity: 1;
left: 0;
right: 0;
padding: 0 10px; padding: 0 10px;
z-index: 500; z-index: 500;
.sub-navigation ~ & {
top: calc(60px + 41px);
}
.svg-icon { .svg-icon {
margin-right: 5px; margin-right: 5px;
} }
&.hidden { &.hidden {
max-height: 0; transform: scaleY(0);
opacity: 0; pointer-events: none;
margin: 0;
border: 0; .timeline-queue-header__label {
opacity: 0;
}
} }
&__btn { &__btn {
@ -46,4 +46,8 @@
height: 46px; height: 46px;
} }
} }
&__label {
transition: 150ms ease;
}
} }