Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions components/list/demo/demo-list-nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ class ListDemoNav extends LitElement {
render() {
return html`
<div @d2l-list-items-move="${this._handleListItemsMove}">
<d2l-list
<d2l-list
?add-button="${this.addButton}"
grid
grid
drag-multiple
@d2l-list-item-link-click="${this._handleItemClick}">
${repeat(this.#list, (item) => item.key, (item) => this._renderItem(item))}
Expand Down Expand Up @@ -149,8 +149,9 @@ class ListDemoNav extends LitElement {
drop-nested
label="${item.primaryText}"
prevent-navigation>
${item.hasIcon ? html`<d2l-icon slot="illustration" icon="tier2:file-document"></d2l-icon>` : nothing}
<d2l-list-item-content>
<div>${item.hasIcon ? html`<d2l-icon icon="tier2:file-document"></d2l-icon>` : nothing}${item.primaryText}</div>
<div>${item.primaryText}</div>
${item.tooltipOpenerText && item.tooltipText
? html`<div slot="secondary"><d2l-tooltip-help text="${item.tooltipOpenerText}">${item.tooltipText}</d2l-tooltip-help></div>`
: nothing
Expand Down
4 changes: 2 additions & 2 deletions components/list/demo/list-demo-scenarios.js
Original file line number Diff line number Diff line change
Expand Up @@ -372,9 +372,9 @@ export const listDemos = {
primaryText: 'Wetland Engineering #2',
dropNested: true,
items: [],
hasIcon: true
hasIcon: false
}],
hasIcon: true
hasIcon: false
}]
}],
};
2 changes: 1 addition & 1 deletion components/list/list-item-expand-collapse-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const ListItemExpandCollapseMixin = superclass => class extends SkeletonM

updated(changedProperties) {
if (changedProperties.has('_siblingHasNestedItems') || changedProperties.has('expandable')) {
this._renderExpandCollapseSlot = this.expandable || this._siblingHasNestedItems;
this._renderExpandCollapseSlot = this.expandable;
}
if (changedProperties.has('_draggingOver') && this._draggingOver && this.dropNested && !this.expanded && this.expandable) {
let elapsedHoverTime = 0;
Expand Down
9 changes: 6 additions & 3 deletions components/list/list-item-generic-layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ class ListItemGenericLayout extends LitElement {
[color-start outside-control-end] minmax(0, min-content)
[expand-collapse-start color-end] minmax(0, min-content)
[control-start expand-collapse-end] minmax(0, min-content)
[control-end content-start] minmax(0, auto)
[spacer-start control-end] minmax(0, min-content)
[spacer-end content-start] minmax(0, auto)
[content-end actions-start] minmax(0, min-content)
[end actions-end];
grid-template-rows:
Expand Down Expand Up @@ -144,8 +145,9 @@ class ListItemGenericLayout extends LitElement {
grid-column: color-start / color-end;
}

::slotted([slot="before-content"]) {
grid-column: color-start / content-start;
::slotted([slot="spacer"]) {
grid-column: spacer-start / spacer-end;
grid-row: 2 / 3;
}

::slotted([slot="control-action"]) ~ ::slotted([slot="content"]),
Expand Down Expand Up @@ -300,6 +302,7 @@ class ListItemGenericLayout extends LitElement {
<slot name="outside-control-action" class="d2l-cell" data-cell-num="1"></slot>
<slot name="color-indicator"></slot>
<slot name="expand-collapse" class="d2l-cell" data-cell-num="4"></slot>
<slot name="spacer"></slot>
<slot name="content" class="d2l-cell" data-cell-num="8" @focus="${!this.noPrimaryAction ? this._preventFocus : null}"></slot>
<slot name="control-action" class="d2l-cell" data-cell-num="3"></slot>
<slot name="control" class="d2l-cell" data-cell-num="5"></slot>
Expand Down
5 changes: 5 additions & 0 deletions components/list/list-item-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,10 @@ export const ListItemMixin = superclass => class extends composeMixins(
padding-inline-start: 2.2rem; /* width of "control" slot set in generic-layout */
}

.d2l-list-item-spacer {
width: var(--d2l-list-item-spacer-width, 0);
}

[slot="content"] ::slotted([slot="illustration"]),
[slot="content"] .d2l-list-item-illustration > * {
border-radius: 6px;
Expand Down Expand Up @@ -871,6 +875,7 @@ export const ListItemMixin = superclass => class extends composeMixins(
${this._renderExpandCollapse()}
</div>
${this.selectable ? html`<div slot="control">${this._renderCheckbox()}</div>` : nothing}
<div slot="spacer" class="d2l-list-item-spacer"></div>
${this.selectable || this.expandable ? html`
<div slot="control-action"
@mouseenter="${this._onMouseEnter}"
Expand Down
3 changes: 3 additions & 0 deletions components/list/list-item-nav-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ export const ListItemNavMixin = superclass => class extends ListItemLinkMixin(su
.d2l-list-item-content ::slotted(*) {
width: 100%;
}
.d2l-list-item-content ::slotted([slot="illustration"]) {
width: auto;
}
:host([current]) [slot="outside-control-container"] {
background-color: var(--d2l-color-regolith);
border: 3px solid var(--d2l-color-celestine);
Expand Down
66 changes: 65 additions & 1 deletion components/list/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ class List extends PageableMixin(SelectionMixin(LitElement)) {
this._breakpoint = 0;
this._slimColor = false;
this._width = 0;
this._spacerMeasurementScheduled = false;

this._listChildrenUpdatedSubscribers = new SubscriberRegistryController(this, 'list-child-status', {
onSubscribe: this._updateActiveSubscriber.bind(this),
Expand Down Expand Up @@ -258,7 +259,7 @@ class List extends PageableMixin(SelectionMixin(LitElement)) {
}

getItems(slot) {
if (!this.shadowRoot) return;
if (!this.shadowRoot) return [];
if (!slot) slot = this.shadowRoot.querySelector('slot:not([name])');
if (!slot) return [];
return slot.assignedNodes({ flatten: true }).filter((node) => {
Expand Down Expand Up @@ -334,6 +335,7 @@ class List extends PageableMixin(SelectionMixin(LitElement)) {
return true;
}
});
this._updateSpacerSlotWidth();
}

setSelectionForAll(selected, selectAllPages) {
Expand All @@ -360,6 +362,29 @@ class List extends PageableMixin(SelectionMixin(LitElement)) {
return items.length > 0 ? items[0]._getFlattenedListItems().lazyLoadListItems : new Map();
}

_getSpacerWidth(item) {
const shadowRoot = item.shadowRoot;
if (!shadowRoot) return 0;

const layout = shadowRoot.querySelector('d2l-list-item-generic-layout');
const content = shadowRoot.querySelector('[slot="content"]');
const spacer = shadowRoot.querySelector('[slot="spacer"]');
if (!layout || !content || layout.offsetParent === null || content.offsetParent === null) return 0;

const layoutRect = layout.getBoundingClientRect();
const contentRect = content.getBoundingClientRect();
const spacerWidth = spacer ? spacer.getBoundingClientRect().width : 0;
const isRtl = getComputedStyle(layout).direction === 'rtl';
const inlineStartWidth = isRtl ? layoutRect.right - contentRect.right : contentRect.left - layoutRect.left;
let totalWidth = Math.max(0, inlineStartWidth - spacerWidth);

const illustrationSlot = content.querySelector('.d2l-list-item-illustration');
const illustration = illustrationSlot?.assignedElements({ flatten: true })?.[0];
totalWidth += this._measureWithMargins(illustration);

return totalWidth;
}

_handleKeyDown(e) {
if (!this.grid || this.slot === 'nested' || e.keyCode !== keyCodes.TAB) return;
e.preventDefault();
Expand Down Expand Up @@ -394,6 +419,7 @@ class List extends PageableMixin(SelectionMixin(LitElement)) {
this._childHasColor = aChildHasColor;
this._childHasExpandCollapseToggle = aChildHasToggleEnabled;
this._listChildrenUpdatedSubscribers.updateSubscribers();
this._updateSpacerSlotWidth();
}

_handleListItemPropertyChange(e) {
Expand Down Expand Up @@ -491,6 +517,7 @@ class List extends PageableMixin(SelectionMixin(LitElement)) {
});

this._updateItemLayouts(items);
this._updateSpacerSlotWidth();

/** @ignore */
this.dispatchEvent(new CustomEvent('d2l-list-item-showing-count-change', {
Expand All @@ -499,6 +526,14 @@ class List extends PageableMixin(SelectionMixin(LitElement)) {
}));
}

_measureWithMargins(element) {
if (!element || element.offsetParent === null) return 0;
const rect = element.getBoundingClientRect();
const styles = getComputedStyle(element);
const margin = (parseFloat(styles.marginInlineStart) || 0) + (parseFloat(styles.marginInlineEnd) || 0);
return rect.width + margin;
}

_updateActiveSubscriber(subscriber) {
subscriber.updateSiblingHasChildren(this._childHasExpandCollapseToggle);
subscriber.updateSiblingHasColor(this._childHasColor);
Expand All @@ -518,6 +553,35 @@ class List extends PageableMixin(SelectionMixin(LitElement)) {
items.forEach(item => item.layout = (this.layout === listLayouts.tiles ? 'tile' : 'normal'));
}

_updateSpacerSlotWidth() {
if (this._spacerMeasurementScheduled) return;
this._spacerMeasurementScheduled = true;

requestAnimationFrame(() => {
this._spacerMeasurementScheduled = false;

const items = this.getItems() || [];
if (items.length === 0) return;

let maxWidth = 0;
const measurements = [];

for (const item of items) {
const totalWidth = this._getSpacerWidth(item);
if (totalWidth === 0) continue;
measurements.push({ item, width: totalWidth });
if (totalWidth > maxWidth) maxWidth = totalWidth;
}

if (measurements.length === 0) return;

for (const { item, width } of measurements) {
if (!item?.style) continue;
item.style.setProperty('--d2l-list-item-spacer-width', `${Math.max(0, maxWidth - width)}px`);
}
});
}

}

customElements.define('d2l-list', List);
Loading