@brightspace-ui/core 3.33.1 → 3.35.0
Sign up to get free protection for your applications and to get access to all the features.
@@ -216,7 +216,10 @@ 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 =>
|
219
|
+
return tryGet(key, undefined, ctx => {
|
220
|
+
this._context.set(key, ctx);
|
221
|
+
this.updated(new Map([['_context']]));
|
222
|
+
});
|
220
223
|
}));
|
221
224
|
});
|
222
225
|
|
@@ -234,24 +237,17 @@ class HtmlBlock extends LitElement {
|
|
234
237
|
'd2l-html-block-compact': this.compact
|
235
238
|
};
|
236
239
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
`;
|
244
|
-
} else {
|
245
|
-
return html`
|
246
|
-
<div class="${classMap(renderContainerClasses)}"></div>
|
247
|
-
${this.noDeferredRendering ? html`<slot @slotchange="${this._handleSlotChange}"></slot>` : ''}
|
248
|
-
`;
|
249
|
-
}
|
240
|
+
return html`
|
241
|
+
<div class="${classMap(renderContainerClasses)}">
|
242
|
+
${!this.noDeferredRendering ? until(this._processEmbeds(), nothing) : nothing}
|
243
|
+
</div>
|
244
|
+
${this.noDeferredRendering ? html`<slot @slotchange="${this._handleSlotChange}"></slot>` : ''}
|
245
|
+
`;
|
250
246
|
}
|
251
247
|
|
252
248
|
async updated(changedProperties) {
|
253
249
|
super.updated(changedProperties);
|
254
|
-
if ((changedProperties.has('
|
250
|
+
if ((changedProperties.has('embeds') || changedProperties.has('_context')) && this.html !== undefined && this.html !== null && !this.noDeferredRendering) {
|
255
251
|
await this._updateRenderContainer();
|
256
252
|
}
|
257
253
|
}
|
@@ -260,10 +256,6 @@ class HtmlBlock extends LitElement {
|
|
260
256
|
return this._renderersProcessedPromise;
|
261
257
|
}
|
262
258
|
|
263
|
-
_embedsFeatureEnabled() {
|
264
|
-
return window.D2L?.LP?.Web?.UI?.Flags.Flag('shield-7574-enable-embed-rendering-framework', true);
|
265
|
-
}
|
266
|
-
|
267
259
|
async _handleSlotChange(e) {
|
268
260
|
if (!e.target || !this.shadowRoot || !this.noDeferredRendering) return;
|
269
261
|
await this._renderInline(e.target);
|
@@ -272,6 +264,7 @@ class HtmlBlock extends LitElement {
|
|
272
264
|
async _processEmbeds() {
|
273
265
|
const htmlFragment = document.createRange().createContextualFragment(this.html);
|
274
266
|
await renderEmbeds(htmlFragment);
|
267
|
+
this.updated(new Map([['embeds']]));
|
275
268
|
return htmlFragment;
|
276
269
|
}
|
277
270
|
|
@@ -315,7 +308,6 @@ class HtmlBlock extends LitElement {
|
|
315
308
|
|
316
309
|
async _updateRenderContainer() {
|
317
310
|
const renderContainer = this.shadowRoot.querySelector('.d2l-html-block-rendered');
|
318
|
-
if (!this._embedsFeatureEnabled()) renderContainer.innerHTML = this.html;
|
319
311
|
await this._processRenderers(renderContainer);
|
320
312
|
}
|
321
313
|
|
@@ -41,6 +41,7 @@ class TestTable extends RtlMixin(DemoPassthroughMixin(TableWrapper, 'd2l-table-w
|
|
41
41
|
static get properties() {
|
42
42
|
return {
|
43
43
|
paging: { type: Boolean, reflect: true },
|
44
|
+
multiLine: { type: Boolean, attribute: 'multi-line' },
|
44
45
|
showButtons: { type: Boolean, attribute: 'show-buttons' },
|
45
46
|
stickyControls: { attribute: 'sticky-controls', type: Boolean, reflect: true },
|
46
47
|
visibleBackground: { attribute: 'visible-background', type: Boolean, reflect: true },
|
@@ -72,6 +73,7 @@ class TestTable extends RtlMixin(DemoPassthroughMixin(TableWrapper, 'd2l-table-w
|
|
72
73
|
constructor() {
|
73
74
|
super();
|
74
75
|
|
76
|
+
this.multiLine = false;
|
75
77
|
this.paging = false;
|
76
78
|
this.showButtons = false;
|
77
79
|
this.stickyControls = false;
|
@@ -99,11 +101,25 @@ class TestTable extends RtlMixin(DemoPassthroughMixin(TableWrapper, 'd2l-table-w
|
|
99
101
|
|
100
102
|
<table class="d2l-table">
|
101
103
|
<thead>
|
102
|
-
|
103
|
-
<
|
104
|
-
|
105
|
-
|
106
|
-
|
104
|
+
${this.multiLine ? html`
|
105
|
+
<tr>
|
106
|
+
<th scope="col" sticky><d2l-selection-select-all></d2l-selection-select-all></th>
|
107
|
+
${this._renderDoubleSortButton('Location')}
|
108
|
+
<th scope="col" colspan="${columns.length}" sticky>
|
109
|
+
Metrics
|
110
|
+
</th>
|
111
|
+
</tr>
|
112
|
+
<tr>
|
113
|
+
<th scope="col" sticky></th>
|
114
|
+
${columns.map(columnHeading => this._renderSortButton(columnHeading))}
|
115
|
+
</tr>
|
116
|
+
` : html`
|
117
|
+
<tr>
|
118
|
+
<th scope="col" sticky><d2l-selection-select-all></d2l-selection-select-all></th>
|
119
|
+
${this._renderDoubleSortButton('Location')}
|
120
|
+
${columns.map(columnHeading => this._renderSortButton(columnHeading))}
|
121
|
+
</tr>
|
122
|
+
`}
|
107
123
|
</thead>
|
108
124
|
<tbody>
|
109
125
|
<tr class="d2l-table-header">
|
@@ -182,7 +198,7 @@ class TestTable extends RtlMixin(DemoPassthroughMixin(TableWrapper, 'd2l-table-w
|
|
182
198
|
_renderDoubleSortButton(name) {
|
183
199
|
const noSort = this._sortField?.toLowerCase() !== 'city' && this._sortField?.toLowerCase() !== 'country';
|
184
200
|
return html`
|
185
|
-
<th scope="col">
|
201
|
+
<th rowspan="${this.multiLine ? 2 : 1}" scope="col">
|
186
202
|
<d2l-table-col-sort-button
|
187
203
|
?desc="${this._sortDesc}"
|
188
204
|
?nosort="${noSort}">${name}
|
@@ -80,6 +80,13 @@
|
|
80
80
|
</template>
|
81
81
|
</d2l-demo-snippet>
|
82
82
|
|
83
|
+
<h2>Multi-line with scroll-wrapper + sticky</h2>
|
84
|
+
<d2l-demo-snippet>
|
85
|
+
<template>
|
86
|
+
<d2l-test-table multi-line sticky-headers sticky-controls sticky-headers-scroll-wrapper style="width: 400px;"></d2l-test-table>
|
87
|
+
</template>
|
88
|
+
</d2l-demo-snippet>
|
89
|
+
|
83
90
|
<div style="margin-bottom: 1000px;"></div>
|
84
91
|
</d2l-demo-page>
|
85
92
|
</body>
|
@@ -599,16 +599,87 @@ export class TableWrapper extends RtlMixin(PageableMixin(SelectionMixin(LitEleme
|
|
599
599
|
const body = this._table.querySelector('tbody');
|
600
600
|
if (!head || !body) return;
|
601
601
|
|
602
|
-
const
|
603
|
-
const firstRowBody = body.rows[0];
|
604
|
-
if (!firstRowHead || !firstRowBody || firstRowHead.cells.length !== firstRowBody.cells.length) return;
|
602
|
+
const candidateRowHeadCells = [];
|
605
603
|
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
604
|
+
// Max length of one of our body rows, which we'll try to map to our candidate head cells.
|
605
|
+
const maxRowBodyLength = Math.max(...([...body.rows].map(row => row.cells.length)));
|
606
|
+
|
607
|
+
const headCellsMap = [];
|
608
|
+
for (let i = 0; i < head.rows.length; i++) {
|
609
|
+
headCellsMap[i] = [];
|
610
|
+
}
|
611
|
+
|
612
|
+
// Build a map of which cells "exist" in each head row so we can pick out
|
613
|
+
// a candidate in each column to sync widths with.
|
614
|
+
for (let rowIndex = 0; rowIndex < head.rows.length; rowIndex++) {
|
615
|
+
const rowMap = headCellsMap[rowIndex];
|
616
|
+
|
617
|
+
let spanOffset = 0;
|
618
|
+
for (let colIndex = 0; colIndex < maxRowBodyLength; colIndex++) {
|
619
|
+
if (rowMap[colIndex] === null) {
|
620
|
+
spanOffset++;
|
621
|
+
continue;
|
622
|
+
}
|
623
|
+
|
624
|
+
const cell = head.rows[rowIndex].cells[colIndex - spanOffset];
|
625
|
+
rowMap[colIndex] = cell;
|
626
|
+
|
627
|
+
if (!cell) continue;
|
628
|
+
|
629
|
+
const colSpan = cell.colSpan;
|
630
|
+
const rowSpan = cell.rowSpan;
|
631
|
+
|
632
|
+
for (let offset = 1; offset < colSpan; offset++) {
|
633
|
+
rowMap[colIndex + offset] = null;
|
634
|
+
}
|
635
|
+
|
636
|
+
for (let offset = 1; offset < rowSpan; offset++) {
|
637
|
+
headCellsMap[rowIndex + offset][colIndex] = null;
|
638
|
+
}
|
639
|
+
}
|
640
|
+
}
|
641
|
+
|
642
|
+
// Pick out a single head cell for each column to sync widths.
|
643
|
+
for (let i = 0; i < maxRowBodyLength; i++) {
|
644
|
+
let candidateCell;
|
645
|
+
for (const rowMap of headCellsMap) {
|
646
|
+
const cell = rowMap[i];
|
647
|
+
|
648
|
+
if (cell && cell.colSpan === 1) {
|
649
|
+
candidateCell = cell;
|
650
|
+
break;
|
651
|
+
}
|
652
|
+
}
|
653
|
+
|
654
|
+
// This does not support heads without at least one single-column
|
655
|
+
// spanning cell in each column.
|
656
|
+
if (!candidateCell) return;
|
657
|
+
|
658
|
+
candidateRowHeadCells[i] = candidateCell;
|
659
|
+
}
|
660
|
+
|
661
|
+
// Pick the body row with the most cells (and no colspans) to measure against
|
662
|
+
const candidateRowBody = [...body.rows].find(row => {
|
663
|
+
return row.cells.length === maxRowBodyLength
|
664
|
+
&& ![...row.cells].find(cell => cell.colSpan > 1);
|
665
|
+
});
|
666
|
+
|
667
|
+
if (candidateRowHeadCells.length === 0 || !candidateRowBody) return;
|
668
|
+
|
669
|
+
let candidateRowBodyLength = 0;
|
670
|
+
for (const cell of candidateRowBody.cells) {
|
671
|
+
candidateRowBodyLength += cell.colSpan;
|
672
|
+
}
|
673
|
+
|
674
|
+
if (candidateRowHeadCells.length !== candidateRowBodyLength) return;
|
675
|
+
|
676
|
+
for (let i = 0; i < candidateRowHeadCells.length; i++) {
|
677
|
+
const headCell = candidateRowHeadCells[i];
|
610
678
|
const headStyle = getComputedStyle(headCell);
|
611
679
|
|
680
|
+
const bodyCell = candidateRowBody.cells[i];
|
681
|
+
const bodyStyle = getComputedStyle(bodyCell);
|
682
|
+
|
612
683
|
if (headCell.clientWidth > bodyCell.clientWidth) {
|
613
684
|
const headOverallWidth = parseFloat(headStyle.width) + parseFloat(headStyle.paddingLeft) + parseFloat(headStyle.paddingRight);
|
614
685
|
bodyCell.style.minWidth = `${headOverallWidth - parseFloat(bodyStyle.paddingLeft) - parseFloat(bodyStyle.paddingRight)}px`;
|
package/custom-elements.json
CHANGED
@@ -11944,6 +11944,11 @@
|
|
11944
11944
|
"name": "d2l-test-table",
|
11945
11945
|
"path": "./components/table/demo/table-test.js",
|
11946
11946
|
"attributes": [
|
11947
|
+
{
|
11948
|
+
"name": "multi-line",
|
11949
|
+
"type": "boolean",
|
11950
|
+
"default": "false"
|
11951
|
+
},
|
11947
11952
|
{
|
11948
11953
|
"name": "paging",
|
11949
11954
|
"type": "boolean",
|
@@ -12001,6 +12006,12 @@
|
|
12001
12006
|
}
|
12002
12007
|
],
|
12003
12008
|
"properties": [
|
12009
|
+
{
|
12010
|
+
"name": "multiLine",
|
12011
|
+
"attribute": "multi-line",
|
12012
|
+
"type": "boolean",
|
12013
|
+
"default": "false"
|
12014
|
+
},
|
12004
12015
|
{
|
12005
12016
|
"name": "paging",
|
12006
12017
|
"attribute": "paging",
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@brightspace-ui/core",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.35.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",
|