@brightspace-ui/core 3.41.1 → 3.42.0
Sign up to get free protection for your applications and to get access to all the features.
- package/components/dialog/demo/dialog-confirm.html +1 -1
- package/components/dialog/demo/dialog.html +26 -0
- package/components/dialog/dialog-confirm.js +3 -1
- package/components/dialog/dialog-fullscreen.js +4 -1
- package/components/dialog/dialog-mixin.js +8 -0
- package/components/dialog/dialog-styles.js +6 -0
- package/components/dialog/dialog.js +2 -1
- package/custom-elements.json +15 -0
- package/package.json +1 -1
@@ -22,7 +22,7 @@
|
|
22
22
|
<d2l-demo-snippet>
|
23
23
|
<template>
|
24
24
|
<d2l-button id="openConfirm">Show Confirm</d2l-button>
|
25
|
-
<d2l-dialog-confirm id="confirm" text="Are you sure you want more cookies?">
|
25
|
+
<d2l-dialog-confirm id="confirm" title-text="Confirm Title" text="Are you sure you want more cookies?">
|
26
26
|
<d2l-button slot="footer" primary data-dialog-action="ok">Yes</d2l-button>
|
27
27
|
<d2l-button slot="footer" data-dialog-action>No</d2l-button>
|
28
28
|
</d2l-dialog-confirm>
|
@@ -247,6 +247,32 @@
|
|
247
247
|
</template>
|
248
248
|
</d2l-demo-snippet>
|
249
249
|
|
250
|
+
<h2>Dialog (overflowing content)</h2>
|
251
|
+
|
252
|
+
<d2l-demo-snippet>
|
253
|
+
<template>
|
254
|
+
<d2l-button id="openScrollFocus">Show Dialog</d2l-button>
|
255
|
+
<d2l-dialog title-text="My Dialog" id="dialogScrollFocus">
|
256
|
+
<p>Deadlights jack lad schooner scallywag dance the hempen jig carouser broadside cable strike colors. Bring a spring upon her cable holystone blow the man down spanker</p>
|
257
|
+
<p>Shiver me timbers to go on account lookout wherry doubloon chase. Belay yo-ho-ho keelhaul squiffy black spot yardarm spyglass sheet transom heave to.</p>
|
258
|
+
<p>Trysail Sail ho Corsair red ensign hulk smartly boom jib rum gangway. Case shot Shiver me timbers gangplank crack Jennys tea cup ballast Blimey lee snow crow's nest rutters. Fluke jib scourge of the seven seas boatswain schooner gaff booty Jack Tar transom spirits.</p>
|
259
|
+
<p>Deadlights jack lad schooner scallywag dance the hempen jig carouser broadside cable strike colors. Bring a spring upon her cable holystone blow the man down spanker</p>
|
260
|
+
<p>Shiver me timbers to go on account lookout wherry doubloon chase. Belay yo-ho-ho keelhaul squiffy black spot yardarm spyglass sheet transom heave to.</p>
|
261
|
+
<p>Trysail Sail ho Corsair red ensign hulk smartly boom jib rum gangway. Case shot Shiver me timbers gangplank crack Jennys tea cup ballast Blimey lee snow crow's nest rutters. Fluke jib scourge of the seven seas boatswain schooner gaff booty Jack Tar transom spirits.</p>
|
262
|
+
<p>Deadlights jack lad schooner scallywag dance the hempen jig carouser broadside cable strike colors. Bring a spring upon her cable holystone blow the man down spanker</p>
|
263
|
+
<p>Shiver me timbers to go on account lookout wherry doubloon chase. Belay yo-ho-ho keelhaul squiffy black spot yardarm spyglass sheet transom heave to.</p>
|
264
|
+
<p>Trysail Sail ho Corsair red ensign hulk smartly boom jib rum gangway. Case shot Shiver me timbers gangplank crack Jennys tea cup ballast Blimey lee snow crow's nest rutters. Fluke jib scourge of the seven seas boatswain schooner gaff booty Jack Tar transom spirits.</p>
|
265
|
+
<d2l-button slot="footer" primary data-dialog-action="ok">Click Me!</d2l-button>
|
266
|
+
<d2l-button slot="footer" data-dialog-action>Cancel</d2l-button>
|
267
|
+
</d2l-dialog>
|
268
|
+
<script>
|
269
|
+
document.querySelector('#openScrollFocus').addEventListener('click', () => {
|
270
|
+
document.querySelector('#dialogScrollFocus').opened = true;
|
271
|
+
});
|
272
|
+
</script>
|
273
|
+
</template>
|
274
|
+
</d2l-demo-snippet>
|
275
|
+
|
250
276
|
</d2l-demo-page>
|
251
277
|
</body>
|
252
278
|
</html>
|
@@ -3,6 +3,7 @@ import { css, html, LitElement, nothing } from 'lit';
|
|
3
3
|
import { DialogMixin } from './dialog-mixin.js';
|
4
4
|
import { dialogStyles } from './dialog-styles.js';
|
5
5
|
import { getUniqueId } from '../../helpers/uniqueId.js';
|
6
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
6
7
|
import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
|
7
8
|
|
8
9
|
/**
|
@@ -81,6 +82,7 @@ class DialogConfirm extends LocalizeCoreElement(DialogMixin(LitElement)) {
|
|
81
82
|
}
|
82
83
|
|
83
84
|
render() {
|
85
|
+
const contentTabIndex = !this.focusableContentElemPresent ? '0' : undefined;
|
84
86
|
const inner = html`
|
85
87
|
${this.critical ? html`<div id="${this._criticalLabelId}" hidden>${this.localize('components.dialog.critical')}</div>` : nothing}
|
86
88
|
<div class="d2l-dialog-inner">
|
@@ -88,7 +90,7 @@ class DialogConfirm extends LocalizeCoreElement(DialogMixin(LitElement)) {
|
|
88
90
|
<div class="d2l-dialog-header">
|
89
91
|
<div><h2 id="${this._titleId}" class="d2l-heading-3">${this.titleText}</h2></div>
|
90
92
|
</div>` : null}
|
91
|
-
<div id="${this._textId}" class="d2l-dialog-content">
|
93
|
+
<div id="${this._textId}" class="d2l-dialog-content" tabindex="${ifDefined(contentTabIndex)}">
|
92
94
|
<div>${this.text ? this.text.split('\n').map(line => html`<p>${line}</p>`) : null}</div>
|
93
95
|
</div>
|
94
96
|
<div class="d2l-dialog-footer">
|
@@ -7,6 +7,7 @@ import { classMap } from 'lit/directives/class-map.js';
|
|
7
7
|
import { DialogMixin } from './dialog-mixin.js';
|
8
8
|
import { dialogStyles } from './dialog-styles.js';
|
9
9
|
import { getUniqueId } from '../../helpers/uniqueId.js';
|
10
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
10
11
|
import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
|
11
12
|
import { PropertyRequiredMixin } from '../../mixins/property-required/property-required-mixin.js';
|
12
13
|
import { styleMap } from 'lit/directives/style-map.js';
|
@@ -256,6 +257,8 @@ class DialogFullscreen extends PropertyRequiredMixin(LocalizeCoreElement(AsyncCo
|
|
256
257
|
<div style=${styleMap(slotStyles)}><slot></slot></div>
|
257
258
|
`;
|
258
259
|
|
260
|
+
const contentTabIndex = !this.focusableContentElemPresent ? '0' : undefined;
|
261
|
+
|
259
262
|
const inner = html`
|
260
263
|
<div class="d2l-dialog-inner" style=${styleMap(heightOverride)}>
|
261
264
|
<div class="d2l-dialog-header">
|
@@ -264,7 +267,7 @@ class DialogFullscreen extends PropertyRequiredMixin(LocalizeCoreElement(AsyncCo
|
|
264
267
|
<d2l-button-icon icon="${this._icon}" text="${this.localize('components.dialog.close')}" @click="${this._abort}"></d2l-button-icon>
|
265
268
|
</div>
|
266
269
|
</div>
|
267
|
-
<div class="d2l-dialog-content" @pending-state="${this._handleAsyncItemState}">${content}</div>
|
270
|
+
<div class="d2l-dialog-content" @pending-state="${this._handleAsyncItemState}" tabindex="${ifDefined(contentTabIndex)}">${content}</div>
|
268
271
|
<div class="${classMap(footerClasses)}">
|
269
272
|
<slot name="footer" @slotchange="${this._handleFooterSlotChange}"></slot>
|
270
273
|
</div>
|
@@ -33,6 +33,10 @@ export const DialogMixin = superclass => class extends RtlMixin(superclass) {
|
|
33
33
|
|
34
34
|
static get properties() {
|
35
35
|
return {
|
36
|
+
/**
|
37
|
+
* @ignore
|
38
|
+
*/
|
39
|
+
focusableContentElemPresent: { state: true },
|
36
40
|
/**
|
37
41
|
* Whether or not the dialog is open
|
38
42
|
*/
|
@@ -64,6 +68,7 @@ export const DialogMixin = superclass => class extends RtlMixin(superclass) {
|
|
64
68
|
|
65
69
|
constructor() {
|
66
70
|
super();
|
71
|
+
this.focusableContentElemPresent = false;
|
67
72
|
this.opened = false;
|
68
73
|
this._autoSize = true;
|
69
74
|
this._dialogId = getUniqueId();
|
@@ -219,6 +224,9 @@ export const DialogMixin = superclass => class extends RtlMixin(superclass) {
|
|
219
224
|
const content = this.shadowRoot.querySelector('.d2l-dialog-content');
|
220
225
|
if (content) {
|
221
226
|
const elementToFocus = this._findAutofocusElement(content) ?? getNextFocusable(content);
|
227
|
+
if (isComposedAncestor(this.shadowRoot.querySelector('.d2l-dialog-content'), elementToFocus)) {
|
228
|
+
this.focusableContentElemPresent = true;
|
229
|
+
}
|
222
230
|
if (isComposedAncestor(this.shadowRoot.querySelector('.d2l-dialog-inner'), elementToFocus)) {
|
223
231
|
this._focusElemOrDescendant(elementToFocus);
|
224
232
|
return;
|
@@ -132,6 +132,12 @@ export const dialogStyles = css`
|
|
132
132
|
padding: 0 30px;
|
133
133
|
}
|
134
134
|
|
135
|
+
.d2l-dialog-content:focus-visible {
|
136
|
+
border-radius: 6px;
|
137
|
+
outline: 2px solid var(--d2l-color-celestine);
|
138
|
+
outline-offset: -2px;
|
139
|
+
}
|
140
|
+
|
135
141
|
.d2l-dialog-content > div {
|
136
142
|
position: relative; /* make this the positioned parent for absolute positioned elements like d2l-template-primary-secondary */
|
137
143
|
}
|
@@ -170,6 +170,7 @@ class Dialog extends PropertyRequiredMixin(LocalizeCoreElement(AsyncContainerMix
|
|
170
170
|
<div id="${ifDefined(this._textId)}" style=${styleMap(slotStyles)}><slot></slot></div>
|
171
171
|
`;
|
172
172
|
|
173
|
+
const contentTabIndex = !this.focusableContentElemPresent ? '0' : undefined;
|
173
174
|
const labelId = this.critical ? `${this._criticalLabelId} ${this._titleId}` : this._titleId;
|
174
175
|
const inner = html`
|
175
176
|
${this.critical ? html`<div id="${this._criticalLabelId}" hidden>${this.localize('components.dialog.critical')}</div>` : nothing}
|
@@ -180,7 +181,7 @@ class Dialog extends PropertyRequiredMixin(LocalizeCoreElement(AsyncContainerMix
|
|
180
181
|
<d2l-button-icon icon="tier1:close-small" text="${this.localize('components.dialog.close')}" @click="${this._abort}"></d2l-button-icon>
|
181
182
|
</div>
|
182
183
|
</div>
|
183
|
-
<div class="d2l-dialog-content" @pending-state="${this._handleAsyncItemState}">${content}</div>
|
184
|
+
<div class="d2l-dialog-content" @pending-state="${this._handleAsyncItemState}" tabindex="${ifDefined(contentTabIndex)}">${content}</div>
|
184
185
|
<div class="${classMap(footerClasses)}">
|
185
186
|
<slot name="footer" @slotchange="${this._handleFooterSlotChange}"></slot>
|
186
187
|
</div>
|
package/custom-elements.json
CHANGED
@@ -2008,6 +2008,11 @@
|
|
2008
2008
|
"description": "The optional title for the dialog",
|
2009
2009
|
"type": "string"
|
2010
2010
|
},
|
2011
|
+
{
|
2012
|
+
"name": "focusableContentElemPresent",
|
2013
|
+
"type": "boolean",
|
2014
|
+
"default": "false"
|
2015
|
+
},
|
2011
2016
|
{
|
2012
2017
|
"name": "opened",
|
2013
2018
|
"attribute": "opened",
|
@@ -2109,6 +2114,11 @@
|
|
2109
2114
|
"description": "REQUIRED: the title for the dialog",
|
2110
2115
|
"type": "string"
|
2111
2116
|
},
|
2117
|
+
{
|
2118
|
+
"name": "focusableContentElemPresent",
|
2119
|
+
"type": "boolean",
|
2120
|
+
"default": "false"
|
2121
|
+
},
|
2112
2122
|
{
|
2113
2123
|
"name": "opened",
|
2114
2124
|
"attribute": "opened",
|
@@ -2240,6 +2250,11 @@
|
|
2240
2250
|
"description": "REQUIRED: the title for the dialog",
|
2241
2251
|
"type": "string"
|
2242
2252
|
},
|
2253
|
+
{
|
2254
|
+
"name": "focusableContentElemPresent",
|
2255
|
+
"type": "boolean",
|
2256
|
+
"default": "false"
|
2257
|
+
},
|
2243
2258
|
{
|
2244
2259
|
"name": "opened",
|
2245
2260
|
"attribute": "opened",
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@brightspace-ui/core",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.42.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",
|