Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add d2l-expand-collapse component to create collapsible areas #540

Merged
merged 14 commits into from
May 19, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions components/expand-collapse/demo/expand-collapse.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta charset="UTF-8">
<link rel="stylesheet" href="../../demo/styles.css" type="text/css">
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
<script type="module">
import '../../button/button.js';
import '../../demo/demo-page.js';
import '../expand-collapse.js';
</script>
</head>

<body unresolved>

<d2l-demo-page page-title="d2l-expand-collapse">

<h2>Default</h2>
<d2l-demo-snippet>
<template>
<d2l-button primary>Toggle</d2l-button>
<d2l-expand-collapse>
AllanKerr marked this conversation as resolved.
Show resolved Hide resolved
<p>
Yar Pirate Ipsum
Crow's nest chase guns coxswain belay coffer jib Shiver me timbers tackle piracy Buccaneer. Overhaul topsail Cat o'nine
tails lee wherry Sink me smartly ballast Sail ho hardtack. Bowsprit aft quarterdeck killick pirate black jack hands
crimp interloper yawl.
</p>
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
<p>
Me trysail gangplank Plate Fleet Sink me hang the jib lanyard parrel square-rigged stern. Gangplank chandler brigantine
spyglass scurvy rope's end plunder lugger topmast trysail. Admiral of the Black cackle fruit hearties maroon bounty
Blimey yo-ho-ho sutler pillage boom.
</p>
</d2l-expand-collapse>
<script type="module">
const button = document.querySelector('d2l-button');
button.addEventListener('click', () => {
const section = document.querySelector('d2l-expand-collapse');
section.expanded = !section.expanded;
});
</script>
</template>
</d2l-demo-snippet>

</d2l-demo-page>

</body>

</html>
140 changes: 140 additions & 0 deletions components/expand-collapse/expand-collapse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import { css, html, LitElement } from 'lit-element/lit-element.js';
import ResizeObserver from 'resize-observer-polyfill/dist/ResizeObserver.es.js';
import { styleMap } from 'lit-html/directives/style-map.js';

const reduceMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;

const states = {
COLLAPSING: 'collapsing', // in the process of collapsing
COLLAPSED: 'collapsed', // fully collapsed
EXPANDING: 'expanding', // in the process of expanding
EXPANDED: 'expanded', // fully expanded
};
AllanKerr marked this conversation as resolved.
Show resolved Hide resolved

class ExpandCollapse extends LitElement {

static get properties() {
return {
expanded: { type: Boolean, reflect: true },
_height: { type: Number },
_state: { type: String }
};
}

static get styles() {
return css`
:host {
display: block;
}

:host([hidden]) {
display: none;
}

.d2l-expand-collapse-container {
display: none;
height: 0px;
AllanKerr marked this conversation as resolved.
Show resolved Hide resolved
overflow: hidden;
transition: height 400ms cubic-bezier(0, 0.7, 0.5, 1);
}

.d2l-expand-collapse-container:not([data-state="collapsed"]) {
display: block;
}

.d2l-expand-collapse-container[data-state="expanded"] {
overflow: visible;
}

/* prevent margin colapse on slotted children */
.d2l-expand-collapse-content:before,
.d2l-expand-collapse-content:after {
content: ' ';
display: table;
}

@media (prefers-reduced-motion: reduce) {
.d2l-expand-collapse-container {
transition: none;
}
}
`;
}

constructor() {
super();
this._onContentResize = this._onContentResize.bind(this);
this.expanded = false;
this._state = states.COLLAPSED;
}

get expanded() {
return this._expanded;
}

set expanded(val) {
const oldVal = this._expanded;
if (oldVal !== val) {
this._expanded = val;
this.requestUpdate('expanded', oldVal);
this._expandedChanged(val);
AllanKerr marked this conversation as resolved.
Show resolved Hide resolved
}
}

firstUpdated() {
super.firstUpdated();

const content = this.shadowRoot.querySelector('.d2l-expand-collapse-content');
AllanKerr marked this conversation as resolved.
Show resolved Hide resolved
this._resizeObserver = new ResizeObserver(this._onContentResize);
this._resizeObserver.observe(content);
AllanKerr marked this conversation as resolved.
Show resolved Hide resolved
}

render() {
const styles = {
height: this.expanded ? `${this._height}px` : null
};
return html`
<div class="d2l-expand-collapse-container" data-state=${this._state} @transitionend=${this._onTransitionEnd} style=${styleMap(styles)}>
AllanKerr marked this conversation as resolved.
Show resolved Hide resolved
<div class="d2l-expand-collapse-content">
<slot></slot>
</div>
</div>
`;
}

_expandedChanged(val) {
if (val) {
this._state = reduceMotion ? states.EXPANDED : states.EXPANDING;
this._updateHeight();
} else {
this._state = reduceMotion ? states.COLLAPSED : states.COLLAPSING;
this._height = null;
}
dlockhart marked this conversation as resolved.
Show resolved Hide resolved
AllanKerr marked this conversation as resolved.
Show resolved Hide resolved
}

_getContent() {
AllanKerr marked this conversation as resolved.
Show resolved Hide resolved
return this.shadowRoot.querySelector('.d2l-expand-collapse-content');
}

_onTransitionEnd() {
if (this._state === states.EXPANDING) {
this._state = states.EXPANDED;
} else if (this._state === states.COLLAPSING) {
this._state = states.COLLAPSED;
}
}

_onContentResize() {
if (!this.expanded) {
return;
}
this._updateHeight();
}

_updateHeight() {
const content = this._getContent();
this._height = content.scrollHeight;
AllanKerr marked this conversation as resolved.
Show resolved Hide resolved
}

}
customElements.define('d2l-expand-collapse', ExpandCollapse);
AllanKerr marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ <h2 class="d2l-heading-3">Components</h2>
<li><a href="components/dropdown/demo/dropdown-tabs.html">d2l-dropdown-tabs</a></li>
</ul>
</li>
<li><a href="components/expand-collapse/demo/expand-collapse.html">d2l-expand-collapse</a></li>
<li><a href="components/focus-trap/demo/focus-trap.html">d2l-focus-trap</a></li>
<li><a href="components/hierarchical-view/demo/hierarchical-view.html">d2l-hierarchical-view</a></li>
<li><a href="components/icons/demo/icon.html">d2l-icon</a></li>
Expand Down