Details
The Details component is an expandable panel for showing and hiding content from the user to make the UI less crowded.
new tab
@customElement('details-basic')
export class Example extends LitElement {
protected createRenderRoot() {
const root = super.createRenderRoot();
// Apply custom theme (only supported if your app uses one)
applyTheme(root);
return root;
}
render() {
return html`
<vaadin-details opened>
<div slot="summary">Contact information</div>
<vaadin-vertical-layout>
<span>Sophia Williams</span>
<span>sophia.williams@company.com</span>
<span>(501) 555-9128</span>
</vaadin-vertical-layout>
</vaadin-details>
`;
}
}
Anatomy
Details consists of a summary and a content area.
Summary
The Summary is the part that is always visible, and typically describes the contents, for example, with a title. Clicking on the summary toggles the content area’s visibility.
The summary supports rich content and can contain any component. This can be utilised for example to indicate the status of the corresponding content.
new tab
@customElement('details-summary')
export class Example extends LitElement {
protected createRenderRoot() {
const root = super.createRenderRoot();
// Apply custom theme (only supported if your app uses one)
applyTheme(root);
return root;
}
@state()
private items: Country[] = [];
@state()
private responsiveSteps: FormLayoutResponsiveStep[] = [
{ minWidth: 0, columns: 1 },
{ minWidth: '20em', columns: 2 },
];
async firstUpdated() {
this.items = await getCountries();
}
render() {
return html`
<vaadin-details opened>
<vaadin-horizontal-layout
slot="summary"
style="justify-content: space-between; width: 100%;"
>
<span>Contact information</span>
<vaadin-horizontal-layout
style="color: var(--lumo-error-text-color); margin-left: var(--lumo-space-s)"
>
<vaadin-icon
icon="vaadin:exclamation-circle"
style="width: var(--lumo-icon-size-s); height: var(--lumo-icon-size-s);"
></vaadin-icon>
<span>2 errors</span>
</vaadin-horizontal-layout>
</vaadin-horizontal-layout>
<vaadin-form-layout .responsiveSteps="${this.responsiveSteps}">
<vaadin-text-field
label="Address"
value="4027 Amber Lake Canyon"
colspan="2"
></vaadin-text-field>
<vaadin-text-field label="ZIP code" required></vaadin-text-field>
<vaadin-text-field label="City" required></vaadin-text-field>
<vaadin-combo-box
label="Country"
item-label-path="name"
item-value-path="id"
.items="${this.items}"
>
</vaadin-combo-box>
</vaadin-form-layout>
</vaadin-details>
`;
}
}
Content
This is the collapsible part of Details. It can contain any component. When the content area is collapsed, the content is invisible and inaccessible by keyboard or screen reader.
new tab
@customElement('details-content')
export class Example extends LitElement {
protected createRenderRoot() {
const root = super.createRenderRoot();
// Apply custom theme (only supported if your app uses one)
applyTheme(root);
return root;
}
static get styles() {
return css`
a {
text-decoration: none;
color: var(--lumo-primary-text-color);
}
`;
}
render() {
return html`
<vaadin-details opened>
<div slot="summary">Analytics</div>
<vaadin-vertical-layout>
<a href="#">Dashboard</a>
<a href="#">Reports</a>
<a href="#">Data sources</a>
</vaadin-vertical-layout>
</vaadin-details>
<vaadin-details opened>
<div slot="summary">Customers</div>
<vaadin-vertical-layout>
<a href="#">Accounts</a>
<a href="#">Contacts</a>
</vaadin-vertical-layout>
</vaadin-details>
<vaadin-details opened>
<div slot="summary">Finances</div>
<vaadin-vertical-layout>
<a href="#">Invoices</a>
<a href="#">Transactions</a>
<a href="#">Statements</a>
</vaadin-vertical-layout>
</vaadin-details>
`;
}
}
Theme Variants
Details has three theme variants: filled
, small
, and reverse
.
Theme variants can be freely combined with each other.
For example, all three themes variants can be applied to the same Details component.
Filled
The filled
theme variant makes the component’s boundaries visible, which helps tie its content together visually and distinguishes it from the surrounding UI.
new tab
@customElement('details-filled')
export class Example extends LitElement {
protected createRenderRoot() {
const root = super.createRenderRoot();
// Apply custom theme (only supported if your app uses one)
applyTheme(root);
return root;
}
render() {
return html`
<vaadin-details opened theme="filled">
<div slot="summary">Members (8)</div>
<ul>
<li>Blake Martin</li>
<li>Caroline Clark</li>
<li>Avery Torres</li>
<li>Khloe Scott</li>
<li>Camila Fisher</li>
<li>Gavin Lewis</li>
<li>Isabella Powell</li>
<li>Zoe Wilson</li>
</ul>
</vaadin-details>
`;
}
}
Small
Use the small
theme variant for compact UIs.
new tab
@customElement('details-small')
export class Example extends LitElement {
protected createRenderRoot() {
const root = super.createRenderRoot();
// Apply custom theme (only supported if your app uses one)
applyTheme(root);
return root;
}
render() {
return html`
<vaadin-details opened theme="small">
<div slot="summary">Members (8)</div>
<ul>
<li>Blake Martin</li>
<li>Caroline Clark</li>
<li>Avery Torres</li>
<li>Khloe Scott</li>
<li>Camila Fisher</li>
<li>Gavin Lewis</li>
<li>Isabella Powell</li>
<li>Zoe Wilson</li>
</ul>
</vaadin-details>
`;
}
}
Reverse
The reverse theme variant places the toggle icon after the summary contents, which can be useful for visually aligning the summary with other content.
new tab
@customElement('details-reverse')
export class Example extends LitElement {
protected createRenderRoot() {
const root = super.createRenderRoot();
// Apply custom theme (only supported if your app uses one)
applyTheme(root);
return root;
}
render() {
return html`
<vaadin-details opened theme="reverse">
<div slot="summary">Members (8)</div>
<ul>
<li>Blake Martin</li>
<li>Caroline Clark</li>
<li>Avery Torres</li>
<li>Khloe Scott</li>
<li>Camila Fisher</li>
<li>Gavin Lewis</li>
<li>Isabella Powell</li>
<li>Zoe Wilson</li>
</ul>
</vaadin-details>
`;
}
}
Disabled
Details can be disabled to prevent them from being expanded or collapsed. Components inside a disabled expanded Details are automatically disabled as well.
new tab
@customElement('details-disabled')
export class Example extends LitElement {
protected createRenderRoot() {
const root = super.createRenderRoot();
// Apply custom theme (only supported if your app uses one)
applyTheme(root);
return root;
}
render() {
return html`
<vaadin-details disabled>
<div slot="summary">Members (8)</div>
<ul>
<li>Blake Martin</li>
<li>Caroline Clark</li>
<li>Avery Torres</li>
<li>Khloe Scott</li>
<li>Camila Fisher</li>
<li>Gavin Lewis</li>
<li>Isabella Powell</li>
<li>Zoe Wilson</li>
</ul>
</vaadin-details>
`;
}
}
Best Practices
Use Details to group related content and to lessen the risk of overwhelming the user with information. However, avoid putting important information in a Details component unless it is expanded by default. Otherwise, the user might not notice it.
Details can be used instead of Accordion if there is a need to see content from multiple collapsible content areas simultaneously.