Skip to content

Commit

Permalink
feat: dropdown-button-icon/custom components (#163)
Browse files Browse the repository at this point in the history
  • Loading branch information
dlockhart committed Jul 18, 2022
1 parent 9fac3e6 commit 784b850
Show file tree
Hide file tree
Showing 22 changed files with 328 additions and 82 deletions.
40 changes: 3 additions & 37 deletions d2l-navigation-button-icon.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { css, html, LitElement, nothing } from 'lit';
import { FocusMixin } from '@brightspace-ui/core/mixins/focus-mixin.js';
import { getUniqueId } from '@brightspace-ui/core/helpers/uniqueId.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { highlightBorderStyles } from './d2l-navigation-styles.js';
import { highlightBorderStyles, highlightButtonStyles } from './d2l-navigation-styles.js';

/**
* Navigation button with an icon and text.
Expand Down Expand Up @@ -43,48 +43,14 @@ class NavigationButtonIcon extends FocusMixin(LitElement) {
}

static get styles() {
return [highlightBorderStyles, css`
return [highlightBorderStyles, highlightButtonStyles, css`
:host {
display: inline-block;
height: 100%;
}
:host([hidden]) {
display: none;
}
button {
align-items: center;
background: transparent;
border: none;
color: var(--d2l-color-ferrite);
cursor: pointer;
display: inline-flex;
font-family: inherit;
font-size: inherit;
gap: 6px;
height: 100%;
margin: 0;
min-height: 40px;
outline: none;
overflow: visible;
padding: 0;
position: relative;
vertical-align: middle;
white-space: nowrap;
}
/* Firefox includes a hidden border which messes up button dimensions */
button::-moz-focus-inner {
border: 0;
}
button:not([disabled]):hover,
button:not([disabled]):focus {
--d2l-icon-fill-color: var(--d2l-color-celestine);
color: var(--d2l-color-celestine);
outline: none;
}
button[disabled] {
cursor: default;
opacity: 0.5;
}
`];
}

Expand Down Expand Up @@ -121,7 +87,7 @@ class NavigationButtonIcon extends FocusMixin(LitElement) {
ariaLabel: this.text,
id: this._buttonId,
text: nothing,
tooltip: html`<d2l-tooltip for="${this._buttonId}" for-type="label" close-on-click>${this.text}</d2l-tooltip>`
tooltip: html`<d2l-tooltip close-on-click for="${this._buttonId}" for-type="label" position="bottom">${this.text}</d2l-tooltip>`
};
}
return {
Expand Down
36 changes: 36 additions & 0 deletions d2l-navigation-dropdown-button-custom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { css, html, LitElement } from 'lit';
import { DropdownOpenerMixin } from '@brightspace-ui/core/components/dropdown/dropdown-opener-mixin.js';
import { highlightBorderStyles, highlightButtonStyles } from './d2l-navigation-styles.js';

class NavigationDropdownButtonCustom extends DropdownOpenerMixin(LitElement) {

static get styles() {
return [highlightBorderStyles, highlightButtonStyles, css`
:host {
display: inline-block;
height: 100%;
position: relative;
}
:host([hidden]) {
display: none;
}
`];
}

getOpenerElement() {
return this.shadowRoot && this.shadowRoot.querySelector('button');
}

render() {
return html`
<button type="button">
<span class="d2l-navigation-highlight-border"></span>
<slot name="opener"></slot>
</button>
<slot></slot>
`;
}

}

customElements.define('d2l-navigation-dropdown-button-custom', NavigationDropdownButtonCustom);
85 changes: 85 additions & 0 deletions d2l-navigation-dropdown-button-icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import '@brightspace-ui/core/components/icons/icon.js';
import '@brightspace-ui/core/components/tooltip/tooltip.js';
import './d2l-navigation-notification-icon.js';
import { css, html, LitElement, nothing } from 'lit';
import { DropdownOpenerMixin } from '@brightspace-ui/core/components/dropdown/dropdown-opener-mixin.js';
import { getUniqueId } from '@brightspace-ui/core/helpers/uniqueId.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { offscreenStyles } from '@brightspace-ui/core/components/offscreen/offscreen.js';
import { highlightBorderStyles, highlightButtonStyles } from './d2l-navigation-styles.js';

class NavigationDropdownButtonIcon extends DropdownOpenerMixin(LitElement) {

static get properties() {
return {
icon: { type: String },
hasNotification: { attribute: 'has-notification', reflect: true, type: Boolean },
text: { type: String },
notificationText: { attribute: 'notification-text', type: String }
};
}

static get styles() {
return [highlightBorderStyles, highlightButtonStyles, offscreenStyles, css`
:host {
display: inline-block;
height: 100%;
position: relative;
}
:host([hidden]) {
display: none;
}
.icon-container {
display: inline-block;
position: relative;
}
`];
}

constructor() {
super();
this.hasNotification = false;
this._buttonId = getUniqueId();
this._describedById = getUniqueId();
}

getOpenerElement() {
return this.shadowRoot && this.shadowRoot.querySelector('button');
}

render() {
const { ariaDescribedBy, ariaDescription, contents } = this._getRenderSettings();
const highlightBorder = !this.disabled ? html`<span class="d2l-navigation-highlight-border"></span>` : nothing;
const tooltip = !this.dropdownOpened ? html`<d2l-tooltip close-on-click for="${this._buttonId}" for-type="label" position="bottom">${this.text}</d2l-tooltip>` : nothing;
return html`
<button
aria-describedby="${ifDefined(ariaDescribedBy)}"
aria-label="${this.text}"
?disabled="${this.disabled}"
id="${this._buttonId}"
type="button">${highlightBorder}${contents}</button>
${ariaDescription}
${tooltip}
<slot></slot>
`;
}

_getRenderSettings() {
const icon = html`<d2l-icon icon="${this.icon}"></d2l-icon>`;
if (this.hasNotification) {
return {
ariaDescribedBy: this._describedById,
ariaDescription: html`<span class="d2l-offscreen" id="${this._describedById}">${this.notificationText}</span>`,
contents: html`<span class="icon-container">${icon}<d2l-navigation-notification-icon></d2l-navigation-notification-icon></span>`
};
}
return {
ariaDescribedBy: undefined,
ariaDescription: nothing,
contents: icon
};
}

}

customElements.define('d2l-navigation-dropdown-button-icon', NavigationDropdownButtonIcon);
82 changes: 46 additions & 36 deletions d2l-navigation-notification-icon.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,54 @@
import '@brightspace-ui/core/components/colors/colors.js';
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
import { RtlMixin } from '@brightspace-ui/core/mixins/rtl-mixin.js';
import { css, html, LitElement } from 'lit';

/**
* @customElement
* @polymer
*/
class NavigationNotificationIcon extends PolymerElement {
static get template() {
return html`
<style is="custom-style">
:host {
display: inline-block;
height: 100%;
position: absolute;
right: calc(-100% + 11px);
top: calc(-50% + 11px);
width: 100%;
}
:host([hidden]){
display: none;
}
:host(:dir(rtl)) {
left: calc(-50% - 4px);
right: auto;
}
.d2l-navigation-notification-icon-indicator {
background: var(--d2l-color-primary-accent-indicator);
border: 2px solid white;
height: 10px;
width: 10px;
border-radius: 50%;
}
:host([thin-border]) .d2l-navigation-notification-icon-indicator {
border-width: 1px;
}
</style>
<div class="d2l-navigation-notification-icon-indicator"></div>
class NavigationNotificationIcon extends RtlMixin(LitElement) {

static get properties() {
return {
thinBorder: { attribute: 'thin-border', reflect: true, type: Boolean }
};
}

static get styles() {
return css`
:host {
display: inline-block;
height: 100%;
position: absolute;
right: calc(-100% + 11px);
top: calc(-50% + 11px);
width: 100%;
}
:host([hidden]) {
display: none;
}
:host([dir="rtl"]) {
left: calc(-50% - 4px);
right: auto;
}
.d2l-navigation-notification-icon-indicator {
background: var(--d2l-color-primary-accent-indicator);
border: 2px solid white;
border-radius: 50%;
height: 10px;
width: 10px;
}
:host([thin-border]) .d2l-navigation-notification-icon-indicator {
border-width: 1px;
}
`;
}

constructor() {
super();
this.thinBorder = false;
}

render() {
return html`<div class="d2l-navigation-notification-icon-indicator"></div>`;
}

}

window.customElements.define('d2l-navigation-notification-icon', NavigationNotificationIcon);
41 changes: 40 additions & 1 deletion d2l-navigation-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,50 @@ export const highlightBorderStyles = css`
width: calc(100% + 14px);
}
*:focus > .d2l-navigation-highlight-border,
*:hover > .d2l-navigation-highlight-border {
*:hover > .d2l-navigation-highlight-border,
*[active] > .d2l-navigation-highlight-border {
background: var(--d2l-color-celestine);
}
`;

export const highlightButtonStyles = css`
button {
align-items: center;
background: transparent;
border: none;
color: var(--d2l-color-ferrite);
cursor: pointer;
display: inline-flex;
font-family: inherit;
font-size: inherit;
gap: 6px;
height: 100%;
margin: 0;
min-height: 40px;
outline: none;
overflow: visible;
padding: 0;
position: relative;
vertical-align: middle;
white-space: nowrap;
}
/* Firefox includes a hidden border which messes up button dimensions */
button::-moz-focus-inner {
border: 0;
}
button:not([disabled]):hover,
button:not([disabled]):focus,
button[active] {
--d2l-icon-fill-color: var(--d2l-color-celestine);
color: var(--d2l-color-celestine);
outline: none;
}
button[disabled] {
cursor: default;
opacity: 0.5;
}
`;

export const highlightLinkStyles = css`
a {
align-items: center;
Expand Down
38 changes: 38 additions & 0 deletions demo/button-link.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
<link rel="stylesheet" href="/node_modules/@brightspace-ui/core/components/demo/styles.css" type="text/css">
<script type="module">
import '@brightspace-ui/core/components/demo/demo-page.js';
import '@brightspace-ui/core/components/dropdown/dropdown-content.js';
import '@brightspace-ui/core/components/icons/icon.js';
import '../d2l-navigation-dropdown-button-custom.js';
import '../d2l-navigation-dropdown-button-icon.js';
import '../d2l-navigation-button.js';
import '../d2l-navigation-button-icon.js';
import '../d2l-navigation-button-notification-icon.js';
Expand All @@ -17,6 +20,19 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8">
<style>
.personal-menu {
align-items: center;
display: flex;
font-size: 0.7rem;
gap: 10px;
}
.personal-menu-square {
background-color: #ab578a;
border-radius: 6px;
display: inline-block;
height: 42px;
width: 42px;
}
.wrapper {
border: 1px solid #999999;
border-top: 4px solid slateblue;
Expand Down Expand Up @@ -62,6 +78,28 @@ <h2>d2l-navigation-button-notification-icon</h2>
</div>
</d2l-demo-snippet>

<h2>d2l-navigation-dropdown-button-custom / d2l-navigation-dropdown-button-icon</h2>
<d2l-demo-snippet>
<div class="wrapper">
<d2l-navigation-dropdown-button-icon icon="tier3:classes" text="Select a course...">
<d2l-dropdown-content vertical-offset="0">Course selector in here.</d2l-dropdown-content>
</d2l-navigation-dropdown-button-icon>
<d2l-navigation-dropdown-button-icon icon="tier3:email" text="Message alerts" disabled>
<d2l-dropdown-content vertical-offset="0">Message alerts in here.</d2l-dropdown-content>
</d2l-navigation-dropdown-button-icon>
<d2l-navigation-dropdown-button-icon icon="tier3:discussions" text="Subscription alerts" has-notification notification-text="You have new subscription alerts">
<d2l-dropdown-content vertical-offset="0">Subscription alerts in here.</d2l-dropdown-content>
</d2l-navigation-dropdown-button-icon>
<d2l-navigation-dropdown-button-custom>
<span class="personal-menu" slot="opener">
<span class="personal-menu-square"></span>
User Name
</span>
<d2l-dropdown-content vertical-offset="0">User Settings menu in here.</d2l-dropdown-content>
</d2l-navigation-dropdown-button-custom>
</div>
</d2l-demo-snippet>

<h2>d2l-navigation-link-image</h2>
<d2l-demo-snippet>
<div class="wrapper">
Expand Down
Loading

0 comments on commit 784b850

Please sign in to comment.