/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {html, LitElement} from 'lit';
import {property, queryAll} from 'lit/decorators.js';
/**
* An item layout component.
*/
export class Item extends LitElement {
/**
* Only needed for SSR.
*
* Add this attribute when an item has two lines to avoid a Flash Of Unstyled
* Content. This attribute is not needed for single line items or items with
* three or more lines.
*/
@property({type: Boolean, reflect: true}) multiline = false;
@queryAll('.text slot') private readonly textSlots!: HTMLSlotElement[];
override render() {
return html`
`;
}
private handleTextSlotChange() {
// Check if there's more than one text slot with content. If so, the item is
// multiline, which has a different min-height than single line items.
let isMultiline = false;
let slotsWithContent = 0;
for (const slot of this.textSlots) {
if (slotHasContent(slot)) {
slotsWithContent += 1;
}
if (slotsWithContent > 1) {
isMultiline = true;
break;
}
}
this.multiline = isMultiline;
}
}
function slotHasContent(slot: HTMLSlotElement) {
for (const node of slot.assignedNodes({flatten: true})) {
// Assume there's content if there's an element slotted in
const isElement = node.nodeType === Node.ELEMENT_NODE;
// If there's only text nodes for the default slot, check if there's
// non-whitespace.
const isTextWithContent =
node.nodeType === Node.TEXT_NODE && node.textContent?.match(/\S/);
if (isElement || isTextWithContent) {
return true;
}
}
return false;
}