@brightspace-ui/core 3.239.0 → 3.240.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.
@@ -129,7 +129,12 @@ const lightVariables = new Map([
129
129
  ['--d2l-theme-shadow-attached', '0 2px 4px 0 rgba(0, 0, 0, 0.03)'],
130
130
  ['--d2l-theme-shadow-attached-block-start', '0 2px 4px 0 rgba(0, 0, 0, 0.03)'],
131
131
  ['--d2l-theme-shadow-attached-block-end', '0 -2px 4px 0 rgba(0, 0, 0, 0.03)'],
132
- ['--d2l-theme-shadow-floating', '0 2px 12px 0 rgba(0, 0, 0, 0.15)'],
132
+ ['--d2l-theme-shadow-floating-offset-x', '0'],
133
+ ['--d2l-theme-shadow-floating-offset-y', '2px'],
134
+ ['--d2l-theme-shadow-floating-blur-radius', '12px'],
135
+ ['--d2l-theme-shadow-floating-spread-radius', '0'],
136
+ ['--d2l-theme-shadow-floating-color', 'rgba(0, 0, 0, 0.15)'],
137
+ ['--d2l-theme-shadow-floating', 'var(--d2l-theme-shadow-floating-offset-x) var(--d2l-theme-shadow-floating-offset-y) var(--d2l-theme-shadow-floating-blur-radius) var(--d2l-theme-shadow-floating-spread-radius) var(--d2l-theme-shadow-floating-color)'],
133
138
  ['--d2l-theme-shadow-inset-offset-x', '0'],
134
139
  ['--d2l-theme-shadow-inset-offset-y', '2px'],
135
140
  ['--d2l-theme-shadow-inset-blur-radius', '0'],
@@ -204,7 +209,12 @@ const darkVariables = new Map([
204
209
  ['--d2l-theme-shadow-attached', '0 2px 4px 0 rgba(0, 0, 0, 0.85)'],
205
210
  ['--d2l-theme-shadow-attached-block-start', '0 2px 4px 0 rgba(0, 0, 0, 0.85)'],
206
211
  ['--d2l-theme-shadow-attached-block-end', '0 -2px 4px 0 rgba(0, 0, 0, 0.85)'],
207
- ['--d2l-theme-shadow-floating', '0 2px 12px 0 rgba(0, 0, 0, 0.85)'],
212
+ ['--d2l-theme-shadow-floating-offset-x', '0'],
213
+ ['--d2l-theme-shadow-floating-offset-y', '2px'],
214
+ ['--d2l-theme-shadow-floating-blur-radius', '12px'],
215
+ ['--d2l-theme-shadow-floating-spread-radius', '0'],
216
+ ['--d2l-theme-shadow-floating-color', 'rgba(0, 0, 0, 0.85)'],
217
+ ['--d2l-theme-shadow-floating', 'var(--d2l-theme-shadow-floating-offset-x) var(--d2l-theme-shadow-floating-offset-y) var(--d2l-theme-shadow-floating-blur-radius) var(--d2l-theme-shadow-floating-spread-radius) var(--d2l-theme-shadow-floating-color)'],
208
218
  ['--d2l-theme-shadow-inset-offset-x', '0'],
209
219
  ['--d2l-theme-shadow-inset-offset-y', '2px'],
210
220
  ['--d2l-theme-shadow-inset-blur-radius', '0'],
@@ -2,6 +2,8 @@ import { _generateResetStyles, heading3Styles } from '../typography/styles.js';
2
2
  import { css, html, LitElement, nothing } from 'lit';
3
3
  import { DialogMixin } from './dialog-mixin.js';
4
4
  import { dialogStyles } from './dialog-styles.js';
5
+ import { getFlag } from '../../helpers/flags.js';
6
+ import { getFocusRingStyles } from '../../helpers/focus.js';
5
7
  import { getUniqueId } from '../../helpers/uniqueId.js';
6
8
  import { ifDefined } from 'lit/directives/if-defined.js';
7
9
  import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
@@ -35,11 +37,25 @@ class DialogConfirm extends LocalizeCoreElement(DialogMixin(LitElement)) {
35
37
  max-width: 420px;
36
38
  }
37
39
 
38
- .d2l-dialog-content > div {
40
+ .d2l-dialog-header > h2 {
41
+ margin: 0;
42
+ width: fit-content;
43
+ }
44
+
45
+ ${getFocusRingStyles(pseudoClass => `.d2l-dialog-content:${pseudoClass} > div`, { extraStyles: css`
46
+
47
+ --d2l-focus-ring-offset: -1px; border-radius: 6px;`
48
+ })}
49
+ .d2l-dialog-content:focus,
50
+ .d2l-dialog-content:focus-visible {
51
+ outline: none;
52
+ }
53
+
54
+ .d2l-dialog-content {
39
55
  padding-top: 30px;
40
56
  }
41
57
 
42
- .d2l-dialog-header + .d2l-dialog-content > div {
58
+ .d2l-dialog-header + .d2l-dialog-content {
43
59
  padding-top: 0;
44
60
  }
45
61
 
@@ -64,7 +80,7 @@ class DialogConfirm extends LocalizeCoreElement(DialogMixin(LitElement)) {
64
80
  top: 0;
65
81
  }
66
82
 
67
- .d2l-dialog-content > div {
83
+ .d2l-dialog-content {
68
84
  padding-top: 20px;
69
85
  }
70
86
 
@@ -76,21 +92,37 @@ class DialogConfirm extends LocalizeCoreElement(DialogMixin(LitElement)) {
76
92
  constructor() {
77
93
  super();
78
94
  this.critical = false;
95
+ this.preferNative = getFlag('GAUD-9644-prefer-native-confirm-dialogs', false);
79
96
  this._criticalLabelId = getUniqueId();
80
97
  this._textId = getUniqueId();
81
98
  this._titleId = getUniqueId();
82
99
  }
83
100
 
84
101
  render() {
85
- const contentTabIndex = !this.focusableContentElemPresent ? '0' : undefined;
102
+ let contentTabIndex = undefined;
103
+ let titleTabIndex = undefined;
104
+ let contentAutofocus = false;
105
+ let titleAutofocus = false;
106
+ if (this._useNative) {
107
+ if (this.titleText) {
108
+ titleTabIndex = '-1';
109
+ titleAutofocus = true;
110
+ } else {
111
+ contentTabIndex = '-1';
112
+ contentAutofocus = true;
113
+ }
114
+ } else {
115
+ contentTabIndex = !this.focusableContentElemPresent ? '0' : undefined;
116
+ }
117
+
86
118
  const inner = html`
87
119
  ${this.critical ? html`<div id="${this._criticalLabelId}" hidden>${this.localize('components.dialog.critical')}</div>` : nothing}
88
120
  <div class="d2l-dialog-inner">
89
121
  ${this.titleText ? html`
90
122
  <div class="d2l-dialog-header">
91
- <div><h2 id="${this._titleId}" class="d2l-heading-3">${this.titleText}</h2></div>
123
+ <h2 id="${this._titleId}" class="d2l-heading-3" tabindex="${ifDefined(titleTabIndex)}" ?autofocus="${titleAutofocus}">${this.titleText}</h2>
92
124
  </div>` : null}
93
- <div id="${this._textId}" class="d2l-dialog-content" tabindex="${ifDefined(contentTabIndex)}">
125
+ <div id="${this._textId}" class="d2l-dialog-content" tabindex="${ifDefined(contentTabIndex)}" ?autofocus="${contentAutofocus}">
94
126
  <div>${this.text ? this.text.split('\n').map(line => html`<p>${line}</p>`) : null}</div>
95
127
  </div>
96
128
  <div class="d2l-dialog-footer">
@@ -113,7 +145,7 @@ class DialogConfirm extends LocalizeCoreElement(DialogMixin(LitElement)) {
113
145
  }
114
146
 
115
147
  _focusInitial() {
116
- if (!this.shadowRoot) return;
148
+ if (!this.shadowRoot || this._useNative) return;
117
149
  const footer = this.shadowRoot.querySelector('.d2l-dialog-footer-slot');
118
150
  const nodes = footer.assignedNodes();
119
151
  for (let i = 0; i < nodes.length; i++) {
@@ -193,6 +193,7 @@ class DialogFullscreen extends PropertyRequiredMixin(LocalizeCoreElement(AsyncCo
193
193
  super();
194
194
  this.async = false;
195
195
  this.noPadding = false;
196
+ this.preferNative = false;
196
197
  this._autoSize = false;
197
198
  this._hasFooterContent = false;
198
199
  this._icon = 'tier1:close-large-thick';
@@ -19,10 +19,7 @@ window.D2L.DialogMixin = window.D2L.DialogMixin || {};
19
19
  // https://bugs.webkit.org/show_bug.cgi?id=233320
20
20
  // starting in Chrome 102, all elements inside <dialog>s that are inside shadow roots have null offsetParent
21
21
  // https://bugs.chromium.org/p/chromium/issues/detail?id=1331803
22
- window.D2L.DialogMixin.hasNative = false;
23
- if (window.D2L.DialogMixin.preferNative === undefined) {
24
- window.D2L.DialogMixin.preferNative = true;
25
- }
22
+ window.D2L.DialogMixin.hasNative = (window.HTMLDialogElement !== undefined);
26
23
 
27
24
  const reduceMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;
28
25
  const abortAction = 'abort';
@@ -44,6 +41,11 @@ export const DialogMixin = superclass => class extends superclass {
44
41
  * ADVANCED: Opt out of dialog content scrolling
45
42
  */
46
43
  noContentScroll: { type: Boolean, attribute: 'no-content-scroll', reflect: true },
44
+ /**
45
+ * @ignore
46
+ * Do NOT use this
47
+ */
48
+ preferNative: { type: Boolean, attribute: 'prefer-native' },
47
49
  /**
48
50
  * The optional title for the dialog
49
51
  */
@@ -72,6 +74,7 @@ export const DialogMixin = superclass => class extends superclass {
72
74
  this.focusableContentElemPresent = false;
73
75
  this.noContentScroll = false;
74
76
  this.opened = false;
77
+ this.preferNative = false;
75
78
  this._autoSize = true;
76
79
  this._dialogId = getUniqueId();
77
80
  this._fullscreenWithin = 0;
@@ -91,7 +94,6 @@ export const DialogMixin = superclass => class extends superclass {
91
94
  this._top = 0;
92
95
  this._updateOverflow = this._updateOverflow.bind(this);
93
96
  this._updateSize = this._updateSize.bind(this);
94
- this._useNative = (window.D2L.DialogMixin.hasNative && window.D2L.DialogMixin.preferNative);
95
97
  this._width = 0;
96
98
  }
97
99
 
@@ -127,6 +129,13 @@ export const DialogMixin = superclass => class extends superclass {
127
129
  }
128
130
  }
129
131
 
132
+ willUpdate(changedProperties) {
133
+ super.willUpdate(changedProperties);
134
+ if (this.#useNativeInitialized) return;
135
+ this._useNative = (window.D2L.DialogMixin.hasNative && this.preferNative);
136
+ this.#useNativeInitialized = true;
137
+ }
138
+
130
139
  open() {
131
140
  if (this.opened) return;
132
141
  this.opened = true;
@@ -155,6 +164,8 @@ export const DialogMixin = superclass => class extends superclass {
155
164
  await Promise.all(composedChildren.map(child => waitForElem(child, predicate)));
156
165
  }
157
166
 
167
+ #useNativeInitialized = false;
168
+
158
169
  _addHandlers() {
159
170
  window.addEventListener('resize', this._updateSize);
160
171
  this.addEventListener('touchstart', this._handleTouchStart);
@@ -387,7 +398,7 @@ export const DialogMixin = superclass => class extends superclass {
387
398
  return abortEvent.defaultPrevented;
388
399
  }
389
400
 
390
- _open() {
401
+ async _open() {
391
402
  if (!this.opened) return;
392
403
 
393
404
  this._opener = getComposedActiveElement();
@@ -411,6 +422,8 @@ export const DialogMixin = superclass => class extends superclass {
411
422
  });
412
423
 
413
424
  if (this._useNative) {
425
+ this._state = 'showing';
426
+ await this.updateComplete;
414
427
  dialog.showModal();
415
428
  }
416
429
 
@@ -432,7 +445,7 @@ export const DialogMixin = superclass => class extends superclass {
432
445
  }, 0);
433
446
 
434
447
  await this._updateSize();
435
- this._state = 'showing';
448
+ if (!this._useNative) this._state = 'showing';
436
449
  await this.updateComplete;
437
450
 
438
451
  // edge case: no children were focused, try again after one redraw
@@ -103,6 +103,7 @@ class Dialog extends PropertyRequiredMixin(LocalizeCoreElement(AsyncContainerMix
103
103
  this.critical = false;
104
104
  this.describeContent = false;
105
105
  this.fullHeight = false;
106
+ this.preferNative = false;
106
107
  this.width = 600;
107
108
  this._criticalLabelId = getUniqueId();
108
109
  this._handleResize = this._handleResize.bind(this);
@@ -40,7 +40,7 @@ class DropdownButton extends DropdownOpenerMixin(LitElement) {
40
40
  width: 0.8rem;
41
41
  }
42
42
  :host([primary]) d2l-icon {
43
- color: white;
43
+ color: var(--d2l-theme-text-color-static-inverted);
44
44
  }
45
45
  d2l-button {
46
46
  width: 100%;
@@ -82,11 +82,11 @@ export const PopoverMixin = superclass => class extends superclass {
82
82
  return css`
83
83
  :host {
84
84
  --d2l-popover-default-animation-name: d2l-popover-animation;
85
- --d2l-popover-default-background-color: #ffffff;
86
- --d2l-popover-default-border-color: var(--d2l-color-mica);
85
+ --d2l-popover-default-background-color: var(--d2l-theme-background-color-base);
86
+ --d2l-popover-default-border-color: var(--d2l-theme-border-color-standard);
87
87
  --d2l-popover-default-border-radius: 0.3rem;
88
- --d2l-popover-default-foreground-color: var(--d2l-color-ferrite);
89
- --d2l-popover-default-shadow-color: rgba(0, 0, 0, 0.15);
88
+ --d2l-popover-default-foreground-color: var(--d2l-theme-text-color-static-standard);
89
+ --d2l-popover-default-shadow-color: var(--d2l-theme-shadow-floating-color);
90
90
  background-color: transparent; /* override popover default */
91
91
  border: none; /* override popover */
92
92
  box-sizing: border-box;
@@ -131,7 +131,7 @@ export const PopoverMixin = superclass => class extends superclass {
131
131
  background-color: var(--d2l-popover-background-color, var(--d2l-popover-default-background-color));
132
132
  border: 1px solid var(--d2l-popover-border-color, var(--d2l-popover-default-border-color));
133
133
  border-radius: var(--d2l-popover-border-radius, var(--d2l-popover-default-border-radius));
134
- box-shadow: 0 2px 12px 0 var(--d2l-popover-shadow-color, var(--d2l-popover-default-shadow-color));
134
+ box-shadow: var(--d2l-theme-shadow-floating-offset-x) var(--d2l-theme-shadow-floating-offset-y) var(--d2l-theme-shadow-floating-blur-radius) var(--d2l-theme-shadow-floating-spread-radius) var(--d2l-popover-shadow-color, var(--d2l-popover-default-shadow-color));
135
135
  box-sizing: border-box;
136
136
  display: flex;
137
137
  max-width: 370px;
@@ -170,7 +170,7 @@ export const PopoverMixin = superclass => class extends superclass {
170
170
  background-color: var(--d2l-popover-background-color, var(--d2l-popover-default-background-color));
171
171
  border: 1px solid var(--d2l-popover-border-color, var(--d2l-popover-default-border-color));
172
172
  border-radius: 0.1rem;
173
- box-shadow: -4px -4px 12px -5px rgba(32, 33, 34, 0.2); /* ferrite */
173
+ box-shadow: -4px -4px 12px -5px var(--d2l-theme-shadow-floating-color);
174
174
  height: ${pointerLength}px;
175
175
  outline: var(--d2l-popover-outline-width, 0) solid var(--d2l-popover-outline-color, transparent);
176
176
  transform: rotate(45deg);
@@ -178,7 +178,7 @@ export const PopoverMixin = superclass => class extends superclass {
178
178
  }
179
179
 
180
180
  :host([_location="block-start"]) .pointer > div {
181
- box-shadow: 4px 4px 12px -5px rgba(32, 33, 34, 0.2); /* ferrite */
181
+ box-shadow: 4px 4px 12px -5px var(--d2l-theme-shadow-floating-color);
182
182
  }
183
183
 
184
184
  @keyframes d2l-popover-animation {
@@ -2548,6 +2548,10 @@
2548
2548
  "description": "Whether or not the dialog is open",
2549
2549
  "type": "boolean",
2550
2550
  "default": "false"
2551
+ },
2552
+ {
2553
+ "name": "preferNative",
2554
+ "default": "false"
2551
2555
  }
2552
2556
  ],
2553
2557
  "events": [
@@ -2667,6 +2671,11 @@
2667
2671
  "description": "Whether or not the dialog is open",
2668
2672
  "type": "boolean",
2669
2673
  "default": "false"
2674
+ },
2675
+ {
2676
+ "name": "preferNative",
2677
+ "type": "boolean",
2678
+ "default": "false"
2670
2679
  }
2671
2680
  ],
2672
2681
  "events": [
@@ -2816,6 +2825,11 @@
2816
2825
  "description": "Whether or not the dialog is open",
2817
2826
  "type": "boolean",
2818
2827
  "default": "false"
2828
+ },
2829
+ {
2830
+ "name": "preferNative",
2831
+ "type": "boolean",
2832
+ "default": "false"
2819
2833
  }
2820
2834
  ],
2821
2835
  "events": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "3.239.0",
3
+ "version": "3.240.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",