diff --git a/components/object-property-list/demo/object-property-list.html b/components/object-property-list/demo/object-property-list.html
index d9e0db65d7a..adf6678987a 100644
--- a/components/object-property-list/demo/object-property-list.html
+++ b/components/object-property-list/demo/object-property-list.html
@@ -59,6 +59,19 @@
Object Property List: Skeleton item count set
+ Object Property List: Hidden items
+
+
+
+
+
+
+
+
+
+
+
+
Object Property List: No external whitespace (still contains internal whitespace in the component renderers)
diff --git a/components/object-property-list/object-property-list-item.js b/components/object-property-list/object-property-list-item.js
index 6ffe9acc004..ff1dea51fe4 100644
--- a/components/object-property-list/object-property-list-item.js
+++ b/components/object-property-list/object-property-list-item.js
@@ -11,6 +11,10 @@ import { SkeletonMixin } from '../skeleton/skeleton-mixin.js';
export class ObjectPropertyListItem extends SkeletonMixin(LitElement) {
static get properties() {
return {
+ /**
+ * @ignore
+ */
+ hidden: { type: Boolean },
/**
* Name of an optional icon to display
* @type {string}
@@ -21,6 +25,7 @@ export class ObjectPropertyListItem extends SkeletonMixin(LitElement) {
* @type {string}
*/
text: { type: String },
+ _showSeparator: { state: true },
};
}
@@ -29,12 +34,14 @@ export class ObjectPropertyListItem extends SkeletonMixin(LitElement) {
:host {
vertical-align: middle;
}
+ :host([hidden]) {
+ display: none;
+ }
d2l-icon {
height: 1.2857em; /* 18px desired height at main font size (14px), but using em to scale properly at smaller breakpoint. */
width: 1.2857em;
}
.separator {
- display: var(--d2l-object-property-list-item-separator-display, inline);
margin: 0 -0.05rem; /* 10px desired margin, subtract 5px arbitrary whitespace and 6px whitespace inside bullet icon. */
}
.separator d2l-icon {
@@ -57,6 +64,11 @@ export class ObjectPropertyListItem extends SkeletonMixin(LitElement) {
`];
}
+ constructor() {
+ super();
+ this._showSeparator = true;
+ }
+
render() {
return html`
${this._renderIcon()}
@@ -65,17 +77,27 @@ export class ObjectPropertyListItem extends SkeletonMixin(LitElement) {
`;
}
+ updated(changedProperties) {
+ super.updated(changedProperties);
+ if (changedProperties.has('hidden')) this._onHidden();
+ }
+
+ _onHidden() {
+ /** Dispatched when the visibility of the item changes */
+ this.dispatchEvent(new CustomEvent('d2l-object-property-list-item-visibility-change', { bubbles: true, composed: true }));
+ }
+
_renderIcon() {
return this.icon && !this.skeleton ? html`` : nothing;
}
_renderSeparator() {
- return html`
+ return this._showSeparator ? html`
- `;
+ ` : nothing;
}
_renderText() {
diff --git a/components/object-property-list/object-property-list.js b/components/object-property-list/object-property-list.js
index 278f7635feb..a4297da797a 100644
--- a/components/object-property-list/object-property-list.js
+++ b/components/object-property-list/object-property-list.js
@@ -28,9 +28,6 @@ class ObjectPropertyList extends LocalizeCoreElement(SkeletonMixin(LitElement))
:host([hidden]) {
display: none;
}
- ::slotted(:last-child), slot :last-child {
- --d2l-object-property-list-item-separator-display: none;
- }
::slotted([slot="status"]) {
display: none;
}
@@ -41,6 +38,13 @@ class ObjectPropertyList extends LocalizeCoreElement(SkeletonMixin(LitElement))
`];
}
+ firstUpdated() {
+ this.addEventListener('d2l-object-property-list-item-visibility-change', () => this._onItemsChanged());
+
+ const slot = this.shadowRoot.querySelector('slot:not([name])');
+ if (slot.childElementCount) this._setItemSeparatorVisibility(slot);
+ }
+
render() {
const slotContents = this.skeleton && this.skeletonCount > 0 ? [...Array(this.skeletonCount)].map(() => html`
@@ -50,10 +54,24 @@ class ObjectPropertyList extends LocalizeCoreElement(SkeletonMixin(LitElement))
- ${slotContents}
+ ${slotContents}
`;
}
+
+ _onItemsChanged(e) {
+ const slot = e?.target || this.shadowRoot.querySelector('slot:not([name])');
+ this._setItemSeparatorVisibility(slot);
+ }
+
+ _setItemSeparatorVisibility(slot) {
+ const slottedElements = slot.assignedElements();
+ const elements = slottedElements.length ? slottedElements : [ ...slot.children ];
+ const filtered = elements.filter(item => item.tagName?.toLowerCase().includes('d2l-object-property-list-') && !item.hidden);
+
+ const lastIndex = filtered.length - 1;
+ filtered.forEach((item, i) => item._showSeparator = (i !== lastIndex));
+ }
}
customElements.define('d2l-object-property-list', ObjectPropertyList);
diff --git a/components/object-property-list/test/object-property-list.test.js b/components/object-property-list/test/object-property-list.test.js
index 897fb7d17ce..a2df0a453da 100644
--- a/components/object-property-list/test/object-property-list.test.js
+++ b/components/object-property-list/test/object-property-list.test.js
@@ -6,12 +6,12 @@ import { aTimeout, expect, fixture, html } from '@open-wc/testing';
import { runConstructor } from '../../../tools/constructor-test-helper.js';
const validateSeparators = (elem, count) => {
- const items = elem.querySelectorAll('d2l-object-property-list-item, d2l-object-property-list-item-link');
+ const items = elem.querySelectorAll('d2l-object-property-list-item:not([hidden]), d2l-object-property-list-item-link:not([hidden])');
expect(items.length).to.equal(count);
items.forEach((item, i) => {
- const expectedDisplay = i === items.length - 1 ? 'none' : 'inline';
+ const shouldHaveSeparator = i !== items.length - 1;
const separator = item.shadowRoot.querySelector('.separator');
- expect(window.getComputedStyle(separator).display).to.equal(expectedDisplay);
+ expect(!!separator).to.equal(shouldHaveSeparator);
});
};
@@ -65,6 +65,37 @@ describe('d2l-object-property-list', () => {
await aTimeout(); // Required for Webkit only.
validateSeparators(elem, 2);
});
+
+ it('should display correctly if status slot is after all items', async() => {
+ const elem = await fixture(html`
+
+
+
+
+
+ `);
+ validateSeparators(elem, 2);
+ });
+
+ it('should respond to hidden items', async() => {
+ const elem = await fixture(html`
+
+
+
+
+
+
+ `);
+ validateSeparators(elem, 2);
+
+ elem.querySelector('#hidden').removeAttribute('hidden');
+ await elem.updateComplete;
+ validateSeparators(elem, 3);
+
+ elem.querySelector('#hidden').setAttribute('hidden', '');
+ await elem.updateComplete;
+ validateSeparators(elem, 2);
+ });
});
});
diff --git a/components/object-property-list/test/object-property-list.visual-diff.html b/components/object-property-list/test/object-property-list.visual-diff.html
index 09eb2ecb520..fa1c6d6d613 100644
--- a/components/object-property-list/test/object-property-list.visual-diff.html
+++ b/components/object-property-list/test/object-property-list.visual-diff.html
@@ -69,5 +69,14 @@
+
+
+
+
+
+
+
+
+