@brightspace-ui/core 3.219.10 → 3.220.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.
@@ -2,11 +2,15 @@ import '../colors/colors.js';
2
2
  import '../loading-spinner/loading-spinner.js';
3
3
  import { css, html, LitElement, nothing } from 'lit';
4
4
  import { getOffsetParent } from '../../helpers/dom.js';
5
+ import { styleMap } from 'lit/directives/style-map.js';
5
6
 
6
7
  const BACKDROP_DELAY_MS = 800;
7
8
  const FADE_DURATION_MS = 500;
8
9
  const SPINNER_DELAY_MS = FADE_DURATION_MS;
9
10
 
11
+ const LOADING_SPINNER_MINIMUM_BUFFER = 100;
12
+ const LOADING_SPINNER_SIZE = 50;
13
+
10
14
  const reduceMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;
11
15
 
12
16
  /**
@@ -22,6 +26,7 @@ class LoadingBackdrop extends LitElement {
22
26
  */
23
27
  shown: { type: Boolean },
24
28
  _state: { type: String, reflect: true },
29
+ _spinnerTop: { state: true }
25
30
  };
26
31
  }
27
32
 
@@ -58,7 +63,6 @@ class LoadingBackdrop extends LitElement {
58
63
  d2l-loading-spinner {
59
64
  opacity: 0;
60
65
  position: absolute;
61
- top: 100px;
62
66
  transition: opacity ${FADE_DURATION_MS}ms ease-in ${SPINNER_DELAY_MS}ms;
63
67
  }
64
68
  :host([_state="shown"]) d2l-loading-spinner {
@@ -80,16 +84,16 @@ class LoadingBackdrop extends LitElement {
80
84
  super();
81
85
  this.shown = false;
82
86
  this._state = 'hidden';
87
+ this._spinnerTop = LOADING_SPINNER_MINIMUM_BUFFER;
83
88
  }
84
89
 
85
90
  render() {
86
91
  if (this._state === 'hidden') return nothing;
87
92
  return html`
88
- <div class="backdrop" @transitionend="${this.#handleTransitionEnd}" @transitioncancel="${this.#hide}"></div>
89
- <d2l-loading-spinner></d2l-loading-spinner>
93
+ <div class="backdrop" @transitionend="${this.#handleTransitionEnd}" @transitioncancel="${this.#hide}" size="${LOADING_SPINNER_SIZE}"></div>
94
+ <d2l-loading-spinner style=${styleMap({ top: `${this._spinnerTop}px` })}></d2l-loading-spinner>
90
95
  `;
91
96
  }
92
-
93
97
  updated(changedProperties) {
94
98
  if (changedProperties.has('_state')) {
95
99
  if (this._state === 'showing') {
@@ -98,8 +102,13 @@ class LoadingBackdrop extends LitElement {
98
102
  }, BACKDROP_DELAY_MS);
99
103
  }
100
104
  }
101
- }
102
105
 
106
+ if (changedProperties.has('shown') && (
107
+ (reduceMotion && this._state === 'shown') || (!reduceMotion && this._state === 'showing')
108
+ )) {
109
+ this.#centerLoadingSpinner();
110
+ }
111
+ }
103
112
  willUpdate(changedProperties) {
104
113
  if (changedProperties.has('shown')) {
105
114
  if (this.shown) {
@@ -110,6 +119,30 @@ class LoadingBackdrop extends LitElement {
110
119
  }
111
120
  }
112
121
 
122
+ #centerLoadingSpinner() {
123
+ if (this._state === 'hidden') { return; }
124
+
125
+ const loadingSpinner = this.shadowRoot.querySelector('d2l-loading-spinner');
126
+ if (!loadingSpinner) { return; }
127
+
128
+ const boundingRect = this.getBoundingClientRect();
129
+
130
+ // Calculate the centerpoint of the visible portion of the element
131
+ const upperVisibleBound = Math.max(0, boundingRect.top);
132
+ const lowerVisibleBound = Math.min(window.innerHeight, boundingRect.bottom);
133
+ const visibleHeight = lowerVisibleBound - upperVisibleBound;
134
+ const centeringOffset = visibleHeight / 2;
135
+
136
+ // Calculate if an offset is required to move to the top of the viewport before centering
137
+ const topOffset = Math.max(0, -boundingRect.top); // measures the distance below the top of the viewport, which is negative if the element starts above the viewport
138
+
139
+ // Adjust for the size of the spinner
140
+ const spinnerSizeOffset = LOADING_SPINNER_SIZE / 2;
141
+
142
+ const newPosition = centeringOffset + topOffset - spinnerSizeOffset;
143
+ this._spinnerTop = Math.max(LOADING_SPINNER_MINIMUM_BUFFER, newPosition);
144
+ }
145
+
113
146
  #fade() {
114
147
  let hideImmediately = reduceMotion || this._state === 'showing';
115
148
  if (this._state === 'shown') {
@@ -123,13 +156,11 @@ class LoadingBackdrop extends LitElement {
123
156
  this._state = 'hiding';
124
157
  }
125
158
  }
126
-
127
159
  #handleTransitionEnd() {
128
160
  if (this._state === 'hiding') {
129
161
  this.#hide();
130
162
  }
131
163
  }
132
-
133
164
  #hide() {
134
165
  this._state = 'hidden';
135
166
 
@@ -137,7 +168,6 @@ class LoadingBackdrop extends LitElement {
137
168
 
138
169
  if (containingBlock.dataset.initiallyInert !== '1') containingBlock.removeAttribute('inert');
139
170
  }
140
-
141
171
  #show() {
142
172
  this._state = reduceMotion ? 'shown' : 'showing';
143
173
 
@@ -38,6 +38,106 @@
38
38
  <td class="grade">85%</td>
39
39
  <td>100</td>
40
40
  </tr>
41
+ <tr>
42
+ <td>Math</td>
43
+ <td class="grade">85%</td>
44
+ <td>100</td>
45
+ </tr>
46
+ <tr>
47
+ <td>Math</td>
48
+ <td class="grade">85%</td>
49
+ <td>100</td>
50
+ </tr>
51
+ <tr>
52
+ <td>Math</td>
53
+ <td class="grade">85%</td>
54
+ <td>100</td>
55
+ </tr>
56
+ <tr>
57
+ <td>Math</td>
58
+ <td class="grade">85%</td>
59
+ <td>100</td>
60
+ </tr>
61
+ <tr>
62
+ <td>Math</td>
63
+ <td class="grade">85%</td>
64
+ <td>100</td>
65
+ </tr>
66
+ <tr>
67
+ <td>Math</td>
68
+ <td class="grade">85%</td>
69
+ <td>100</td>
70
+ </tr>
71
+ <tr>
72
+ <td>Math</td>
73
+ <td class="grade">85%</td>
74
+ <td>100</td>
75
+ </tr>
76
+ <tr>
77
+ <td>Math</td>
78
+ <td class="grade">85%</td>
79
+ <td>100</td>
80
+ </tr>
81
+ <tr>
82
+ <td>Math</td>
83
+ <td class="grade">85%</td>
84
+ <td>100</td>
85
+ </tr>
86
+ <tr>
87
+ <td>Math</td>
88
+ <td class="grade">85%</td>
89
+ <td>100</td>
90
+ </tr>
91
+ <tr>
92
+ <td>Math</td>
93
+ <td class="grade">85%</td>
94
+ <td>100</td>
95
+ </tr>
96
+ <tr>
97
+ <td>Math</td>
98
+ <td class="grade">85%</td>
99
+ <td>100</td>
100
+ </tr>
101
+ <tr>
102
+ <td>Math</td>
103
+ <td class="grade">85%</td>
104
+ <td>100</td>
105
+ </tr>
106
+ <tr>
107
+ <td>Math</td>
108
+ <td class="grade">85%</td>
109
+ <td>100</td>
110
+ </tr>
111
+ <tr>
112
+ <td>Math</td>
113
+ <td class="grade">85%</td>
114
+ <td>100</td>
115
+ </tr>
116
+ <tr>
117
+ <td>Math</td>
118
+ <td class="grade">85%</td>
119
+ <td>100</td>
120
+ </tr>
121
+ <tr>
122
+ <td>Math</td>
123
+ <td class="grade">85%</td>
124
+ <td>100</td>
125
+ </tr>
126
+ <tr>
127
+ <td>Math</td>
128
+ <td class="grade">85%</td>
129
+ <td>100</td>
130
+ </tr>
131
+ <tr>
132
+ <td>Math</td>
133
+ <td class="grade">85%</td>
134
+ <td>100</td>
135
+ </tr>
136
+ <tr>
137
+ <td>Math</td>
138
+ <td class="grade">85%</td>
139
+ <td>100</td>
140
+ </tr>
41
141
  <tr>
42
142
  <td>Art</td>
43
143
  <td class="grade">98%</td>
@@ -3,16 +3,128 @@ if (globalThis.document !== undefined && !globalThis.document.head.querySelector
3
3
  style.id = 'd2l-colors';
4
4
 
5
5
  const lightPalette = `
6
- --d2l-color-background-base: var(--d2l-color-sylvite);
7
- --d2l-color-background-default: #ffffff;
8
- --d2l-color-border-medium: var(--d2l-color-mica);
9
- --d2l-color-font-base: var(--d2l-color-ferrite);
6
+ --d2l-sem-background-color-base: #ffffff;
7
+ --d2l-sem-background-color-elevated: var(--d2l-sem-background-color-base);
8
+ --d2l-sem-background-color-floating: var(--d2l-sem-background-color-base);
9
+ --d2l-sem-background-color-interactive-faint-default: var(--d2l-color-regolith);
10
+ --d2l-sem-background-color-interactive-faint-hover: var(--d2l-color-sylvite);
11
+ --d2l-sem-background-color-interactive-highlighted: var(--d2l-sem-brand-color-highlight);
12
+ --d2l-sem-background-color-interactive-primary-default: var(--d2l-sem-brand-color-primary-default);
13
+ --d2l-sem-background-color-interactive-primary-hover: var(--d2l-sem-brand-color-primary-hover);
14
+ --d2l-sem-background-color-interactive-secondary-default: var(--d2l-color-gypsum);
15
+ --d2l-sem-background-color-interactive-secondary-hover: var(--d2l-color-mica);
16
+ --d2l-sem-background-color-interactive-tertiary-default: #ffffff;
17
+ --d2l-sem-background-color-interactive-tertiary-hover: var(--d2l-sem-background-color-interactive-secondary-default);
18
+ --d2l-sem-background-color-interactive-translucent-default: #000000;
19
+ --d2l-sem-background-color-interactive-translucent-hover: var(--d2l-sem-brand-color-primary-default);
20
+ --d2l-sem-background-color-sunken: #f6f7f8;
21
+ --d2l-sem-border-color-emphasized: var(--d2l-color-galena);
22
+ --d2l-sem-border-color-focus: var(--d2l-color-celestine);
23
+ --d2l-sem-border-color-standard: var(--d2l-color-mica);
24
+ --d2l-sem-border-color-subtle: var(--d2l-color-gypsum);
25
+ --d2l-sem-brand-color-highlight: var(--d2l-color-celestine-plus-2);
26
+ --d2l-sem-brand-color-primary-default: var(--d2l-color-celestine);
27
+ --d2l-sem-brand-color-primary-hover: var(--d2l-color-celestine-minus-1);
28
+ --d2l-sem-icon-color-faint: var(--d2l-sem-border-color-standard);
29
+ --d2l-sem-icon-color-inverted: #ffffff;
30
+ --d2l-sem-icon-color-standard: var(--d2l-color-tungsten);
31
+ --d2l-sem-status-color-default: var(--d2l-color-celestine);
32
+ --d2l-sem-status-color-error: var(--d2l-color-cinnabar);
33
+ --d2l-sem-status-color-success-text: var(--d2l-color-olivine-minus-1);
34
+ --d2l-sem-status-color-success: var(--d2l-color-olivine);
35
+ --d2l-sem-status-color-warning-text: var(--d2l-color-carnelian-minus-1);
36
+ --d2l-sem-status-color-warning: var(--d2l-color-carnelian);
37
+ --d2l-sem-text-color-interactive-default: var(--d2l-sem-brand-color-primary-default);
38
+ --d2l-sem-text-color-interactive-hover: var(--d2l-sem-brand-color-primary-hover);
39
+ --d2l-sem-text-color-static-faint: var(--d2l-color-galena);
40
+ --d2l-sem-text-color-static-inverted: #ffffff;
41
+ --d2l-sem-text-color-static-standard: var(--d2l-color-ferrite);
42
+ --d2l-sem-text-color-static-subtle: var(--d2l-color-tungsten);
43
+
44
+ --d2l-sem-opacity-disabled-control: 0.5;
45
+ --d2l-sem-opacity-disabled-link: 0.74;
46
+ --d2l-sem-opacity-disabled-linkicon: 0.64;
47
+
48
+ --d2l-sem-shadow-attached-color: rgba(0, 0, 0, 0.03);
49
+ --d2l-sem-shadow-attached-offset-x: 0;
50
+ --d2l-sem-shadow-attached-offset-y: 2px;
51
+ --d2l-sem-shadow-attached-blur: 4px;
52
+ --d2l-sem-shadow-attached-spread: 0;
53
+ --d2l-sem-shadow-attached: var(--d2l-shadow-attached-offset-x) var(--d2l-shadow-attached-offset-y) var(--d2l-shadow-attached-blur) var(--d2l-shadow-attached-spread) var(--d2l-shadow-attached-color);
54
+ --d2l-sem-shadow-floating-color: rgba(0, 0, 0, 0.15);
55
+ --d2l-sem-shadow-floating-offset-x: 0;
56
+ --d2l-sem-shadow-floating-offset-y: 2px;
57
+ --d2l-sem-shadow-floating-blur: 12px;
58
+ --d2l-sem-shadow-floating-spread: 0;
59
+ --d2l-sem-shadow-floating: var(--d2l-shadow-floating-offset-x) var(--d2l-shadow-floating-offset-y) var(--d2l-shadow-floating-blur) var(--d2l-shadow-floating-spread) var(--d2l-shadow-floating-color);
60
+ --d2l-sem-shadow-inset-color: rgba(177, 185, 190, 0.2); /* corundum */
61
+ --d2l-sem-shadow-inset-offset-x: 0;
62
+ --d2l-sem-shadow-inset-offset-y: 2px;
63
+ --d2l-sem-shadow-inset-blur: 0;
64
+ --d2l-sem-shadow-inset-spread: 0;
65
+ --d2l-sem-shadow-inset: inset var(--d2l-shadow-inset-offset-x) var(--d2l-shadow-inset-offset-y) var(--d2l-shadow-inset-blur) var(--d2l-shadow-inset-spread) var(--d2l-shadow-inset-color);
10
66
  `;
11
67
  const darkPalette = `
12
- --d2l-color-background-base: #000000;
13
- --d2l-color-background-default: #18191a; /* new color */
14
- --d2l-color-border-medium: var(--d2l-color-tungsten);
15
- --d2l-color-font-base: var(--d2l-color-regolith);
68
+ --d2l-sem-background-color-base: #161718;
69
+ --d2l-sem-background-color-elevated: var(--d2l-color-ferrite);
70
+ --d2l-sem-background-color-floating: var(--d2l-color-ferrite);
71
+ --d2l-sem-background-color-interactive-faint-default: var(--d2l-color-ferrite);
72
+ --d2l-sem-background-color-interactive-faint-hover: #303335;
73
+ --d2l-sem-background-color-interactive-highlighted: var(--d2l-sem-brand-color-highlight);
74
+ --d2l-sem-background-color-interactive-primary-default: var(--d2l-sem-brand-color-primary-default);
75
+ --d2l-sem-background-color-interactive-primary-hover: var(--d2l-sem-brand-color-primary-hover);
76
+ --d2l-sem-background-color-interactive-secondary-default: #303335;
77
+ --d2l-sem-background-color-interactive-secondary-hover: var(--d2l-color-ferrite);
78
+ --d2l-sem-background-color-interactive-tertiary-default: #000000;
79
+ --d2l-sem-background-color-interactive-tertiary-hover: var(--d2l-sem-background-color-interactive-secondary-default);
80
+ --d2l-sem-background-color-interactive-translucent-default: #000000;
81
+ --d2l-sem-background-color-interactive-translucent-hover: var(--d2l-sem-brand-color-primary-default);
82
+ --d2l-sem-background-color-sunken: #000000;
83
+ --d2l-sem-border-color-emphasized: var(--d2l-color-galena);
84
+ --d2l-sem-border-color-focus: var(--d2l-color-celestine-plus-1);
85
+ --d2l-sem-border-color-standard: var(--d2l-color-tungsten);
86
+ --d2l-sem-border-color-subtle: #303335;
87
+ --d2l-sem-brand-color-highlight: #161718;
88
+ --d2l-sem-brand-color-primary-default: var(--d2l-color-celestine-plus-1);
89
+ --d2l-sem-brand-color-primary-hover: var(--d2l-color-celestine);
90
+ --d2l-sem-icon-color-faint: var(--d2l-sem-border-color-standard);
91
+ --d2l-sem-icon-color-inverted: #ffffff;
92
+ --d2l-sem-icon-color-standard: var(--d2l-color-corundum);
93
+ --d2l-sem-status-color-default: var(--d2l-sem-brand-color-primary-default);
94
+ --d2l-sem-status-color-error: var(--d2l-color-cinnabar-plus-1);
95
+ --d2l-sem-status-color-success-text: #ffffff;
96
+ --d2l-sem-status-color-success: var(--d2l-color-olivine);
97
+ --d2l-sem-status-color-warning-text: var(--d2l-color-carnelian);
98
+ --d2l-sem-status-color-warning: var(--d2l-color-carnelian);
99
+ --d2l-sem-text-color-interactive-default: var(--d2l-sem-brand-color-primary-default);
100
+ --d2l-sem-text-color-interactive-hover: var(--d2l-sem-brand-color-primary-hover);
101
+ --d2l-sem-text-color-static-faint: var(--d2l-color-galena);
102
+ --d2l-sem-text-color-static-inverted: #161718;
103
+ --d2l-sem-text-color-static-standard: var(--d2l-color-mica);
104
+ --d2l-sem-text-color-static-subtle: var(--d2l-color-chromite);
105
+
106
+ --d2l-sem-opacity-disabled-control: 0.5;
107
+ --d2l-sem-opacity-disabled-link: 0.74;
108
+ --d2l-sem-opacity-disabled-linkicon: 0.64;
109
+
110
+ --d2l-sem-shadow-attached-color: rgba(0, 0, 0, 0.03);
111
+ --d2l-sem-shadow-attached-offset-x: 0;
112
+ --d2l-sem-shadow-attached-offset-y: 2px;
113
+ --d2l-sem-shadow-attached-blur: 4px;
114
+ --d2l-sem-shadow-attached-spread: 0;
115
+ --d2l-sem-shadow-attached: var(--d2l-shadow-attached-offset-x) var(--d2l-shadow-attached-offset-y) var(--d2l-shadow-attached-blur) var(--d2l-shadow-attached-spread) var(--d2l-shadow-attached-color);
116
+ --d2l-sem-shadow-floating-color: rgba(0, 0, 0, 0.85);
117
+ --d2l-sem-shadow-floating-offset-x: 0;
118
+ --d2l-sem-shadow-floating-offset-y: 2px;
119
+ --d2l-sem-shadow-floating-blur: 12px;
120
+ --d2l-sem-shadow-floating-spread: 0;
121
+ --d2l-sem-shadow-floating: var(--d2l-shadow-floating-offset-x) var(--d2l-shadow-floating-offset-y) var(--d2l-shadow-floating-blur) var(--d2l-shadow-floating-spread) var(--d2l-shadow-floating-color);
122
+ --d2l-sem-shadow-inset-color: rgba(177, 185, 190, 0.2); /* corundum */
123
+ --d2l-sem-shadow-inset-offset-x: 0;
124
+ --d2l-sem-shadow-inset-offset-y: 2px;
125
+ --d2l-sem-shadow-inset-blur: 0;
126
+ --d2l-sem-shadow-inset-spread: 0;
127
+ --d2l-sem-shadow-inset: inset var(--d2l-shadow-inset-offset-x) var(--d2l-shadow-inset-offset-y) var(--d2l-shadow-inset-blur) var(--d2l-shadow-inset-spread) var(--d2l-shadow-inset-color);
16
128
  `;
17
129
 
18
130
  style.textContent = `
@@ -109,11 +221,11 @@ if (globalThis.document !== undefined && !globalThis.document.head.querySelector
109
221
  html {
110
222
  ${lightPalette}
111
223
  }
112
- html[data-theme="dark"] {
224
+ html[data-color-mode="dark"] {
113
225
  ${darkPalette}
114
226
  }
115
227
  @media (prefers-color-scheme: dark) {
116
- html[data-theme="os"] {
228
+ html[data-color-mode="os"] {
117
229
  ${darkPalette}
118
230
  }
119
231
  }
@@ -0,0 +1,12 @@
1
+ export const colorModes = ['light', 'dark', 'os'];
2
+ export const defaultColorMode = 'light';
3
+
4
+ const urlParams = new URLSearchParams(window.location.search);
5
+ const requestedColorMode = urlParams.get('color-mode');
6
+
7
+ const colorMode = colorModes.includes(requestedColorMode) ? requestedColorMode : localStorage.getItem('color-mode');
8
+ if (colorMode) {
9
+ document.documentElement.dataset.colorMode = colorMode;
10
+ } else {
11
+ delete document.documentElement.dataset.colorMode;
12
+ }
@@ -1,11 +1,12 @@
1
1
  import './demo-flags.js';
2
- import './demo-theme.js';
3
2
  import '../button/button.js';
4
3
  import '../inputs/input-checkbox-group.js';
5
4
  import '../inputs/input-checkbox.js';
5
+ import '../inputs/input-fieldset.js';
6
6
  import '../inputs/input-group.js';
7
7
  import '../collapsible-panel/collapsible-panel.js';
8
8
  import '../collapsible-panel/collapsible-panel-summary-item.js';
9
+ import { colorModes, defaultColorMode } from './demo-color-mode.js';
9
10
  import { css, html, LitElement, nothing } from 'lit';
10
11
  import { getDocumentLocaleSettings, supportedLocalesDetails } from '@brightspace-ui/intl/lib/common.js';
11
12
  import { getFlagOverrides, getKnownFlags } from '../../helpers/flags.js';
@@ -13,7 +14,6 @@ import { inputLabelStyles } from '../inputs/input-label-styles.js';
13
14
  import { selectStyles } from '../inputs/input-select-styles.js';
14
15
 
15
16
  const localeSettings = getDocumentLocaleSettings();
16
- const defaultTheme = 'light';
17
17
 
18
18
  class DemoPageSettings extends LitElement {
19
19
 
@@ -35,8 +35,14 @@ class DemoPageSettings extends LitElement {
35
35
  d2l-collapsible-panel {
36
36
  width: 100%;
37
37
  }
38
+ .color-mode-group {
39
+ display: inline-flex;
40
+ }
38
41
  #applyFlagsButton {
39
- margin-block-start: 1rem;
42
+ max-width: max-content;
43
+ }
44
+ #useAsDefaultColorMode {
45
+ margin-block-end: 0;
40
46
  }
41
47
  `];
42
48
  }
@@ -54,7 +60,7 @@ class DemoPageSettings extends LitElement {
54
60
  } else {
55
61
  this._language = getDocumentLocaleSettings().language;
56
62
  }
57
- this._theme = document.documentElement.dataset.theme || defaultTheme;
63
+ this._colorMode = document.documentElement.dataset.colorMode || defaultColorMode;
58
64
  }
59
65
 
60
66
  connectedCallback() {
@@ -84,7 +90,7 @@ class DemoPageSettings extends LitElement {
84
90
  languageItem = html`<d2l-collapsible-panel-summary-item slot="summary" text="Language: ${selectedLanguageCode}"></d2l-collapsible-panel-summary-item>`;
85
91
  }
86
92
 
87
- const themeOptions = ['light', 'dark', 'os'].map(theme => html`<option value="${theme}" ?selected="${this._theme === theme}">${theme}</option>`);
93
+ const colorModeOptions = colorModes.map(colorMode => html`<option value="${colorMode}" ?selected="${this._colorMode === colorMode}">${colorMode}</option>`);
88
94
 
89
95
  const knownFlags = this.#getKnownFlagsSorted();
90
96
  const knownFlagCheckboxes = [];
@@ -107,15 +113,19 @@ class DemoPageSettings extends LitElement {
107
113
  <span class="d2l-input-label">Language</span>
108
114
  <select class="d2l-input-select" @change="${this.#handleLanguageChange}">${languageOptions}</select>
109
115
  </label>
110
- <label>
111
- <span class="d2l-input-label">Theme</span>
112
- <select class="d2l-input-select" @change="${this.#handleThemeChange}">${themeOptions}</select>
113
- </label>
116
+
117
+ <d2l-input-fieldset label="Color Mode">
118
+ <d2l-input-group class="color-mode-group">
119
+ <select id="colorMode" aria-label="Color Mode" class="d2l-input-select" @change="${this.#handleColorModeChange}">${colorModeOptions}</select>
120
+ <d2l-input-checkbox id="useAsDefaultColorMode" label="Use as Default" @change="${this.#handleUseAsDefaultColorModeChange}"></d2l-input-checkbox>
121
+ </d2l-input-group>
122
+ </d2l-input-fieldset>
123
+
114
124
  ${knownFlagCheckboxes.length > 0 ? html`
115
125
  <d2l-input-checkbox-group id="flagsCheckboxGroup" label="Flags">
116
126
  ${knownFlagCheckboxes}
117
127
  </d2l-input-checkbox-group>
118
- <d2l-button id="applyFlagsButton" @click="${this.#handleApplyFlagsClick}">Apply</d2l-button>
128
+ <d2l-button id="applyFlagsButton" @click="${this.#handleApplyFlagsClick}">Apply Flags</d2l-button>
119
129
  ` : 'No known flags'}
120
130
  </d2l-input-group>
121
131
  ${languageItem}
@@ -156,6 +166,20 @@ class DemoPageSettings extends LitElement {
156
166
  window.location.search = urlParams.toString();
157
167
  }
158
168
 
169
+ #handleColorModeChange(e) {
170
+ const newColorMode = e.target[e.target.selectedIndex].value;
171
+ document.documentElement.dataset.colorMode = newColorMode;
172
+ const url = new URL(window.location.href);
173
+
174
+ const useAsDefault = this.shadowRoot.querySelector('#useAsDefaultColorMode').checked;
175
+ if (useAsDefault) {
176
+ this.#updateDefaultColorMode(newColorMode);
177
+ }
178
+
179
+ url.searchParams.set('color-mode', newColorMode);
180
+ window.history.replaceState({}, '', url.toString());
181
+ }
182
+
159
183
  #handleDocumentLanguageChange() {
160
184
  this._language = localeSettings.language;
161
185
  const url = new URL(window.location.href);
@@ -177,16 +201,15 @@ class DemoPageSettings extends LitElement {
177
201
  document.documentElement.lang = newLanguageCode;
178
202
  }
179
203
 
180
- #handleThemeChange(e) {
181
- const newTheme = e.target[e.target.selectedIndex].value;
182
- document.documentElement.setAttribute('data-theme', newTheme);
183
- const url = new URL(window.location.href);
184
- if (newTheme === defaultTheme) {
185
- url.searchParams.delete('theme');
186
- } else {
187
- url.searchParams.set('theme', newTheme);
204
+ #handleUseAsDefaultColorModeChange(e) {
205
+ const useAsDefault = e.target.checked;
206
+ if (useAsDefault) {
207
+ this.#updateDefaultColorMode(this.shadowRoot.querySelector('#colorMode').value);
188
208
  }
189
- window.history.replaceState({}, '', url.toString());
209
+ }
210
+
211
+ #updateDefaultColorMode(colorMode) {
212
+ localStorage.setItem('color-mode', colorMode);
190
213
  }
191
214
 
192
215
  }
@@ -31,7 +31,7 @@ class DemoPage extends LitElement {
31
31
  static get styles() {
32
32
  return [ css`
33
33
  :host {
34
- background-color: var(--d2l-color-background-base);
34
+ background-color: var(--d2l-sem-background-color-sunken);
35
35
  display: block;
36
36
  padding: 30px;
37
37
  }
@@ -46,7 +46,7 @@ class DemoPage extends LitElement {
46
46
  }
47
47
  .d2l-demo-page-content > ::slotted(h2),
48
48
  .d2l-demo-page-content > ::slotted(h3) {
49
- color: var(--d2l-color-font-base);
49
+ color: var(--d2l-sem-text-color-static-standard);
50
50
  font-size: 0.8rem;
51
51
  font-weight: 700;
52
52
  line-height: 1.2rem;
@@ -24,8 +24,8 @@ class DemoSnippet extends LitElement {
24
24
  static get styles() {
25
25
  return css`
26
26
  :host {
27
- background-color: var(--d2l-color-background-default);
28
- border: 1px solid var(--d2l-color-border-medium);
27
+ background-color: var(--d2l-sem-background-color-base);
28
+ border: 1px solid var(--d2l-sem-border-color-standard);
29
29
  border-radius: 6px;
30
30
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
31
31
  display: block;
@@ -41,7 +41,7 @@ class DemoSnippet extends LitElement {
41
41
  display: flex;
42
42
  }
43
43
  .d2l-demo-snippet-demo-wrapper.fullscreen {
44
- background-color: var(--d2l-color-background-default);
44
+ background-color: var(--d2l-sem-background-color-base);
45
45
  height: 100vh;
46
46
  inset: 0;
47
47
  overflow: auto;
@@ -67,7 +67,7 @@ class DemoSnippet extends LitElement {
67
67
  padding: 0;
68
68
  }
69
69
  .d2l-demo-snippet-settings {
70
- border-inline-start: 1px solid var(--d2l-color-border-medium);
70
+ border-inline-start: 1px solid var(--d2l-sem-border-color-standard);
71
71
  flex: 0 0 auto;
72
72
  padding: 6px;
73
73
  }
@@ -76,7 +76,7 @@ class DemoSnippet extends LitElement {
76
76
  top: 0;
77
77
  }
78
78
  d2l-dropdown.settings-dropdown {
79
- background-color: var(--d2l-color-background-default);
79
+ background-color: var(--d2l-sem-background-color-base);
80
80
  border-radius: 6px;
81
81
  outline: 1px solid var(--d2l-color-celestine-minus-1);
82
82
  position: fixed;
@@ -1,5 +1,5 @@
1
1
  html {
2
- background-color: var(--d2l-color-background-base);
2
+ background-color: var(--d2l-sem-background-color-base);
3
3
  font-size: 20px;
4
4
  }
5
5
  body {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "3.219.10",
3
+ "version": "3.220.1",
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",
@@ -1,7 +0,0 @@
1
- const urlParams = new URLSearchParams(window.location.search);
2
- const theme = urlParams.get('theme');
3
- if (theme) {
4
- document.documentElement.dataset.theme = theme;
5
- } else {
6
- delete document.documentElement.dataset.theme;
7
- }