Skip to content

Accordion

<loomi-accordion> / <loomi-accordion-item> is a simple stack of clickable headers that when clicked on, expand to reveal their content or collapse to hide their content.

Terminal window
npm install @loomidev/accordion lit
import "@loomidev/accordion";

Each item needs a title for the clickable header, and the content goes in the default slot.

LoomiUI is an open-source UI component library built with Lit and Web Components, designed to help developers build modern, accessible, and high-performance user interfaces that work across frameworks and platforms. By embracing web standards, its components can be used in plain HTML or integrated seamlessly into frameworks such as Astro, Laravel, React, Vue, Angular, and Svelte. The library emphasizes consistency, composability, theming through CSS custom properties, and an excellent developer experience backed by comprehensive, interactive documentation.

Beyond the core library, LoomiUI is envisioned as a complete ecosystem for building production-ready applications. While the core components remain free and open source, developers can extend their workflow with premium templates, starter kits, advanced components, and developer tools that accelerate development without sacrificing flexibility. Every component is documented with live, interactive examples that demonstrate its capabilities, making it easy for developers to learn, customize, and confidently adopt LoomiUI in projects of any size.

LoomiUI is installed with npm, following the same setup flow as most modern frontend libraries.

If you are new to LoomiUI, the recommended starting point is the main package. Installing this package registers all available LoomiUI components in one step, which lets you start building right away without deciding on individual component packages up front.

You customize LoomiUI with normal CSS variables, just like any other styles in your app. Add the variables in your own stylesheet, and every LoomiUI component on the page can pick them up automatically.

That means you can start small: change one color, preview it, and adjust as needed. When you are happy with it, the same values apply across buttons, inputs, alerts, and more.

<loomi-accordion>
<loomi-accordion-item title="What is LoomiUI?">
<div>
<p>
LoomiUI is an open-source UI component library built with Lit and Web Components, designed to help developers build modern, accessible, and high-performance user interfaces that work across frameworks and platforms. By embracing web standards, its components can be used in plain HTML or integrated seamlessly into frameworks such as Astro, Laravel, React, Vue, Angular, and Svelte. The library emphasizes consistency, composability, theming through CSS custom properties, and an excellent developer experience backed by comprehensive, interactive documentation.</p>
<p>
Beyond the core library, LoomiUI is envisioned as a complete ecosystem for building production-ready applications. While the core components remain free and open source, developers can extend their workflow with premium templates, starter kits, advanced components, and developer tools that accelerate development without sacrificing flexibility. Every component is documented with live, interactive examples that demonstrate its capabilities, making it easy for developers to learn, customize, and confidently adopt LoomiUI in projects of any size.
</p>
</div>
</loomi-accordion-item>
<loomi-accordion-item title="How do I install it?">
<div>
<p>LoomiUI is installed with npm, following the same setup flow as most modern frontend libraries.</p>
<p class="pt-4">
If you are new to LoomiUI, the recommended starting point is the main package. Installing this package registers all available LoomiUI components in one step, which lets you start building right away without deciding on individual component packages up front.
</p>
</div>
</loomi-accordion-item>
<loomi-accordion-item title="Can I theme it?">
<p>You customize LoomiUI with normal CSS variables, just like any other styles in your app. Add the variables in your own stylesheet, and every LoomiUI component on the page can pick them up automatically.</p>
<p>That means you can start small: change one color, preview it, and adjust as needed. When you are happy with it, the same values apply across buttons, inputs, alerts, and more.</p>
</loomi-accordion-item>
</loomi-accordion>

Need something richer than plain text? Use the title slot instead of the title attribute.

What is LoomiUI?
v1.0.0

LoomiUI is an open-source UI component library built with Lit and Web Components, designed to help developers build modern, accessible, and high-performance user interfaces that work across frameworks and platforms. By embracing web standards, its components can be used in plain HTML or integrated seamlessly into frameworks such as Astro, Laravel, React, Vue, Angular, and Svelte. The library emphasizes consistency, composability, theming through CSS custom properties, and an excellent developer experience backed by comprehensive, interactive documentation.

<loomi-accordion>
<loomi-accordion-item>
<div slot="title" style="display:flex;align-items:center;gap:0.5rem">
<loomi-icon name="cube"></loomi-icon>
<div>
<div>What is LoomiUI?</div>
<div class="text-xs text-gray-500">v1.0.0</div>
</div>
</div>
<p>
LoomiUI is an open-source UI component library built with Lit and Web Components, designed to help developers build modern, accessible, and high-performance user interfaces that work across frameworks and platforms. By embracing web standards, its components can be used in plain HTML or integrated seamlessly into frameworks such as Astro, Laravel, React, Vue, Angular, and Svelte. The library emphasizes consistency, composability, theming through CSS custom properties, and an excellent developer experience backed by comprehensive, interactive documentation.</p>
</p>
</loomi-accordion-item>
</loomi-accordion>

This section starts expanded.

This one doesn't.

<loomi-accordion>
<loomi-accordion-item title="Open on load" open>
<p>This section starts expanded.</p>
</loomi-accordion-item>
<loomi-accordion-item title="Closed on load">
<p>This one doesn't.</p>
</loomi-accordion-item>
</loomi-accordion>

By default opening one item closes whatever else is open. Set can-open-multiple to let items stay open independently.

Morning lifts the blinds and paints the room in gold. Soft rain counts the roofs while the garden learns its song.
<loomi-accordion can-open-multiple>
<loomi-accordion-item title="Dawn" open>Morning lifts the blinds and paints the room in gold.</loomi-accordion-item>
<loomi-accordion-item title="Rain" open>Soft rain counts the roofs while the garden learns its song.</loomi-accordion-item>
</loomi-accordion>

By default items sit inside one shared card, separated by divider lines. Set grouped="false" for each item to render as its own standalone card.

A small wind signs its name across the lake. The moon keeps watch while city windows blink.
<loomi-accordion grouped="false">
<loomi-accordion-item title="Standalone breeze">A small wind signs its name across the lake.</loomi-accordion-item>
<loomi-accordion-item title="Standalone moon">The moon keeps watch while city windows blink.</loomi-accordion-item>
</loomi-accordion>
<loomi-accordion-item title="Tight content" no-padding>
<img src="/banner.jpg" alt="" />
</loomi-accordion-item>

For the library-wide baseline, see Foundations — Accessibility.

For the shared container and viewport rules, see Foundations — Responsive behavior.

For theme activation, token overrides, and contrast guidance, see Foundations — Dark mode.

AttributeDefaultDescription
groupedtrueGroup items in one card (vs standalone cards). (boolean)
can-open-multiplefalseAllow multiple open items. (boolean)
color(blank)Background color when grouped="false".
AttributeDefaultDescription
title(blank)Header text (or use the title slot).
openfalseOpen by default. (boolean)
color(blank)Standalone background color.
no-paddingfalseRemove body padding. (boolean)
SlotDescription
(default)Content placed inside the component.
titleCustom title content.
EventDescription
loomi-accordion-toggleFired when the accordion is toggled.

Small pieces of UI,
stitched lightly to any app,
ready when called.

Install what you need,
import once at the app edge,
then write the element.

<loomi-accordion grouped="false" can-open-multiple color="error">
<loomi-accordion-item title="What is loomi?" open>
<p>Small pieces of UI,<br />stitched lightly to any app,<br />ready when called.</p>
</loomi-accordion-item>
<loomi-accordion-item title="How do I install it?">
<p>Install what you need,<br />import once at the app edge,<br />then write the element.</p>
</loomi-accordion-item>
</loomi-accordion>

<loomi-accordion-item> and <loomi-accordion> are standard custom elements, so the browser can use them in plain HTML, Blade, React, Vue, Angular, Svelte, Astro, and most other frameworks. The important beginner rule is: install the package, import it once before the tag is rendered, then write the Loomi tag in your template.

Run install commands from the app where you want to use this component. That means the folder that contains that app’s package.json. Do not run these install commands from packages/accordion unless you are editing LoomiUI itself.

Terminal window
cd /path/to/your-app
npm install @loomidev/accordion lit

If you are contributing to LoomiUI itself, first move to the top-level components folder. That is where the main package.json for all packages lives, and pnpm --filter ... commands should be run from there:

Terminal window
cd /path/to/your-copy-of-loomiui/components
pnpm --filter @loomidev/accordion build
pnpm --filter @loomidev/accordion typecheck

Use the CDN version for prototypes, documentation pages, or a quick reproduction. The import map tells the browser where to find Lit, which Loomi components use internally.

<script type="importmap">
{ "imports": { "lit": "https://esm.sh/lit@3.3.3", "lit/": "https://esm.sh/lit@3.3.3/" } }
</script>
<script type="module" src="https://esm.sh/@loomidev/accordion"></script>
<loomi-accordion>
<loomi-accordion-item title="Shipping">Orders usually ship in 2 business days.</loomi-accordion-item>
<loomi-accordion-item title="Returns">Returns are accepted within 30 days.</loomi-accordion-item>
</loomi-accordion>

In Vite, Webpack, Parcel, Rollup, or a framework build pipeline, install the package and import it once in your main app JavaScript file. After that, you can use the Loomi tag anywhere in your app.

import "@loomidev/accordion";

Run the install command from your Laravel project root, then import the component in resources/js/app.js. If your project uses Laravel Vite, npm run dev and npm run build should also be run from the Laravel project root.

Terminal window
cd /path/to/your-laravel-app
npm install @loomidev/accordion lit
npm run dev
resources/js/app.js
import "@loomidev/accordion";
<loomi-accordion>
<loomi-accordion-item title="Shipping">Orders usually ship in 2 business days.</loomi-accordion-item>
<loomi-accordion-item title="Returns">Returns are accepted within 30 days.</loomi-accordion-item>
</loomi-accordion>

React can render Loomi tags directly. If you are on React 18, or if you need to pass arrays, objects, or functions, use a ref and assign those values after the component mounts.

import "@loomidev/accordion";
export function LoomiExample() {
return (
<loomi-accordion>
<loomi-accordion-item title="Shipping">Orders usually ship in 2 business days.</loomi-accordion-item>
<loomi-accordion-item title="Returns">Returns are accepted within 30 days.</loomi-accordion-item>
</loomi-accordion>
);
}

If TypeScript does not recognize the Loomi tag in JSX, add it to your app’s JSX type declarations.

Import the package in the component that uses it, or once in your main Vue file. Vue templates can use Loomi tags directly. For arrays, objects, or functions, pass the value as a JavaScript property instead of as plain text.

<script setup>
import "@loomidev/accordion";
</script>
<template>
<loomi-accordion>
<loomi-accordion-item title="Shipping">Orders usually ship in 2 business days.</loomi-accordion-item>
<loomi-accordion-item title="Returns">Returns are accepted within 30 days.</loomi-accordion-item>
</loomi-accordion>
</template>

If Vue warns that the tag is an unknown component, configure compilerOptions.isCustomElement for tags that start with loomi- in your Vite or Vue config.

Import the package once and tell Angular to allow custom HTML tags with CUSTOM_ELEMENTS_SCHEMA. For NgModule apps, add the schema to the module instead of the standalone component.

app.component.ts
import { CUSTOM_ELEMENTS_SCHEMA, Component } from "@angular/core";
import "@loomidev/accordion";
@Component({
selector: "app-root",
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `
<loomi-accordion>
<loomi-accordion-item title="Shipping">Orders usually ship in 2 business days.</loomi-accordion-item>
<loomi-accordion-item title="Returns">Returns are accepted within 30 days.</loomi-accordion-item>
</loomi-accordion>
`,
})
export class AppComponent {}

Svelte can import the package inside a component script. Astro can import it in the frontmatter of the page or layout where the tag appears.

<script>
import "@loomidev/accordion";
</script>
<loomi-accordion>
<loomi-accordion-item title="Shipping">Orders usually ship in 2 business days.</loomi-accordion-item>
<loomi-accordion-item title="Returns">Returns are accepted within 30 days.</loomi-accordion-item>
</loomi-accordion>
---
import "@loomidev/accordion";
---
<loomi-accordion>
<loomi-accordion-item title="Shipping">Orders usually ship in 2 business days.</loomi-accordion-item>
<loomi-accordion-item title="Returns">Returns are accepted within 30 days.</loomi-accordion-item>
</loomi-accordion>

Frameworks such as Next.js, Nuxt, SvelteKit, and Astro sometimes render HTML on the server before browser-only code runs. If your framework complains, move the Loomi import to client-side code. In Next.js, that usually means a component with "use client"; in Nuxt, it often means a .client.ts plugin.

  • @loomidev/core