diff --git a/browser/components/loop/content/js/panel.js b/browser/components/loop/content/js/panel.js
index ac6aa8650fd..407367e439e 100644
--- a/browser/components/loop/content/js/panel.js
+++ b/browser/components/loop/content/js/panel.js
@@ -22,6 +22,57 @@ loop.panel = (function(_, mozL10n) {
*/
var router;
+ var TabView = React.createClass({displayName: 'TabView',
+ getInitialState: function() {
+ return {
+ selectedTab: "call"
+ };
+ },
+
+ handleSelectTab: function(event) {
+ var tabName = event.target.dataset.tabName;
+ this.setState({selectedTab: tabName});
+
+ if (this.props.onSelect) {
+ this.props.onSelect(tabName);
+ }
+ },
+
+ render: function() {
+ var cx = React.addons.classSet;
+ var tabButtons = [];
+ var tabs = [];
+ React.Children.forEach(this.props.children, function(tab, i) {
+ var tabName = tab.props.name;
+ var isSelected = (this.state.selectedTab == tabName);
+ tabButtons.push(
+ React.DOM.li({className: cx({selected: isSelected}),
+ key: i,
+ 'data-tab-name': tabName,
+ onClick: this.handleSelectTab}
+ )
+ );
+ tabs.push(
+ React.DOM.div({key: i, className: cx({tab: true, selected: isSelected})},
+ tab.props.children
+ )
+ );
+ }, this);
+ return (
+ React.DOM.div({className: "tab-view-container"},
+ React.DOM.ul({className: "tab-view"}, tabButtons),
+ tabs
+ )
+ );
+ }
+ });
+
+ var Tab = React.createClass({displayName: 'Tab',
+ render: function() {
+ return null;
+ }
+ });
+
/**
* Dropdown menu mixin.
* @type {Object}
@@ -424,10 +475,17 @@ loop.panel = (function(_, mozL10n) {
return (
React.DOM.div(null,
NotificationListView({notifications: this.props.notifications}),
- CallUrlResult({client: this.props.client,
- notifications: this.props.notifications,
- callUrl: this.props.callUrl}),
- ToSView(null),
+ TabView({onSelect: this.selectTab},
+ Tab({name: "call"},
+ CallUrlResult({client: this.props.client,
+ notifications: this.props.notifications,
+ callUrl: this.props.callUrl}),
+ ToSView(null)
+ ),
+ Tab({name: "contacts"},
+ React.DOM.span(null, "contacts")
+ )
+ ),
React.DOM.div({className: "footer"},
AvailabilityDropdown(null),
AuthLink(null),
diff --git a/browser/components/loop/content/js/panel.jsx b/browser/components/loop/content/js/panel.jsx
index 902c343e957..1791f69aa5d 100644
--- a/browser/components/loop/content/js/panel.jsx
+++ b/browser/components/loop/content/js/panel.jsx
@@ -22,6 +22,57 @@ loop.panel = (function(_, mozL10n) {
*/
var router;
+ var TabView = React.createClass({
+ getInitialState: function() {
+ return {
+ selectedTab: "call"
+ };
+ },
+
+ handleSelectTab: function(event) {
+ var tabName = event.target.dataset.tabName;
+ this.setState({selectedTab: tabName});
+
+ if (this.props.onSelect) {
+ this.props.onSelect(tabName);
+ }
+ },
+
+ render: function() {
+ var cx = React.addons.classSet;
+ var tabButtons = [];
+ var tabs = [];
+ React.Children.forEach(this.props.children, function(tab, i) {
+ var tabName = tab.props.name;
+ var isSelected = (this.state.selectedTab == tabName);
+ tabButtons.push(
+
+
+ );
+ tabs.push(
+
+ {tab.props.children}
+
+ );
+ }, this);
+ return (
+
+ );
+ }
+ });
+
+ var Tab = React.createClass({
+ render: function() {
+ return null;
+ }
+ });
+
/**
* Dropdown menu mixin.
* @type {Object}
@@ -424,10 +475,17 @@ loop.panel = (function(_, mozL10n) {
return (
-
-
+
+
+
+
+
+
+ contacts
+
+
diff --git a/browser/components/loop/content/shared/css/panel.css b/browser/components/loop/content/shared/css/panel.css
index b751c77e17b..436316b5774 100644
--- a/browser/components/loop/content/shared/css/panel.css
+++ b/browser/components/loop/content/shared/css/panel.css
@@ -4,12 +4,6 @@
/* Panel styles */
.panel {
- /* XXX force proper content positioning by adding extra margin space
- * taken away by reset.css
- */
- margin-top: 7px;
- margin-bottom: 7px;
-
/* hide the extra margin space that the panel resizer now wants to show */
overflow: hidden;
}
@@ -18,6 +12,74 @@
margin-bottom: 1em;
}
+.tab-view,
+.tab-view > li {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ vertical-align: baseline;
+}
+
+.tab-view {
+ display: flex;
+ flex-direction: row;
+ padding: 10px;
+ border-bottom: 1px solid #ccc;
+ background: #fafafa;
+ border-top-right-radius: 2px;
+ border-top-left-radius: 2px;
+ list-style: none;
+}
+
+.tab-view > li {
+ flex: 1;
+ text-align: center;
+ color: #ccc;
+ border-right: 1px solid #ccc;
+ padding: 0 10px;
+ height: 16px;
+ cursor: pointer;
+ background-repeat: no-repeat;
+ background-size: 16px 16px;
+ background-position: center;
+}
+
+.tab-view > li[data-tab-name="call"] {
+ background-image: url("../img/icons-16x16.svg#precall");
+}
+
+.tab-view > li[data-tab-name="call"]:hover {
+ background-image: url("../img/icons-16x16.svg#precall-hover");
+}
+
+.tab-view > li[data-tab-name="call"].selected {
+ background-image: url("../img/icons-16x16.svg#precall-active");
+}
+
+.tab-view > li[data-tab-name="contacts"] {
+ background-image: url("../img/icons-16x16.svg#contacts");
+}
+
+.tab-view > li[data-tab-name="contacts"]:hover {
+ background-image: url("../img/icons-16x16.svg#contacts-hover");
+}
+
+.tab-view > li[data-tab-name="contacts"].selected {
+ background-image: url("../img/icons-16x16.svg#contacts-active");
+}
+
+.tab-view > li:last-child {
+ border-right: 0;
+}
+
+.tab {
+ display: none;
+}
+
+.tab.selected {
+ display: block;
+}
+
.share {
background: #fbfbfb;
}
diff --git a/browser/components/loop/content/shared/img/icons-16x16.svg b/browser/components/loop/content/shared/img/icons-16x16.svg
new file mode 100644
index 00000000000..901570ce12e
--- /dev/null
+++ b/browser/components/loop/content/shared/img/icons-16x16.svg
@@ -0,0 +1,117 @@
+
+
+
diff --git a/browser/components/loop/jar.mn b/browser/components/loop/jar.mn
index d1761edc2fc..20d36890bf9 100644
--- a/browser/components/loop/jar.mn
+++ b/browser/components/loop/jar.mn
@@ -44,7 +44,8 @@ browser.jar:
content/browser/loop/shared/img/svg/glyph-account-16x16.svg (content/shared/img/svg/glyph-account-16x16.svg)
content/browser/loop/shared/img/svg/glyph-signin-16x16.svg (content/shared/img/svg/glyph-signin-16x16.svg)
content/browser/loop/shared/img/svg/glyph-signout-16x16.svg (content/shared/img/svg/glyph-signout-16x16.svg)
- content/browser/loop/shared/img/audio-call-avatar.svg (content/shared/img/audio-call-avatar.svg)
+ content/browser/loop/shared/img/audio-call-avatar.svg (content/shared/img/audio-call-avatar.svg)
+ content/browser/loop/shared/img/icons-16x16.svg (content/shared/img/icons-16x16.svg)
# Shared scripts
content/browser/loop/shared/js/feedbackApiClient.js (content/shared/js/feedbackApiClient.js)