Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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
31 changes: 31 additions & 0 deletions components/order/demo/order-demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import '../order.js';
import '../../button/button.js';
import { css, html, LitElement } from 'lit';

Check failure on line 3 in components/order/demo/order-demo.js

View workflow job for this annotation

GitHub Actions / Lint

'css' is defined but never used

/**
* A container element that can order its contents separately for keyboard users, screenreader users, and visually
* @slot content - Slot for primary content
*/
class OrderDemo extends LitElement {

static get properties() {
return {
num: { type: Number },
visualOrder: { type: String, attribute: 'visual-order' },
keyboardOrder: { type: String, attribute: 'keyboard-order' },
extra: { type: Boolean }
}

Check failure on line 17 in components/order/demo/order-demo.js

View workflow job for this annotation

GitHub Actions / Lint

Missing semicolon
}

render() {
return html`<d2l-order style="gap: 0.5rem;" visual-order="${this.visualOrder}" keyboard-order="${this.keyboardOrder}">
${Array(this.num).fill(0).map((item, idx) => {
return html`<d2l-button>${idx + 1}</d2l-button>`

Check failure on line 23 in components/order/demo/order-demo.js

View workflow job for this annotation

GitHub Actions / Lint

Missing semicolon
})}
${this.extra ? html`<d2l-button>Extra Button</d2l-button>` : null}
</d2l-order>`;
}

}

customElements.define('d2l-order-demo', OrderDemo);
119 changes: 119 additions & 0 deletions components/order/demo/order.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8">
<link rel="stylesheet" href="../../demo/styles.css" type="text/css">
<script type="module">
import '../../button/button.js';
import '../../switch/switch.js';
import '../../demo/demo-page.js';
import './order-demo.js';
import '../order.js';
</script>
<style>
d2l-order {
gap: 0.5rem;
}
</style>
</head>
<body unresolved>

<d2l-demo-page page-title="d2l-order">

<h2>Order - Real-World</h2>

<d2l-demo-snippet>

<template>

<d2l-order visual-order="[2,3,4,1]">
<d2l-switch text="Hidden"></d2l-switch>
<d2l-button primary>Save & Close</d2l-button>
<d2l-button>Save</d2l-button>
<d2l-button>Cancel</d2l-button>
</d2l-order>

</template>

</d2l-demo-snippet>

<h2>Order - Visual</h2>

<d2l-demo-snippet>

<template>

<d2l-order visual-order="[5,4,1,3,2]">
<d2l-button>One</d2l-button>
<d2l-button>Two</d2l-button>
<d2l-button>Three</d2l-button>
<d2l-button>Four</d2l-button>
<d2l-button>Five</d2l-button>
</d2l-order>

</template>

</d2l-demo-snippet>

<h2>Order - Visual & Keyboard</h2>

<d2l-demo-snippet>

<template>

<d2l-order visual-order="[5,4,1,3,2]" keyboard-order="[2,1,4,3,5]">
<d2l-button>One</d2l-button>
<d2l-button>Two</d2l-button>
<d2l-button>Three</d2l-button>
<d2l-button>Four</d2l-button>
<d2l-button>Five</d2l-button>
</d2l-order>

</template>

</d2l-demo-snippet>

<h2>Order - Non-Interactive</h2>

<d2l-demo-snippet>

<template>

<d2l-order visual-order="[5,4,1,3,2]">
<d2l-button>One</d2l-button>
<d2l-button>Two</d2l-button>
<h3>Three</h3>
<h3>Four</h3>
<d2l-button>Five</d2l-button>
</d2l-order>

</template>

</d2l-demo-snippet>

<h2>Order - Toggle Extra Button</h2>

<d2l-button id="toggle">Toggle Extra Button</d2l-button>

<d2l-demo-snippet>

<template>
<div class="order-demo">

<d2l-order-demo num="4" visual-order="[5,4,3,2,1]" keyboard-order="[2,1,4,3,5]"></d2l-order-demo>

</div>
</template>

<script>
document.querySelector('#toggle').addEventListener('click', () => {
const demoEl = document.querySelector('d2l-order-demo');
demoEl.extra ^= 1;
});
</script>
</d2l-demo-snippet>

</d2l-demo-page>
</body>
</html>
17 changes: 17 additions & 0 deletions components/order/order-item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { css, html, LitElement } from 'lit';

Check failure on line 1 in components/order/order-item.js

View workflow job for this annotation

GitHub Actions / Lint

'css' is defined but never used

/**
* A container element that can order its contents separately for keyboard users, screenreader users, and visually
* @slot content - Slot for primary content
*/
class OrderItem extends LitElement {

static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true };

render() {
return html`<slot></slot>`;
}

}

customElements.define('d2l-order-item', OrderItem);
73 changes: 73 additions & 0 deletions components/order/order.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import './order-item.js';
import { css, html, LitElement } from 'lit';
import { styleMap } from 'lit/directives/style-map.js';

/**
* A container element that can order its contents separately for keyboard users, screenreader users, and visually.
* @slot content - Slot for primary content
*/
class Order extends LitElement {

static get properties() {
return {
/**
* Specifies the order in which elements should be navigable by keyboard.
* This should almost never be set, allowing keyboard order to match the visual order.
* @type {array}
* @default {visualOrder}
*/
keyboardOrder: { type: Array, attribute: 'keyboard-order' },
/**
* Specifies the order in which elements should appear visually
* @type {array}
*/
visualOrder: { type: Array, attribute: 'visual-order' },
};
}

static get styles() {
return css`
:host {
display: flex;
align-items: center;
}
`;
}

constructor() {
super();
this.visualOrder = Array(this.childElementCount).fill(0).map((_, idx) => idx + 1);
}

render() {
return html`
${[...this.children].map((child, idx) => {

child.slot = `item-${idx + 1}`;
const orderIdx = this.visualOrder.indexOf(idx + 1) + 1;
const styles = { order: orderIdx || idx + 1 };
const tabindex = child.focus && (this.keyboardOrder?.indexOf(idx + 1) + 1 || orderIdx);

return html`
<d2l-order-item
tabindex="${tabindex ?? idx}"
style="${styleMap(styles)}">
<slot @slotchange="${this.#handleSlotChangeRemove}" name="item-${idx + 1}"></slot>
</d2l-order-item>
`;
})}
<slot @slotchange="${this.#handleSlotChangeAdd}"></slot>
`;
}

#handleSlotChangeAdd(e) {
if (e.target.assignedElements().length) this.requestUpdate();
}

#handleSlotChangeRemove(e) {
if (!e.target.assignedElements().length) this.requestUpdate();
}

}

customElements.define('d2l-order', Order);
Loading