@brightspace-ui/core 3.100.3 → 3.101.0

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.
@@ -258,6 +258,86 @@ document.querySelector('#open').addEventListener('click', () => {
258
258
  });
259
259
  ```
260
260
 
261
+ ## Loading Asynchronous Content
262
+
263
+ The `until` directive can be used for manging the rendering of dialog content when it is loaded asynchronously. The example below loads some dialog content asynchronously, displaying a [Loading Spinner](../loading-spinner/) until the content is ready.
264
+
265
+ Notes on this example:
266
+ - Dialog sizing: `this.resolveLoadingComplete` (part of `LoadingCompleteMixin`) on image load triggers the dialog resize
267
+ - Focus management: focus will go to the first footer button by default. If focus should instead go to a focusable element in the content then that would need to be specified, often by using `.focus()` on the other focusable element.
268
+
269
+ <!-- docs: demo code autoSize:false size:xlarge -->
270
+ ```html
271
+ <script type="module">
272
+ import '@brightspace-ui/core/components/button/button.js';
273
+ import '@brightspace-ui/core/components/loading-spinner/loading-spinner.js';
274
+ import { html, LitElement, noChange } from 'lit';
275
+ import { guard } from 'lit/directives/guard.js';
276
+ import { LoadingCompleteMixin } from '@brightspace-ui/core/mixins/loading-complete/loading-complete-mixin.js';
277
+ import { until } from 'lit/directives/until.js';
278
+
279
+ class DialogAsyncContentUntil extends LoadingCompleteMixin(LitElement) {
280
+
281
+ static get properties() {
282
+ return {
283
+ key: { type: String }
284
+ };
285
+ }
286
+
287
+ constructor() {
288
+ super();
289
+ this.key = null;
290
+ }
291
+
292
+ render() {
293
+ const loadingSpinner = html`<d2l-loading-spinner size="100" style="width: 100%;"></d2l-loading-spinner>`;
294
+ return html`${guard([this.key], () => until(this.#getContent(this.key), loadingSpinner, noChange))}`;
295
+ }
296
+
297
+ #getContent(key) {
298
+ return new Promise((resolve) => {
299
+ if (!key) return;
300
+ setTimeout(() => {
301
+ resolve(html`
302
+ <d2l-button>Focus on me!</d2l-button>
303
+ <img
304
+ src="https://us.v-cdn.net/cdn-cgi/image/fit=scale-down,width=1600/https://us.v-cdn.net/6036482/uploads/Y6MNPRWX5OVH/moose-poses-guided-tour.png"
305
+ style="height: 300px; display: block;"
306
+ @load="${this.#handleImageLoad}"
307
+ >
308
+ `);
309
+ }, 1000);
310
+ });
311
+ }
312
+
313
+ #handleImageLoad() {
314
+ this.shadowRoot.querySelector('d2l-button').focus();
315
+ this.resolveLoadingComplete();
316
+ }
317
+ }
318
+
319
+ customElements.define('d2l-dialog-demo-async-content-until', DialogAsyncContentUntil);
320
+ </script>
321
+ <script type="module">
322
+ import '@brightspace-ui/core/components/button/button.js';
323
+ import '@brightspace-ui/core/components/dialog/dialog.js';
324
+
325
+ document.querySelector('#open').addEventListener('click', () => {
326
+ document.querySelector('#dialog').opened = true;
327
+ document.querySelector('d2l-dialog-demo-async-content-until').key = 'my-dialog';
328
+ });
329
+ document.querySelector('#dialog').addEventListener('d2l-dialog-close', (e) => {
330
+ console.log('dialog action:', e.detail.action);
331
+ });
332
+ </script>
333
+ <d2l-dialog id="dialog" title-text="Async Dialog">
334
+ <d2l-dialog-demo-async-content-until></d2l-dialog-demo-async-content-until>
335
+ <d2l-button slot="footer" primary data-dialog-action="done">Done</d2l-button>
336
+ <d2l-button slot="footer" data-dialog-action>Cancel</d2l-button>
337
+ </d2l-dialog>
338
+ <d2l-button id="open">Show Dialog</d2l-button>
339
+ ```
340
+
261
341
  ## Accessibility
262
342
 
263
343
  ### Focus Management
@@ -0,0 +1,89 @@
1
+ import '../../button/button.js';
2
+ import '../../list/list.js';
3
+ import '../../list/list-item.js';
4
+ import '../../list/list-item-content.js';
5
+ import '../../loading-spinner/loading-spinner.js';
6
+ import { css, html, LitElement, noChange } from 'lit';
7
+ import { guard } from 'lit/directives/guard.js';
8
+ import { LoadingCompleteMixin } from '../../../mixins/loading-complete/loading-complete-mixin.js';
9
+ import { until } from 'lit/directives/until.js';
10
+
11
+ class DialogAsyncContentUntil extends LoadingCompleteMixin(LitElement) {
12
+
13
+ static get properties() {
14
+ return {
15
+ href: { type: String }
16
+ };
17
+ }
18
+
19
+ static get styles() {
20
+ return css`
21
+ .content-button {
22
+ padding-block: 1rem;
23
+ }
24
+ .d2l-dialog-content-loading {
25
+ text-align: center;
26
+ }
27
+ `;
28
+ }
29
+
30
+ constructor() {
31
+ super();
32
+ this.href = null;
33
+ }
34
+
35
+ render() {
36
+ const loadingSpinner = html`
37
+ <div class="d2l-dialog-content-loading">
38
+ <d2l-loading-spinner size="100"></d2l-loading-spinner>
39
+ </div>
40
+ `;
41
+ return html`${guard([this.href], () => until(this._getContent(this.href), loadingSpinner, noChange))}`;
42
+ }
43
+
44
+ _getContent(href) {
45
+ return new Promise((resolve) => {
46
+ if (!href) return;
47
+ setTimeout(() => {
48
+ resolve(html`
49
+ <d2l-button class="content-button">Focus on me!</d2l-button>
50
+ <d2l-list>
51
+ <d2l-list-item>
52
+ <img slot="illustration" src="https://s.brightspace.com/course-images/images/38e839b1-37fa-470c-8830-b189ce4ae134/tile-high-density-max-size.jpg" @load="${this.#handleImageLoad}">
53
+ <d2l-list-item-content>
54
+ <div>Introductory Earth Sciences</div>
55
+ <div slot="supporting-info">This course explores the geological process of the Earth's interior and surface. These include volcanism, earthquakes, mountains...</div>
56
+ </d2l-list-item-content>
57
+ </d2l-list-item>
58
+ <d2l-list-item>
59
+ <img slot="illustration" src="https://s.brightspace.com/course-images/images/e5fd575a-bc14-4a80-89e1-46f349a76178/tile-high-density-max-size.jpg" @load="${this.#handleImageLoad}">
60
+ <d2l-list-item-content>
61
+ <div>Engineering Materials for Energy Systems</div>
62
+ <div slot="supporting-info">This course explores the geological processes of the Earth's interior and surface. These include volcanism, earthquakes, mountain...</div>
63
+ </d2l-list-item-content>
64
+ </d2l-list-item>
65
+ <d2l-list-item>
66
+ <img slot="illustration" src="https://s.brightspace.com/course-images/images/63b162ab-b582-4bf9-8c1d-1dad04714121/tile-high-density-max-size.jpg" @load="${this.#handleImageLoad}">
67
+ <d2l-list-item-content>
68
+ <div>Geomorphology and GIS </div>
69
+ <div slot="supporting-info">This course explores the geological processes of the Earth's interior and surface. These include volcanism, earthquakes, mountain...</div>
70
+ </d2l-list-item-content>
71
+ </d2l-list-item>
72
+ </d2l-list>
73
+ `);
74
+ }, 1000);
75
+ });
76
+ }
77
+
78
+ #handleImageLoad() {
79
+ const images = this.shadowRoot.querySelectorAll('img');
80
+ for (const image of images) {
81
+ if (!image.complete) return;
82
+ }
83
+ this.shadowRoot.querySelector('.content-button').focus();
84
+ this.resolveLoadingComplete();
85
+ }
86
+
87
+ }
88
+
89
+ customElements.define('d2l-dialog-demo-async-content-until', DialogAsyncContentUntil);
@@ -18,6 +18,7 @@
18
18
  import '../../list/demo/demo-list.js';
19
19
  import '../dialog.js';
20
20
  import './dialog-async-content.js';
21
+ import './dialog-async-content-until.js';
21
22
  import './dialog-container.js';
22
23
  </script>
23
24
  <style>
@@ -133,6 +134,28 @@
133
134
  </template>
134
135
  </d2l-demo-snippet>
135
136
 
137
+ <h2>Dialog (async using until)</h2>
138
+
139
+ <d2l-demo-snippet>
140
+ <template>
141
+ <d2l-button id="openAsyncUntil">Show Dialog</d2l-button>
142
+ <d2l-dialog id="dialogAsyncUntil" title-text="Dialog Title">
143
+ <d2l-dialog-demo-async-content-until></d2l-dialog-demo-async-content-until>
144
+ <d2l-button slot="footer" primary data-dialog-action="ok">Click Me!</d2l-button>
145
+ <d2l-button slot="footer" data-dialog-action>Cancel</d2l-button>
146
+ </d2l-dialog>
147
+ <script>
148
+ document.querySelector('#openAsyncUntil').addEventListener('click', () => {
149
+ document.querySelector('#dialogAsyncUntil').opened = true;
150
+ document.querySelector('d2l-dialog-demo-async-content-until').href = 'some-href';
151
+ });
152
+ document.querySelector('#dialogAsyncUntil').addEventListener('d2l-dialog-close', (e) => {
153
+ console.log('dialog action:', e.detail.action);
154
+ });
155
+ </script>
156
+ </template>
157
+ </d2l-demo-snippet>
158
+
136
159
  <h2>Dialog (intercept closing)</h2>
137
160
 
138
161
  <d2l-demo-snippet>
@@ -285,7 +285,7 @@ export const DropdownPopoverMixin = superclass => class extends LocalizeCoreElem
285
285
  case 'left': return 'inline-start';
286
286
  case 'right': return 'inline-end';
287
287
  default: return undefined;
288
- }
288
+ }
289
289
  }
290
290
 
291
291
  #adaptPositionSpan(val) {
@@ -293,7 +293,7 @@ export const DropdownPopoverMixin = superclass => class extends LocalizeCoreElem
293
293
  case 'start': return 'end';
294
294
  case 'end': return 'start';
295
295
  default: return 'all';
296
- }
296
+ }
297
297
  }
298
298
 
299
299
  #getMobileCloseButtonStyles() {
@@ -644,9 +644,7 @@ class Filter extends FocusMixin(LocalizeCoreElement(RtlMixin(LitElement))) {
644
644
  <div class="d2l-filter-dimension-set-value d2l-body-compact">
645
645
  <div class="d2l-filter-dimension-set-value-text">${item.text}</div>
646
646
  ${item.count !== undefined ? html`<div class="d2l-body-small">(${formatNumber(item.count)})</div>` : nothing}
647
- ${item.additionalContent
648
- ? html`<d2l-icon icon="${item.selected ? 'tier1:arrow-collapse-small' : 'tier1:arrow-expand-small'}" aria-hidden="true"></d2l-icon>`
649
- : nothing}
647
+ ${item.additionalContent ? html`<d2l-icon icon="${item.selected ? 'tier1:arrow-collapse-small' : 'tier1:arrow-expand-small'}" aria-hidden="true"></d2l-icon>` : nothing}
650
648
  </div>
651
649
  ${item.additionalContent ? html`
652
650
  <d2l-expand-collapse-content
@@ -658,9 +656,7 @@ class Filter extends FocusMixin(LocalizeCoreElement(RtlMixin(LitElement))) {
658
656
  ` : nothing}
659
657
  </div>
660
658
  </d2l-list-item>
661
- ${item.additionalContent && item.selected && this._displayKeyboardTooltip
662
- ? html`<d2l-tooltip align="start" announced for="${itemId}" for-type="descriptor" @d2l-tooltip-hide="${this._handleTooltipHide}">${this.localizeHTML('components.filter.additionalContentTooltip')}</d2l-tooltip>`
663
- : nothing}
659
+ ${item.additionalContent && item.selected && this._displayKeyboardTooltip ? html`<d2l-tooltip align="start" announced for="${itemId}" for-type="descriptor" @d2l-tooltip-hide="${this._handleTooltipHide}">${this.localizeHTML('components.filter.additionalContentTooltip')}</d2l-tooltip>` : nothing}
664
660
  `;
665
661
  }
666
662
 
@@ -1,4 +1,3 @@
1
- /* eslint-disable indent */
2
1
  import '../../button/button-icon.js';
3
2
  import '../../dropdown/dropdown-button-subtle.js';
4
3
  import '../../dropdown/dropdown-menu.js';
@@ -1982,6 +1982,31 @@
1982
1982
  }
1983
1983
  ]
1984
1984
  },
1985
+ {
1986
+ "name": "d2l-dialog-demo-async-content-until",
1987
+ "path": "./components/dialog/demo/dialog-async-content-until.js",
1988
+ "attributes": [
1989
+ {
1990
+ "name": "href",
1991
+ "type": "string"
1992
+ }
1993
+ ],
1994
+ "properties": [
1995
+ {
1996
+ "name": "href",
1997
+ "attribute": "href",
1998
+ "type": "string"
1999
+ },
2000
+ {
2001
+ "name": "loadingComplete",
2002
+ "type": "Promise<any>"
2003
+ },
2004
+ {
2005
+ "name": "resolveLoadingComplete",
2006
+ "type": "() => void"
2007
+ }
2008
+ ]
2009
+ },
1985
2010
  {
1986
2011
  "name": "d2l-dialog-demo-async-content",
1987
2012
  "path": "./components/dialog/demo/dialog-async-content.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "3.100.3",
3
+ "version": "3.101.0",
4
4
  "description": "A collection of accessible, free, open-source web components for building Brightspace applications",
5
5
  "type": "module",
6
6
  "repository": "https://github.com/BrightspaceUI/core.git",