From 15709040e7b5c821ea04fdca76b4a4df05771a28 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 18 Jan 2019 15:07:11 -0700 Subject: [PATCH] Make tabs be their own panels --- res/css/structures/_TabbedView.scss | 42 +++---- res/themes/dharma/css/_dharma.scss | 10 +- res/themes/light/css/_base.scss | 10 +- src/components/structures/TabbedView.js | 103 ++++-------------- .../views/dialogs/UserSettingsDialog.js | 7 +- 5 files changed, 46 insertions(+), 126 deletions(-) diff --git a/res/css/structures/_TabbedView.scss b/res/css/structures/_TabbedView.scss index 7d42823d17..81a3af06a9 100644 --- a/res/css/structures/_TabbedView.scss +++ b/res/css/structures/_TabbedView.scss @@ -1,5 +1,6 @@ /* Copyright 2017 Travis Ralston +Copyright 2019 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,40 +21,22 @@ limitations under the License. display: flex; width: 100%; height: 100%; - background-color: $tab-panel-bg-color; } .mx_TabbedView_tabLabels { - width: 300px; + width: 136px; height: 100%; - background-color: $tab-list-bg-color; - color: $tab-list-fg-color; - border-right: 1px solid $tab-border-color; - border-left: 1px solid $tab-border-color; -} - -.mx_TabbedView_tabPanels { - width: calc(100% - 320px); - display: inline-block; - height: 100%; - padding-left: 20px; - scroll-snap-type: block; + color: $tab-label-fg-color; } .mx_TabbedView_tabLabel { - text-align: center; vertical-align: middle; - text-transform: uppercase; cursor: pointer; display: block; - padding: 20px; - width: calc(100% - 40px); - border-bottom: 1px solid $tab-border-color; -} - -.mx_TabbedView_exit { - padding-top: 10px; - padding-bottom: 10px; + border-radius: 3px; + font-size: 12px; + font-weight: 600; + height: 20px; } .mx_TabbedView_tabLabel:hover { @@ -61,16 +44,17 @@ limitations under the License. } .mx_TabbedView_tabLabel_active { - font-weight: 700; - background-color: $tab-list-active-bg-color; - color: $tab-list-active-fg-color; + background-color: $tab-label-active-bg-color; + color: $tab-label-active-fg-color; } .mx_TabbedView_tabPanel { + width: calc(100% - 320px); + display: inline-block; height: 100vh; // 100% of viewport height - scroll-snap-align: start; + margin-left: 20px; } .mx_TabbedView_tabPanelContent { - width: 600px; + flex-grow: 1; } \ No newline at end of file diff --git a/res/themes/dharma/css/_dharma.scss b/res/themes/dharma/css/_dharma.scss index 8f369a3b33..e95ad82daf 100644 --- a/res/themes/dharma/css/_dharma.scss +++ b/res/themes/dharma/css/_dharma.scss @@ -187,12 +187,10 @@ $lightbox-fg-color: #ffffff; $lightbox-border-color: #ffffff; // Tabbed views -$tab-list-bg-color: $secondary-accent-color; -$tab-list-fg-color: $accent-color; -$tab-list-active-bg-color: $tertiary-accent-color; -$tab-list-active-fg-color: $accent-color; -$tab-border-color: $tertiary-accent-color; -$tab-panel-bg-color: #fff; +$tab-label-fg-color: #45474a; +$tab-label-active-fg-color: #ffffff; +$tab-label-bg-color: transparent; +$tab-label-active-bg-color: #7ac9a1; // unused? $progressbar-color: #000; diff --git a/res/themes/light/css/_base.scss b/res/themes/light/css/_base.scss index 996fe965cf..852442c4d1 100644 --- a/res/themes/light/css/_base.scss +++ b/res/themes/light/css/_base.scss @@ -183,12 +183,10 @@ $imagebody-giflabel-border: rgba(0, 0, 0, 0.2); $imagebody-giflabel-color: rgba(255, 255, 255, 1); // Tabbed views -$tab-list-bg-color: $secondary-accent-color; -$tab-list-fg-color: $accent-color; -$tab-list-active-bg-color: $tertiary-accent-color; -$tab-list-active-fg-color: $accent-color; -$tab-border-color: $tertiary-accent-color; -$tab-panel-bg-color: #fff; +$tab-label-fg-color: #45474a; +$tab-label-active-fg-color: #ffffff; +$tab-label-bg-color: transparent; +$tab-label-active-bg-color: #7ac9a1; // unused? $progressbar-color: #000; diff --git a/src/components/structures/TabbedView.js b/src/components/structures/TabbedView.js index 44ecee7a95..047d48e808 100644 --- a/src/components/structures/TabbedView.js +++ b/src/components/structures/TabbedView.js @@ -16,45 +16,42 @@ limitations under the License. */ import * as React from "react"; -import {_t, _td} from '../../languageHandler'; -import GeminiScrollbar from 'react-gemini-scrollbar'; +import {_t} from '../../languageHandler'; import PropTypes from "prop-types"; -//import scrollSnapPolyfill from 'css-scroll-snap-polyfill'; - -const DEFAULT_EXIT_STRING = _td("Return to app"); /** - * Represents a tab for the TabbedView + * Represents a tab for the TabbedView. */ export class Tab { /** - * Creates a new tab - * @param {string} tabLabel The untranslated tab label + * Creates a new tab. + * @param {string} tabLabel The untranslated tab label. + * @param {string} tabIconRef The relative path to the tab's icon. * @param {string} tabJsx The JSX for the tab container. */ - constructor(tabLabel, tabJsx) { + constructor(tabLabel, tabIconRef, tabJsx) { this.label = tabLabel; this.body = tabJsx; } } export class TabbedView extends React.Component { + static propTypes = { + // The tabs to show + tabs: PropTypes.arrayOf(Tab).isRequired, + }; + constructor() { super(); - // This is used to track when the user has scrolled all the way up or down so we - // don't immediately start flipping between tabs. - this._reachedEndAt = 0; - } - - getInitialState() { - return { + this.state = { activeTabIndex: 0, }; } _getActiveTabIndex() { - return this.state ? this.state.activeTabIndex : 0; + if (!this.state || !this.state.activeTabIndex) return 0; + return this.state.activeTabIndex; } /** @@ -66,28 +63,12 @@ export class TabbedView extends React.Component { const idx = this.props.tabs.indexOf(tab); if (idx !== -1) { this.setState({activeTabIndex: idx}); - this._reachedEndAt = 0; // reset scroll timer - } - else console.error("Could not find tab " + tab.label + " in tabs"); - } - - _nextTab() { - let targetIndex = this._getActiveTabIndex() + 1; - if (targetIndex < this.props.tabs.length) { - this.setState({activeTabIndex: targetIndex}); - this._reachedEndAt = 0; // reset scroll timer + } else { + console.error("Could not find tab " + tab.label + " in tabs"); } } - _previousTab() { - let targetIndex = this._getActiveTabIndex() - 1; - if (targetIndex >= 0) { - this.setState({activeTabIndex: targetIndex}); - this._reachedEndAt = 0; // reset scroll timer - } - } - - _getTabLabel(tab) { + _renderTabLabel(tab) { let classes = "mx_TabbedView_tabLabel "; const idx = this.props.tabs.indexOf(tab); @@ -101,7 +82,7 @@ export class TabbedView extends React.Component { ); } - _getTabPanel(tab) { + _renderTabPanel(tab) { return (
{tab.body} @@ -109,57 +90,17 @@ export class TabbedView extends React.Component { ); } - componentDidUpdate() { - window.requestAnimationFrame(() => { - console.log("SCROLL SNAP POLYFILL: UPDATE"); - //scrollSnapPolyfill(); - }); - } - - componentDidMount() { - window.requestAnimationFrame(() => { - console.log("SCROLL SNAP POLYFILL: MOUNT"); - //scrollSnapPolyfill(); - }); - } - render() { - const labels = []; - const tabs = []; - - for (const tab of this.props.tabs) { - labels.push(this._getTabLabel(tab)); - tabs.push(this._getTabPanel(tab)); - } - - const returnToApp = ( - - {_t(this.props.exitLabel || DEFAULT_EXIT_STRING)} - - ); + const labels = this.props.tabs.map(tab => this._renderTabLabel(tab)); + const panel = this._renderTabPanel(this.props.tabs[this._getActiveTabIndex()]); return (
- {returnToApp} {labels}
-
- {tabs} -
+ {panel}
); } -} - -TabbedView.PropTypes = { - // Called when the user clicks the "Exit" or "Return to app" button - onExit: PropTypes.func.isRequired, - - // The untranslated label for the "Return to app" button. - // Default: "Return to app" - exitLabel: PropTypes.string, - - // The tabs to show - tabs: PropTypes.arrayOf(Tab).isRequired, -}; \ No newline at end of file +} \ No newline at end of file diff --git a/src/components/views/dialogs/UserSettingsDialog.js b/src/components/views/dialogs/UserSettingsDialog.js index f04b92b6cc..e54bc9c857 100644 --- a/src/components/views/dialogs/UserSettingsDialog.js +++ b/src/components/views/dialogs/UserSettingsDialog.js @@ -16,7 +16,6 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; -import sdk from '../../../index'; import {Tab, TabbedView} from "../../structures/TabbedView"; import {_td} from "../../../languageHandler"; @@ -27,14 +26,14 @@ export default class UserSettingsDialog extends React.Component { _getTabs() { return [ - new Tab(_td("General"),
General Test
), - new Tab(_td("Account"),
Account Test
), + new Tab(_td("General"), "",
General Test
), + new Tab(_td("Account"), "",
Account Test
), ]; } render() { return ( - + //