Upgrade gr-dropdown with additional capabilities
The shared dropdown component is made more-configurable, so it can be
reused in more contexts.
* The down-arrow is an flag that can be enabled on the dropdown, instead
of added (and styled) at the use site.
* Items no longer need to be links to new URLs. They can be buttons with
declared handlers.
* The dropdown trigger can be a link or a button, as configured by the
link flag.
Change-Id: Ia9db3b66bf30bc56bf2ab4ce1f2292f51ab4754d
diff --git a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.html b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.html
index cead416..07c922a 100644
--- a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.html
+++ b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.html
@@ -34,7 +34,10 @@
vertical-align: middle;
}
</style>
- <gr-dropdown items=[[links]] top-content=[[topContent]]
+ <gr-dropdown
+ link
+ items=[[links]]
+ top-content=[[topContent]]
horizontal-align="right">
<span hidden$="[[_hasAvatars]]" hidden>[[account.name]]</span>
<gr-avatar account="[[account]]" hidden$="[[!_hasAvatars]]" hidden
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html
index c3d9b16..74dc9e7 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html
@@ -52,23 +52,8 @@
.linksTitle {
color: black;
display: inline-block;
- padding-right: 1em;
position: relative;
}
- .downArrow {
- border-left: .36em solid transparent;
- border-right: .36em solid transparent;
- border-top: .36em solid #ccc;
- height: 0;
- position: absolute;
- right: 0;
- top: calc(50% - .05em);
- transition: border-top-color 200ms;
- width: 0;
- }
- .links li:hover .downArrow {
- border-top-color: #666;
- }
.rightItems {
align-items: center;
display: flex;
@@ -119,10 +104,12 @@
<template is="dom-repeat" items="[[_links]]" as="linkGroup">
<li>
<gr-dropdown
+ link
+ down-arrow
items = [[linkGroup.links]]
horizontal-align="left">
<span class="linksTitle" id="[[linkGroup.title]]">
- [[linkGroup.title]] <i class="downArrow"></i>
+ [[linkGroup.title]]
</span>
</gr-dropdown>
</li>
diff --git a/polygerrit-ui/app/elements/shared/gr-button/gr-button.js b/polygerrit-ui/app/elements/shared/gr-button/gr-button.js
index 7e91b0e..800b1df 100644
--- a/polygerrit-ui/app/elements/shared/gr-button/gr-button.js
+++ b/polygerrit-ui/app/elements/shared/gr-button/gr-button.js
@@ -18,6 +18,10 @@
is: 'gr-button',
properties: {
+ link: {
+ type: Boolean,
+ reflectToAttribute: true,
+ },
disabled: {
type: Boolean,
observer: '_disabledChanged',
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html
index 95b03fc..1882500 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html
@@ -38,6 +38,9 @@
font: inherit;
padding: .3em 0;
}
+ :host[down-arrow] .dropdown-trigger {
+ padding-right: 1.4em;
+ }
gr-avatar {
height: 2em;
width: 2em;
@@ -58,16 +61,17 @@
font-weight: bold;
}
li .accountInfo,
- li a {
+ li .itemAction {
+ cursor: pointer;
display: block;
padding: .85em 1em;
}
- li a:link,
- li a:visited {
+ li .itemAction:link,
+ li .itemAction:visited {
color: #00e;
text-decoration: none;
}
- li a:hover {
+ li .itemAction:hover {
background-color: #6B82D6;
color: #fff;
}
@@ -78,14 +82,30 @@
.bold-text {
font-weight: bold;
}
+ :host:not([down-arrow]) .downArrow { display: none; }
+ :host[down-arrow] .downArrow {
+ border-left: .36em solid transparent;
+ border-right: .36em solid transparent;
+ border-top: .36em solid #ccc;
+ height: 0;
+ position: absolute;
+ right: .3em;
+ top: calc(50% - .05em);
+ transition: border-top-color 200ms;
+ width: 0;
+ }
+ .dropdown-trigger:hover .downArrow {
+ border-top-color: #666;
+ }
</style>
- <gr-button link class="dropdown-trigger" id="trigger"
+ <gr-button link="[[link]]" class="dropdown-trigger" id="trigger"
on-tap="_showDropdownTapHandler">
<content></content>
+ <i class="downArrow"></i>
</gr-button>
<iron-dropdown id="dropdown"
vertical-align="top"
- vertical-offset="40"
+ vertical-offset="[[verticalOffset]]"
allow-outside-scroll="true"
horizontal-align="[[horizontalAlign]]"
on-tap="_handleDropdownTap">
@@ -109,7 +129,16 @@
items="[[items]]"
as="link"
initial-count="75">
- <li><a href$="[[_computeRelativeURL(link.url)]]">[[link.name]]</a>
+ <li>
+ <span
+ class="itemAction"
+ data-id$="[[link.id]]"
+ on-tap="_handleItemTap"
+ hidden$="[[link.url]]">[[link.name]]</span>
+ <a
+ class="itemAction"
+ href$="[[_computeRelativeURL(link.url)]]"
+ hidden$="[[!link.url]]">[[link.name]]</a>
</li>
</template>
</ul>
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js
index d10d219..d1fae7f 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js
@@ -17,6 +17,12 @@
Polymer({
is: 'gr-dropdown',
+ /**
+ * Fired when a non-link dropdown item with the given ID is tapped.
+ *
+ * @event tap-item-<id>
+ */
+
properties: {
items: Array,
topContent: Object,
@@ -24,6 +30,20 @@
type: String,
value: 'left',
},
+
+ /**
+ * Style the dropdown trigger as a link (rather than a button).
+ */
+ link: {
+ type: Boolean,
+ value: false,
+ },
+
+ verticalOffset: {
+ type: Number,
+ value: 40,
+ },
+
_hasAvatars: String,
},
@@ -53,5 +73,10 @@
var host = window.location.host;
return this._computeURLHelper(host, path);
},
+
+ _handleItemTap: function(e) {
+ var id = e.target.getAttribute('data-id');
+ if (id) { this.dispatchEvent(new CustomEvent('tap-item-' + id)); }
+ },
});
})();
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
index b2f2d21..2794caf 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
@@ -70,5 +70,15 @@
assert.isTrue(topItems[0].classList.contains('bold-text'));
assert.isFalse(topItems[1].classList.contains('bold-text'));
});
+
+ test('non link items', function() {
+ element.items = [
+ {name: 'item one', id: 'foo'}, {name: 'item two', id: 'bar'}];
+ var stub = sinon.stub();
+ element.addEventListener('tap-item-foo', stub);
+ flushAsynchronousOperations();
+ MockInteractions.tap(element.$$('.itemAction'));
+ assert.isTrue(stub.called);
+ });
});
</script>