@brightspace-ui/labs 2.30.0 → 2.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/demo/components/ou-filter/demoDataManager.js +128 -0
- package/demo/components/ou-filter/ouFilterDemoPage.js +103 -0
- package/demo/components/ou-filter/util.js +38 -0
- package/package.json +5 -3
- package/src/components/ou-filter/README.md +74 -0
- package/src/components/wizard/README.md +40 -21
- /package/src/components/wizard/{step.js → wizard-step.js} +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { action, decorate, observable } from 'mobx';
|
|
2
|
+
import { COURSE_OFFERING, includesSearch, Tree } from '../../../src/components/ou-filter/tree-filter.js';
|
|
3
|
+
import { OuFilterDataManager } from '../../../src/components/ou-filter/ou-filter.js';
|
|
4
|
+
|
|
5
|
+
const orgUnitChildrenCache = new Map();
|
|
6
|
+
function fetchCachedChildren() {
|
|
7
|
+
return orgUnitChildrenCache;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const OU_TYPES = {
|
|
11
|
+
ORG: 1,
|
|
12
|
+
DEPT: 2,
|
|
13
|
+
COURSE: 3,
|
|
14
|
+
FAC: 7,
|
|
15
|
+
SEM: 25
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/* eslint-disable no-console */
|
|
19
|
+
export class DemoDataManager extends OuFilterDataManager {
|
|
20
|
+
|
|
21
|
+
constructor(searchFn) {
|
|
22
|
+
super();
|
|
23
|
+
this._orgUnitTree = new Tree({});
|
|
24
|
+
this._searchFn = searchFn;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get orgUnitTree() {
|
|
28
|
+
return this._orgUnitTree;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// the method called only when Tree.isDynamic === true
|
|
32
|
+
async fetchRelevantChildren(id, bookmark) {
|
|
33
|
+
console.log(`fetchRelevantChildren ${id}, ${bookmark}`);
|
|
34
|
+
|
|
35
|
+
let results;
|
|
36
|
+
// one case for each child in "Faculty 2 - children loaded on open" (id 9)
|
|
37
|
+
switch (id) {
|
|
38
|
+
case 9:
|
|
39
|
+
if (bookmark !== 'orgUnit-9') {
|
|
40
|
+
results = { PagingInfo: { HasMoreItems: true, Bookmark: 'orgUnit-9' }, Items: [
|
|
41
|
+
{ Id: 20, Name: 'Department 3', Type: OU_TYPES.DEPT, Parents: [9], IsActive: false }
|
|
42
|
+
] };
|
|
43
|
+
} else {
|
|
44
|
+
results = { PagingInfo: { HasMoreItems: false, Bookmark: null }, Items: [
|
|
45
|
+
{ Id: 30, Name: 'Department 4', Type: OU_TYPES.DEPT, Parents: [9], IsActive: false }
|
|
46
|
+
] };
|
|
47
|
+
}
|
|
48
|
+
break;
|
|
49
|
+
case 20:
|
|
50
|
+
results = { PagingInfo: { HasMoreItems: false, Bookmark: null }, Items: [
|
|
51
|
+
{ Id: 21, Name: 'Department 3 Course 1', Type: OU_TYPES.COURSE, Parents: [20], IsActive: false },
|
|
52
|
+
{ Id: 22, Name: 'Department 3 Course 2', Type: OU_TYPES.COURSE, Parents: [20], IsActive: false }
|
|
53
|
+
] };
|
|
54
|
+
break;
|
|
55
|
+
case 30:
|
|
56
|
+
results = { PagingInfo: { HasMoreItems: false, Bookmark: null }, Items: [
|
|
57
|
+
{ Id: 31, Name: 'Department 3 Course 1', Type: OU_TYPES.COURSE, Parents: [20], IsActive: false }
|
|
58
|
+
] };
|
|
59
|
+
break;
|
|
60
|
+
default:
|
|
61
|
+
// no-op: return object with no children
|
|
62
|
+
return await super.fetchRelevantChildren(id, bookmark);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// example of handling cache
|
|
66
|
+
if (!orgUnitChildrenCache.has(id)) {
|
|
67
|
+
orgUnitChildrenCache.set(id, results);
|
|
68
|
+
} else {
|
|
69
|
+
const cached = orgUnitChildrenCache.get(id);
|
|
70
|
+
cached.PagingInfo = results.PagingInfo;
|
|
71
|
+
cached.Items.push(...results.Items);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// return result in 2 sec to show loading spinner
|
|
75
|
+
return await new Promise(resolve => setTimeout(() => resolve(results), 2000));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
loadData() {
|
|
79
|
+
const lastSearchResults = null;
|
|
80
|
+
const orgUnits = [
|
|
81
|
+
{ Id: 1, Name: 'Course 1', Type: OU_TYPES.COURSE, Parents: [3, 4], IsActive: false },
|
|
82
|
+
{ Id: 2, Name: 'Course 2', Type: OU_TYPES.COURSE, Parents: [3, 10], IsActive: true },
|
|
83
|
+
{ Id: 6, Name: 'Course 3 has a surprisingly long name, but nonetheless this kind of thing is bound to happen sometimes and we do need to design for it. Is that not so?', Type: OU_TYPES.COURSE, Parents: [7, 4], IsActive: true },
|
|
84
|
+
{ Id: 8, Name: 'ZCourse 4', Type: OU_TYPES.COURSE, Parents: [5], IsActive: false },
|
|
85
|
+
{ Id: 3, Name: 'Department 1', Type: OU_TYPES.DEPT, Parents: [5], IsActive: false },
|
|
86
|
+
{ Id: 7, Name: 'Department 2 has a longer name', Type: OU_TYPES.DEPT, Parents: [5], IsActive: false },
|
|
87
|
+
{ Id: 4, Name: 'Semester 1', Type: OU_TYPES.SEM, Parents: [6606], IsActive: false },
|
|
88
|
+
{ Id: 10, Name: 'Semester 2', Type: OU_TYPES.SEM, Parents: [6606], IsActive: false },
|
|
89
|
+
{ Id: 5, Name: 'Faculty 1 - children loaded on first load', Type: OU_TYPES.FAC, Parents: [6606], IsActive: false },
|
|
90
|
+
{ Id: 9, Name: 'Faculty 2 - children loaded on open', Type: OU_TYPES.FAC, Parents: [6606, 10], IsActive: false },
|
|
91
|
+
{ Id: 6606, Name: 'Dev', Type: OU_TYPES.ORG, Parents: [0], IsActive: false }
|
|
92
|
+
];
|
|
93
|
+
const isOrgUnitsTruncated = true;
|
|
94
|
+
|
|
95
|
+
this._orgUnitTree = new Tree({
|
|
96
|
+
// add in any nodes from the most recent search; otherwise
|
|
97
|
+
// the search will blink out and come back, and also drop any "load more" results
|
|
98
|
+
nodes: lastSearchResults ? [...orgUnits, ...lastSearchResults] : orgUnits,
|
|
99
|
+
leafTypes: [COURSE_OFFERING],
|
|
100
|
+
invisibleTypes: [OU_TYPES.SEM],
|
|
101
|
+
selectedIds: [1, 21],
|
|
102
|
+
ancestorIds: [],
|
|
103
|
+
oldTree: this.orgUnitTree,
|
|
104
|
+
isDynamic: isOrgUnitsTruncated,
|
|
105
|
+
// preload the tree with any children queries we've already run: otherwise parts of the
|
|
106
|
+
// tree blink out and then come back as they are loaded again
|
|
107
|
+
extraChildren: isOrgUnitsTruncated ?
|
|
108
|
+
fetchCachedChildren() || new Map() :
|
|
109
|
+
null,
|
|
110
|
+
searchFn: this._searchFn ? this._searchFn : includesSearch
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// for perf testing
|
|
114
|
+
// this._orgUnitTree = createNaryTree(5, 5000);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// the method called only when Tree.isDynamic === true
|
|
118
|
+
async orgUnitSearch(searchString, bookmark) {
|
|
119
|
+
console.log(`orgUnitSearch ${searchString}, ${bookmark}`);
|
|
120
|
+
|
|
121
|
+
return await super.orgUnitSearch(searchString, bookmark);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
decorate(DemoDataManager, {
|
|
126
|
+
_orgUnitTree: observable,
|
|
127
|
+
loadData: action
|
|
128
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import '@brightspace-ui/core/components/inputs/input-search.js';
|
|
2
|
+
|
|
3
|
+
import { css, html } from 'lit';
|
|
4
|
+
import { DemoDataManager } from './demoDataManager.js';
|
|
5
|
+
import { MobxLitElement } from '@adobe/lit-mobx';
|
|
6
|
+
import { startsWithSearch } from '../../../src/components/ou-filter/tree-filter.js';
|
|
7
|
+
|
|
8
|
+
function parseHash(hash) {
|
|
9
|
+
return hash.substring(1).split(';').reduce((acc, curr) => {
|
|
10
|
+
const [key, val] = curr.split('=');
|
|
11
|
+
acc.set(key, val);
|
|
12
|
+
return acc;
|
|
13
|
+
}, new Map());
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* eslint-disable no-console */
|
|
17
|
+
class OuFilterDemoPage extends MobxLitElement {
|
|
18
|
+
|
|
19
|
+
static get styles() {
|
|
20
|
+
return [
|
|
21
|
+
css`
|
|
22
|
+
:host {
|
|
23
|
+
display: inline-block;
|
|
24
|
+
}
|
|
25
|
+
div {
|
|
26
|
+
padding: 30px;
|
|
27
|
+
}
|
|
28
|
+
label {
|
|
29
|
+
display: block;
|
|
30
|
+
margin-top: 25px;
|
|
31
|
+
}
|
|
32
|
+
`
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
constructor() {
|
|
37
|
+
super();
|
|
38
|
+
this.dataManager = new DemoDataManager();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
connectedCallback() {
|
|
42
|
+
super.connectedCallback();
|
|
43
|
+
|
|
44
|
+
const hashMap = parseHash(window.location.hash);
|
|
45
|
+
|
|
46
|
+
if (hashMap.has('dir')) {
|
|
47
|
+
document.documentElement.setAttribute('dir', hashMap.get('dir'));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (hashMap.has('search') && hashMap.get('search') === 'startswith') {
|
|
51
|
+
this.dataManager = new DemoDataManager(startsWithSearch);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
firstUpdated() {
|
|
56
|
+
this.dataManager.loadData();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
render() {
|
|
60
|
+
return html`
|
|
61
|
+
<div>
|
|
62
|
+
<d2l-labs-ou-filter
|
|
63
|
+
.dataManager=${this.dataManager}
|
|
64
|
+
select-all-ui
|
|
65
|
+
@d2l-labs-ou-filter-change="${this._handleOrgUnitFilterChange}"
|
|
66
|
+
></d2l-labs-ou-filter>
|
|
67
|
+
<label for="org-unit-id-search">Test visibility modifiers: show only branches containing org unit ids</label>
|
|
68
|
+
<d2l-input-search
|
|
69
|
+
id="org-unit-id-search"
|
|
70
|
+
label="Demo search input"
|
|
71
|
+
@d2l-input-search-searched="${this._handleInputSearchChange}">
|
|
72
|
+
</d2l-input-search>
|
|
73
|
+
</div>
|
|
74
|
+
`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
_handleInputSearchChange(event) {
|
|
78
|
+
const searchInput = event.detail.value;
|
|
79
|
+
const visibilityModifierKey = 'searchInputFilter';
|
|
80
|
+
if (!searchInput) {
|
|
81
|
+
this.dataManager.orgUnitTree.removeVisibilityModifier(visibilityModifierKey);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// expect CSV of org unit ids
|
|
86
|
+
const searchedOrgUnitIds = searchInput.split(',').map(orgUnitIdStr => Number(orgUnitIdStr));
|
|
87
|
+
const tree = this.dataManager.orgUnitTree;
|
|
88
|
+
|
|
89
|
+
// example: only load branches that contain any of the searched orgUnitIds
|
|
90
|
+
tree.setVisibilityModifier(
|
|
91
|
+
visibilityModifierKey,
|
|
92
|
+
(id) => tree.hasDescendantsInList(id, searchedOrgUnitIds)
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
_handleOrgUnitFilterChange(event) {
|
|
97
|
+
event.stopPropagation();
|
|
98
|
+
console.log(event.target.selected);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
customElements.define('d2l-labs-oufilter-demo-page', OuFilterDemoPage);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Tree } from '../../../src/components/ou-filter/tree-filter.js';
|
|
2
|
+
|
|
3
|
+
let idCounter = 1;
|
|
4
|
+
|
|
5
|
+
function createNode(id, parents, type) {
|
|
6
|
+
return { Id: id, Name: `Node ${id}`, Type: type, Parents: parents, IsActive: true };
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function spawnChildren(node, n) {
|
|
10
|
+
const newNodes = [];
|
|
11
|
+
for (let i = 1; i <= n; i++) {
|
|
12
|
+
newNodes.push(createNode(++idCounter, [node.Id], node.Type + 1));
|
|
13
|
+
}
|
|
14
|
+
return newNodes;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function createNaryTree(n, numNodes) {
|
|
18
|
+
|
|
19
|
+
idCounter = 1;
|
|
20
|
+
|
|
21
|
+
const nodes = [createNode(1, [0], 0)];
|
|
22
|
+
let newNodes = [...nodes];
|
|
23
|
+
|
|
24
|
+
// create each layer of the tree until we have the requisite total number of nodes; drop any excess nodes
|
|
25
|
+
while (nodes.length < numNodes) {
|
|
26
|
+
|
|
27
|
+
let children = newNodes.flatMap(node => spawnChildren(node, n));
|
|
28
|
+
if (children.length + nodes.length > numNodes) {
|
|
29
|
+
children = children.slice(0, numNodes - nodes.length);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
nodes.push(...children);
|
|
33
|
+
newNodes = children;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const numLevels = Math.ceil(Math.log(numNodes - 1) / Math.log(n)); // including level 0 (root node)
|
|
37
|
+
return new Tree({ nodes, leafTypes: [numLevels] });
|
|
38
|
+
}
|
package/package.json
CHANGED
|
@@ -47,10 +47,11 @@
|
|
|
47
47
|
"./components/pager-numeric.js": "./src/components/pagination/pager-numeric.js",
|
|
48
48
|
"./components/view-toggle.js": "./src/components/view-toggle/view-toggle.js",
|
|
49
49
|
"./components/wizard.js": "./src/components/wizard/wizard.js",
|
|
50
|
-
"./components/wizard-step.js": "./src/components/wizard/step.js",
|
|
50
|
+
"./components/wizard-step.js": "./src/components/wizard/wizard-step.js",
|
|
51
51
|
"./controllers/computed-value.js": "./src/controllers/computed-values/computed-value.js",
|
|
52
52
|
"./controllers/computed-values.js": "./src/controllers/computed-values/computed-values.js",
|
|
53
53
|
"./controllers/language-listener.js": "./src/controllers/language-listener/language-listener.js",
|
|
54
|
+
"./demo/components/ou-filter/*.js": "./demo/components/ou-filter/*.js",
|
|
54
55
|
"./utilities/pub-sub.js": "./src/utilities/pub-sub/pub-sub.js",
|
|
55
56
|
"./utilities/reactive-store.js": "./src/utilities/reactive-store/reactive-store.js",
|
|
56
57
|
"./utilities/lit-router": "./src/utilities/router/index.js"
|
|
@@ -93,7 +94,8 @@
|
|
|
93
94
|
"files": [
|
|
94
95
|
"labs.serge.json",
|
|
95
96
|
"/src",
|
|
96
|
-
"/demo/components/media-player/static"
|
|
97
|
+
"/demo/components/media-player/static",
|
|
98
|
+
"/demo/components/ou-filter/*.js"
|
|
97
99
|
],
|
|
98
100
|
"publishConfig": {
|
|
99
101
|
"access": "public"
|
|
@@ -112,5 +114,5 @@
|
|
|
112
114
|
"resize-observer-polyfill": "^1",
|
|
113
115
|
"webvtt-parser": "^2.1.2"
|
|
114
116
|
},
|
|
115
|
-
"version": "2.
|
|
117
|
+
"version": "2.31.1"
|
|
116
118
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Org Unit Filter
|
|
2
|
+
|
|
3
|
+
A Lit component that renders an org unit structure tree. It supports load more and searching functionality.
|
|
4
|
+
|
|
5
|
+
## Org Unit Filter [d2l-labs-ou-filter]
|
|
6
|
+
|
|
7
|
+
<!-- docs: demo align:flex-start autoSize:false size:xlarge -->
|
|
8
|
+
```html
|
|
9
|
+
<script type="module">
|
|
10
|
+
import '@brightspace-ui/labs/demo/components/ou-filter/ouFilterDemoPage.js';
|
|
11
|
+
</script>
|
|
12
|
+
<d2l-labs-oufilter-demo-page></d2l-labs-oufilter-demo-page>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### General Usage
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import { action, decorate, observable } from 'mobx';
|
|
19
|
+
import { MobxLitElement } from '@adobe/lit-mobx';
|
|
20
|
+
import { OuFilterDataManager } from '@brightspace-ui-labs/ou-filter/ou-filter.js';
|
|
21
|
+
|
|
22
|
+
class FooDataManager extends OuFilterDataManager {
|
|
23
|
+
|
|
24
|
+
constructor() {
|
|
25
|
+
super();
|
|
26
|
+
this._orgUnitTree = new Tree({});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async loadData() {
|
|
30
|
+
this._orgUnitTree = new Tree({ nodes: ..., ... });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
decorate(FooDataManager, {
|
|
35
|
+
_orgUnitTree: observable,
|
|
36
|
+
loadData: action
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
class FooPage extends MobxLitElement {
|
|
40
|
+
constructor() {
|
|
41
|
+
this.dataManager = new FooDataManager();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
firstUpdated() {
|
|
45
|
+
this.dataManager.loadData();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
render () {
|
|
49
|
+
return html`
|
|
50
|
+
<d2l-labs-ou-filter
|
|
51
|
+
.dataManager=${this.dataManager}
|
|
52
|
+
select-all-ui
|
|
53
|
+
@d2l-labs-ou-filter-change="${this._orgUnitFilterChange}"
|
|
54
|
+
></d2l-labs-ou-filter>`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
_orgUnitFilterChange() {
|
|
58
|
+
console.log(event.target.selected);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
<!-- docs: start hidden content -->
|
|
64
|
+
|
|
65
|
+
**Properties:**
|
|
66
|
+
|
|
67
|
+
| Property | Type | Default | Description |
|
|
68
|
+
|----------|------|---------|-------------|
|
|
69
|
+
| dataManager | Object | {empty} | Object that extends OuFilterDataManager. It provides and manages data for d2l-labs-ou-filter |
|
|
70
|
+
| select-all-ui | Boolean | {empty} | Shows Select all button |
|
|
71
|
+
| d2l-labs-ou-filter-change | Function | {empty} | Event handler that is fired when selection is changed |
|
|
72
|
+
| disabled | Boolean | {empty} | Render the filter in a disabled state |
|
|
73
|
+
|
|
74
|
+
<!-- docs: end hidden content -->
|
|
@@ -1,34 +1,52 @@
|
|
|
1
1
|
# Wizard
|
|
2
2
|
|
|
3
|
-
The
|
|
3
|
+
The wizard component can be used to display a stepped workflow.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Wizard [d2l-labs-wizard]
|
|
6
6
|
|
|
7
|
+
<!-- docs: demo code -->
|
|
7
8
|
```html
|
|
8
9
|
<script type="module">
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
import '@brightspace-ui/labs/components/wizard.js';
|
|
11
|
+
import '@brightspace-ui/labs/components/wizard-step.js';
|
|
12
|
+
// <!-- docs: start hidden content -->
|
|
13
|
+
requestAnimationFrame(() => {
|
|
14
|
+
const wizard = document.getElementById('wizard');
|
|
15
|
+
wizard.addEventListener('stepper-next', function() {
|
|
16
|
+
wizard.next();
|
|
17
|
+
});
|
|
18
|
+
wizard.addEventListener('stepper-restart', function() {
|
|
19
|
+
wizard.restart();
|
|
20
|
+
});
|
|
21
|
+
})
|
|
22
|
+
// <!-- docs: end hidden content -->
|
|
11
23
|
</script>
|
|
12
|
-
<d2l-labs-wizard
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
<d2l-labs-wizard
|
|
25
|
+
id="wizard"
|
|
26
|
+
selected-step="1">
|
|
27
|
+
<d2l-labs-wizard-step
|
|
28
|
+
next-button-aria-label="Go to step 2"
|
|
29
|
+
step-title="Get Started"
|
|
30
|
+
hide-restart-button="true">
|
|
31
|
+
<p>First Step</p>
|
|
32
|
+
</d2l-labs-wizard-step>
|
|
33
|
+
|
|
34
|
+
<d2l-labs-wizard-step
|
|
35
|
+
aria-title="This is the second step"
|
|
36
|
+
restart-button-tooltip="Restart this wizard">
|
|
37
|
+
<p>Second Step</p>
|
|
38
|
+
</d2l-labs-wizard-step>
|
|
39
|
+
|
|
40
|
+
<d2l-labs-wizard-step
|
|
41
|
+
step-title="Almost Done"
|
|
42
|
+
next-button-title="Done"
|
|
43
|
+
next-button-tooltip="Save this wizard">
|
|
44
|
+
<p>Last Step</p>
|
|
45
|
+
</d2l-labs-wizard-step>
|
|
20
46
|
</d2l-labs-wizard>
|
|
21
|
-
<script>
|
|
22
|
-
var wizard = document.getElementById('wizard');
|
|
23
|
-
wizard.addEventListener('stepper-next', function() {
|
|
24
|
-
wizard.next();
|
|
25
|
-
});
|
|
26
|
-
wizard.addEventListener('stepper-restart', function() {
|
|
27
|
-
wizard.restart();
|
|
28
|
-
});
|
|
29
|
-
</script>
|
|
30
47
|
```
|
|
31
48
|
|
|
49
|
+
<!-- docs: start hidden content -->
|
|
32
50
|
|
|
33
51
|
### Properties:
|
|
34
52
|
|
|
@@ -47,3 +65,4 @@ The `<d2l-labs-wizard>` can be used to be display a stepped workflow.
|
|
|
47
65
|
- `stepper-next`: dispatched when the Next button is clicked
|
|
48
66
|
- `stepper-restart`: dispatched when the Restart button is clicked
|
|
49
67
|
|
|
68
|
+
<!-- docs: end hidden content -->
|
|
File without changes
|