@brightspace-ui/core 3.47.0 → 3.48.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -30,8 +30,12 @@ Note: All `*-value` properties should be in ISO 8601 calendar date format (`YYYY
30
30
  * `d2l-calendar-selected`: dispatched when a date is selected through click, space, or enter. `e.detail.date` is in ISO 8601 calendar date format (`YYYY-MM-DD`).
31
31
  <!-- docs: end hidden content -->
32
32
 
33
+ ### Methods
34
+
35
+ - `getShownValue()`: returns the date representing the year and month in view as an ISO 8601 calendar date format (`YYYY-MM-DD`).
36
+
33
37
  ## Accessibility
34
38
 
35
39
  The Daylight calendar (`d2l-calendar`) generally follows the W3C's best practice recommendations for a [Date picker dialog](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/datepicker-dialog/). Of note is the keyboard behaviour following the [grid pattern](https://www.w3.org/WAI/ARIA/apg/patterns/grid/).
36
40
 
37
- The W3C recommendations, specifically relating to `attributes` on the calendar's table elements, were followed as much as possible. At the time of development it was not possible to create a calendar with a `grid` role which had the desired appearance, functionality, and supported all browser/screen reader combinations that we support; the expected screen reader experience was replicated as much as possible (e.g., announcing the expected content).
41
+ The W3C recommendations, specifically relating to `attributes` on the calendar's table elements, were followed as much as possible. At the time of development it was not possible to create a calendar with a `grid` role which had the desired appearance, functionality, and supported all browser/screen reader combinations that we support; the expected screen reader experience was replicated as much as possible (e.g., announcing the expected content).
@@ -40,7 +40,8 @@ function getCalendarData() {
40
40
  return calendarData;
41
41
  }
42
42
 
43
- function getInitialFocusDate(selectedValue, minValue, maxValue) {
43
+ function getInitialFocusDate(initialValue, selectedValue, minValue, maxValue) {
44
+ if (initialValue) return getDateFromISODate(initialValue);
44
45
  if (selectedValue) return getDateFromISODate(selectedValue);
45
46
  else return getDateFromISODate(getClosestValidDate(minValue, maxValue, false));
46
47
  }
@@ -50,9 +51,9 @@ export function checkIfDatesEqual(date1, date2) {
50
51
  return date1.getTime() === date2.getTime();
51
52
  }
52
53
 
53
- export function getMinMaxDatesInView(selectedValue, minValue, maxValue) {
54
+ export function getMinMaxDatesInView(initialValue, selectedValue, minValue, maxValue) {
54
55
  getCalendarData();
55
- const date = getInitialFocusDate(selectedValue, minValue, maxValue);
56
+ const date = getInitialFocusDate(initialValue, selectedValue, minValue, maxValue);
56
57
  const dates = getDatesInMonthArray(date.getMonth(), date.getFullYear());
57
58
  return {
58
59
  maxValue: dates[dates.length - 1][6],
@@ -160,6 +161,11 @@ class Calendar extends LocalizeCoreElement(RtlMixin(LitElement)) {
160
161
  * @type {string}
161
162
  */
162
163
  label: { attribute: 'label', reflect: true, type: String },
164
+ /**
165
+ * ADVANCED: Initial date to override the logic for determining default date to initially show
166
+ * @type {string}
167
+ */
168
+ initialValue: { attribute: 'initial-value', type: String },
163
169
  /**
164
170
  * Maximum valid date that could be selected by a user
165
171
  * @type {string}
@@ -609,7 +615,9 @@ class Calendar extends LocalizeCoreElement(RtlMixin(LitElement)) {
609
615
  composed: false,
610
616
  detail: {
611
617
  maxValue: dates[dates.length - 1][6],
612
- minValue: dates[0][0]
618
+ month: this._shownMonth,
619
+ minValue: dates[0][0],
620
+ year: this._shownYear
613
621
  }
614
622
  }));
615
623
 
@@ -625,6 +633,10 @@ class Calendar extends LocalizeCoreElement(RtlMixin(LitElement)) {
625
633
  }
626
634
  }
627
635
 
636
+ getShownValue() {
637
+ return new Date(this._shownYear, this._shownMonth).toISOString();
638
+ }
639
+
628
640
  async reset(allowDisabled) {
629
641
  const date = this._getInitialFocusDate();
630
642
  await this._updateFocusDate(date, false, allowDisabled);
@@ -649,7 +661,7 @@ class Calendar extends LocalizeCoreElement(RtlMixin(LitElement)) {
649
661
  }
650
662
 
651
663
  _getInitialFocusDate() {
652
- const date = getInitialFocusDate(this.selectedValue, this.minValue, this.maxValue);
664
+ const date = getInitialFocusDate(this.initialValue, this.selectedValue, this.minValue, this.maxValue);
653
665
  this._shownMonth = date.getMonth();
654
666
  this._shownYear = date.getFullYear();
655
667
  return date;
@@ -62,8 +62,11 @@
62
62
  };
63
63
 
64
64
  const calendar = document.querySelector('#eventsCalendar');
65
- calendar.dayInfos = getEvents(getMinMaxDatesInView(calendar.selectedValue));
66
- calendar.addEventListener('d2l-calendar-view-change', e => calendar.dayInfos = getEvents(e.detail));
65
+ calendar.dayInfos = getEvents(getMinMaxDatesInView(undefined, calendar.selectedValue));
66
+ calendar.addEventListener('d2l-calendar-view-change', e => {
67
+ console.log(e);
68
+ calendar.dayInfos = getEvents(e.detail);
69
+ });
67
70
  </script>
68
71
  </template>
69
72
  </d2l-demo-snippet>
@@ -1,13 +1,14 @@
1
1
  import '../colors/colors.js';
2
2
  import { codeStyles, createHtmlBlockRenderer as createCodeRenderer } from '../../helpers/prism.js';
3
- import { css, html, LitElement, nothing, unsafeCSS } from 'lit';
3
+ import { createRef, ref } from 'lit/directives/ref.js';
4
+ import { css, html, LitElement, unsafeCSS } from 'lit';
4
5
  import { classMap } from 'lit/directives/class-map.js';
5
6
  import { createHtmlBlockRenderer as createMathRenderer } from '../../helpers/mathjax.js';
6
7
  import { getFocusPseudoClass } from '../../helpers/focus.js';
8
+ import { LoadingCompleteMixin } from '../../mixins/loading-complete/loading-complete-mixin.js';
7
9
  import { renderEmbeds } from '../../helpers/embeds.js';
8
10
  import { requestInstance } from '../../mixins/provider/provider-mixin.js';
9
11
  import { tryGet } from '@brightspace-ui/lms-context-provider/client.js';
10
- import { until } from 'lit/directives/until.js';
11
12
 
12
13
  export const htmlBlockContentStyles = css`
13
14
  .d2l-html-block-rendered {
@@ -142,7 +143,7 @@ const getRenderers = async() => {
142
143
  /**
143
144
  * A component for displaying user-authored HTML.
144
145
  */
145
- class HtmlBlock extends LitElement {
146
+ class HtmlBlock extends LoadingCompleteMixin(LitElement) {
146
147
 
147
148
  static get properties() {
148
149
  return {
@@ -206,8 +207,7 @@ class HtmlBlock extends LitElement {
206
207
  this._initialContextResolve = undefined;
207
208
  this._initialContextPromise = new Promise(resolve => this._initialContextResolve = resolve);
208
209
 
209
- this._renderersProcessedResolve = undefined;
210
- this._renderersProcessedPromise = new Promise(resolve => this._renderersProcessedResolve = resolve);
210
+ this._renderContainerRef = createRef();
211
211
 
212
212
  const contextKeysPromise = getRenderers().then(renderers => renderers.reduce((keys, currentRenderer) => {
213
213
  if (currentRenderer.contextKeys) currentRenderer.contextKeys.forEach(key => keys.push(key));
@@ -216,10 +216,7 @@ class HtmlBlock extends LitElement {
216
216
 
217
217
  const contextValsPromise = contextKeysPromise.then(contextKeys => {
218
218
  return Promise.allSettled(contextKeys.map(key => {
219
- return tryGet(key, undefined, ctx => {
220
- this._context.set(key, ctx);
221
- this.updated(new Map([['_context']]));
222
- });
219
+ return tryGet(key, undefined, ctx => this._context.set(key, ctx));
223
220
  }));
224
221
  });
225
222
 
@@ -238,24 +235,18 @@ class HtmlBlock extends LitElement {
238
235
  };
239
236
 
240
237
  return html`
241
- <div class="${classMap(renderContainerClasses)}">
242
- ${!this.noDeferredRendering ? until(this._processEmbeds(), nothing) : nothing}
243
- </div>
238
+ <div class="${classMap(renderContainerClasses)}" ${ref(this._renderContainerRef)}></div>
244
239
  ${this.noDeferredRendering ? html`<slot @slotchange="${this._handleSlotChange}"></slot>` : ''}
245
240
  `;
246
241
  }
247
242
 
248
243
  async updated(changedProperties) {
249
244
  super.updated(changedProperties);
250
- if ((changedProperties.has('embeds') || changedProperties.has('_context')) && this.html !== undefined && this.html !== null && !this.noDeferredRendering) {
245
+ if (this.html !== undefined && this.html !== null && !this.noDeferredRendering) {
251
246
  await this._updateRenderContainer();
252
247
  }
253
248
  }
254
249
 
255
- async getLoadingComplete() {
256
- return this._renderersProcessedPromise;
257
- }
258
-
259
250
  async _handleSlotChange(e) {
260
251
  if (!e.target || !this.shadowRoot || !this.noDeferredRendering) return;
261
252
  await this._renderInline(e.target);
@@ -264,7 +255,6 @@ class HtmlBlock extends LitElement {
264
255
  async _processEmbeds() {
265
256
  const htmlFragment = document.createRange().createContextualFragment(this.html);
266
257
  await renderEmbeds(htmlFragment);
267
- this.updated(new Map([['embeds']]));
268
258
  return htmlFragment;
269
259
  }
270
260
 
@@ -289,7 +279,7 @@ class HtmlBlock extends LitElement {
289
279
  loadingCompletePromises.push(renderer.getLoadingComplete());
290
280
  }
291
281
  }
292
- Promise.all(loadingCompletePromises).then(() => this._renderersProcessedResolve());
282
+ Promise.all(loadingCompletePromises).then(this.resolveLoadingComplete);
293
283
  }
294
284
 
295
285
  async _renderInline(slot) {
@@ -300,15 +290,16 @@ class HtmlBlock extends LitElement {
300
290
  .find(node => (node.nodeType === Node.ELEMENT_NODE && node.tagName === 'DIV'));
301
291
 
302
292
  if (!noDeferredRenderingContainer) {
303
- this._renderersProcessedResolve();
293
+ this.resolveLoadingComplete();
304
294
  return;
305
295
  }
306
296
  await this._processRenderers(noDeferredRenderingContainer);
307
297
  }
308
298
 
309
299
  async _updateRenderContainer() {
310
- const renderContainer = this.shadowRoot.querySelector('.d2l-html-block-rendered');
311
- await this._processRenderers(renderContainer);
300
+ this._renderContainerRef.value.innerHTML = '';
301
+ this._renderContainerRef.value.append(await this._processEmbeds());
302
+ await this._processRenderers(this._renderContainerRef.value);
312
303
  }
313
304
 
314
305
  _validateHtml() {
@@ -823,6 +823,11 @@
823
823
  "description": "Unique label text for calendar (necessary if multiple calendars on page)",
824
824
  "type": "string"
825
825
  },
826
+ {
827
+ "name": "initial-value",
828
+ "description": "ADVANCED: Initial date to override the logic for determining default date to initially show",
829
+ "type": "string"
830
+ },
826
831
  {
827
832
  "name": "max-value",
828
833
  "description": "Maximum valid date that could be selected by a user",
@@ -857,6 +862,12 @@
857
862
  "description": "Unique label text for calendar (necessary if multiple calendars on page)",
858
863
  "type": "string"
859
864
  },
865
+ {
866
+ "name": "initialValue",
867
+ "attribute": "initial-value",
868
+ "description": "ADVANCED: Initial date to override the logic for determining default date to initially show",
869
+ "type": "string"
870
+ },
860
871
  {
861
872
  "name": "maxValue",
862
873
  "attribute": "max-value",
@@ -4759,6 +4770,14 @@
4759
4770
  "description": "Whether to disable deferred rendering of the user-authored HTML. Do *not* set this\nunless your HTML relies on script executions that may break upon stamping.",
4760
4771
  "type": "Boolean",
4761
4772
  "default": "false"
4773
+ },
4774
+ {
4775
+ "name": "loadingComplete",
4776
+ "type": "Promise<any>"
4777
+ },
4778
+ {
4779
+ "name": "resolveLoadingComplete",
4780
+ "type": "() => void"
4762
4781
  }
4763
4782
  ]
4764
4783
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "3.47.0",
3
+ "version": "3.48.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",