about summary refs log tree commit diff
path: root/app/javascript/mastodon/features/ui/components/column.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/mastodon/features/ui/components/column.jsx')
-rw-r--r--app/javascript/mastodon/features/ui/components/column.jsx72
1 files changed, 72 insertions, 0 deletions
diff --git a/app/javascript/mastodon/features/ui/components/column.jsx b/app/javascript/mastodon/features/ui/components/column.jsx
new file mode 100644
index 000000000..7bc2f7e00
--- /dev/null
+++ b/app/javascript/mastodon/features/ui/components/column.jsx
@@ -0,0 +1,72 @@
+import React from 'react';
+import ColumnHeader from './column_header';
+import PropTypes from 'prop-types';
+import { debounce } from 'lodash';
+import { scrollTop } from '../../../scroll';
+import { isMobile } from '../../../is_mobile';
+
+export default class Column extends React.PureComponent {
+
+  static propTypes = {
+    heading: PropTypes.string,
+    icon: PropTypes.string,
+    children: PropTypes.node,
+    active: PropTypes.bool,
+    hideHeadingOnMobile: PropTypes.bool,
+  };
+
+  handleHeaderClick = () => {
+    const scrollable = this.node.querySelector('.scrollable');
+
+    if (!scrollable) {
+      return;
+    }
+
+    this._interruptScrollAnimation = scrollTop(scrollable);
+  };
+
+  scrollTop () {
+    const scrollable = this.node.querySelector('.scrollable');
+
+    if (!scrollable) {
+      return;
+    }
+
+    this._interruptScrollAnimation = scrollTop(scrollable);
+  }
+
+
+  handleScroll = debounce(() => {
+    if (typeof this._interruptScrollAnimation !== 'undefined') {
+      this._interruptScrollAnimation();
+    }
+  }, 200);
+
+  setRef = (c) => {
+    this.node = c;
+  };
+
+  render () {
+    const { heading, icon, children, active, hideHeadingOnMobile } = this.props;
+
+    const showHeading = heading && (!hideHeadingOnMobile || (hideHeadingOnMobile && !isMobile(window.innerWidth)));
+
+    const columnHeaderId = showHeading && heading.replace(/ /g, '-');
+    const header = showHeading && (
+      <ColumnHeader icon={icon} active={active} type={heading} onClick={this.handleHeaderClick} columnHeaderId={columnHeaderId} />
+    );
+    return (
+      <div
+        ref={this.setRef}
+        role='region'
+        aria-labelledby={columnHeaderId}
+        className='column'
+        onScroll={this.handleScroll}
+      >
+        {header}
+        {children}
+      </div>
+    );
+  }
+
+}