Accordions
Overview
Accordions are great way to compact content blocs and display required ones by clicking on it.
Installation
Notes
To use this component, you need to initialize your project first. If not done yet, run one of the following command:
npx jsxpine init or yarn jsxpine init or pnpm jsxpine init or bunx jsxpine init.
Go to the installation and usage page to learn more.
jsxpine add accordion
Copied !
-------------------- Accordion Component -------------------------
import clsx from "clsx";
/**
* @typedef {Extract<import("../common/types").HTMLTagNameType, "body" | "div" | "section" | "article" | "nav" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "button" | "p" | "span" | "header" | "footer" | "ul" | "ol" | "li" | "strong" | "em">} AccordionTagType
*/
/**
* @typedef AccordionProps
* @type {import("../common/props").HTMLTagWithChildren & { as?: AccordionTagType }}
*/
/**
* Group Accordion Content props
* @param {AccordionProps} props
*/
export function GroupAccordionContent({
children,
class: className = "",
as = "div",
...restProps
}) {
return (
<tag
of={as}
x-show="isActive(id)"
x-collapse
class={clsx(className)}
{...restProps}
>
{children}
</tag>
);
}
/**
* Group Accordion Trigger props
* @param {AccordionProps} props
*/
export function GroupAccordionTrigger({
children,
class: className,
as = "div",
...restProps
}) {
return (
<tag
of={as}
x-on:click="setActiveAccordion(id)"
class={clsx(
"cursor-pointer",
className
)}
{...restProps}
>
{children}
</tag>
);
}
/**
* Group Accordion Item props
* @param {AccordionProps} props
*/
export function GroupAccordionItem({
children,
class: className,
as = "div",
...restProps
}) {
return (
<tag
of={as}
x-data="{ id: $id('accordion-item') }"
class={clsx("flex flex-col", className)}
{...restProps}
>
{children}
</tag>
);
}
/**
* Group Accordion List props
* @param {AccordionProps} props
*/
export function GroupAccordionList({
children,
class: className,
as = "div",
...restProps
}) {
return (
<tag
of={as}
x-data="groupAccordion"
class={clsx("flex flex-col w-full", className)}
{...restProps}
>
{children}
</tag>
);
}
/**
* Solo Accordion Trigger props
* @param {AccordionProps} props
*/
export function SoloAccordionTrigger(props) {
const { class: className, children, as = "div", ...restProps } = props;
return (
<tag
of={as}
x-bind="trigger"
class={clsx(className, "cursor-pointer")}
{...restProps}
>
{children}
</tag>
);
}
/**
* Solo Accordion Content props
* @param {AccordionProps} props
*/
export function SoloAccordionContent({
children,
class: className,
as = "div",
...restProps
}) {
return (
<tag
of={as}
x-bind="display"
x-collapse
class={className}
{...restProps}
>
{children}
</tag>
);
}
/**
* Solo Accordion props
* @type {import("../common/props").JSXComponent<AccordionProps>}
*/
export function SoloAccordion({
children,
class: className,
as = "div",
...restProps
}) {
return (
<tag
of={as}
x-data="soloAccordion"
class={clsx("w-full", className)}
{...restProps}
>
{children}
</tag>
);
}
-------------------- Alpine Dependencies -------------------------
/**
* @typedef {Object} GroupAccordionDataOutput
* @property {string} activeAccordion
* @property {(id: string) => void} setActiveAccordion
* @property {(id: string) => boolean} isActive
*/
/**
* Group Accordion alpine data
* @returns {import("alpinejs").AlpineComponent<GroupAccordionDataOutput>}
*/
export function groupAccordionData() {
return {
activeAccordion: "",
setActiveAccordion(id) {
this.activeAccordion = this.activeAccordion == id ? "" : id;
},
isActive(id) {
return this.activeAccordion === id;
},
};
}
/**
* @typedef {Object} SoloAccordionDataOutput
* @property {boolean} show
* @property {Function} close
* @property {Function} open
* @property {Function} toggle
* @property {Record<string, Function>} trigger
* @property {Record<string, () => boolean>} display
*/
/**
* Solo Accordion alpine data
* @returns {import("alpinejs").AlpineComponent<SoloAccordionDataOutput>}
*/
export function soloAccordionData() {
return {
show: false,
open() {
this.show = true;
},
close() {
this.show = false;
},
toggle() {
this.show = !this.show;
},
trigger: {
["@click"]() {
this.toggle();
}
},
display: {
["x-show"]() {
return this.show;
}
}
};
}
Solo Accordion
Enables accordion feature individually
Click here to toggle content below
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempus finibus magna et dictum. Aenean volutpat et nisi id interdum. Integer nec lectus gravida, aliquet odio a, elementum turpis. Sed efficitur ligula lacus, ut laoreet lorem vulputate eget. Vivamus eget nulla elementum, auctor nisi vitae, elementum tortor.
Click here to toggle content below
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempus finibus magna et dictum. Aenean volutpat et nisi id interdum. Integer nec lectus gravida, aliquet odio a, elementum turpis. Sed efficitur ligula lacus, ut laoreet lorem vulputate eget. Vivamus eget nulla elementum, auctor nisi vitae, elementum tortor.
Click here to toggle content below
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempus finibus magna et dictum. Aenean volutpat et nisi id interdum. Integer nec lectus gravida, aliquet odio a, elementum turpis. Sed efficitur ligula lacus, ut laoreet lorem vulputate eget. Vivamus eget nulla elementum, auctor nisi vitae, elementum tortor.
Copied !
import {
SoloAccordion,
SoloAccordionContent,
SoloAccordionTrigger
} from "$components/accordion.component";
export function SoloAccordionExample() {
return (
<>
<SoloAccordion class="bg-white border rounded text-slate-900">
<SoloAccordionTrigger as="h2" class="text-center p-4">
Click here to toggle content below
</SoloAccordionTrigger>
<SoloAccordionContent as="p" class="p-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempus
finibus magna et dictum. Aenean volutpat et nisi id interdum. Integer
nec lectus gravida, aliquet odio a, elementum turpis. Sed efficitur
ligula lacus, ut laoreet lorem vulputate eget. Vivamus eget nulla
elementum, auctor nisi vitae, elementum tortor.
</SoloAccordionContent>
</SoloAccordion>
<SoloAccordion class="bg-black text-white border rounded">
<SoloAccordionTrigger as="h2" class="text-center p-4">
Click here to toggle content below
</SoloAccordionTrigger>
<SoloAccordionContent as="p" class="p-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempus
finibus magna et dictum. Aenean volutpat et nisi id interdum. Integer
nec lectus gravida, aliquet odio a, elementum turpis. Sed efficitur
ligula lacus, ut laoreet lorem vulputate eget. Vivamus eget nulla
elementum, auctor nisi vitae, elementum tortor.
</SoloAccordionContent>
</SoloAccordion>
<SoloAccordion class="bg-slate-300 text-slate-900 border rounded">
<SoloAccordionTrigger as="h2" class="text-center p-4">
Click here to toggle content below
</SoloAccordionTrigger>
<SoloAccordionContent as="p" class="p-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempus
finibus magna et dictum. Aenean volutpat et nisi id interdum. Integer
nec lectus gravida, aliquet odio a, elementum turpis. Sed efficitur
ligula lacus, ut laoreet lorem vulputate eget. Vivamus eget nulla
elementum, auctor nisi vitae, elementum tortor.
</SoloAccordionContent>
</SoloAccordion>
</>
);
}
Group Accordion
Groups accordions and display only one (closing previous opened one).
Click here and close all others.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempus finibus magna et dictum. Aenean volutpat et nisi id interdum. Integer nec lectus gravida, aliquet odio a, elementum turpis. Sed efficitur ligula lacus, ut laoreet lorem vulputate eget. Vivamus eget nulla elementum, auctor nisi vitae, elementum tortor.
Click here and close all others.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempus finibus magna et dictum. Aenean volutpat et nisi id interdum. Integer nec lectus gravida, aliquet odio a, elementum turpis. Sed efficitur ligula lacus, ut laoreet lorem vulputate eget. Vivamus eget nulla elementum, auctor nisi vitae, elementum tortor.
Click here and close all others.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempus finibus magna et dictum. Aenean volutpat et nisi id interdum. Integer nec lectus gravida, aliquet odio a, elementum turpis. Sed efficitur ligula lacus, ut laoreet lorem vulputate eget. Vivamus eget nulla elementum, auctor nisi vitae, elementum tortor.
Copied !
import {
GroupAccordionList,
GroupAccordionItem,
GroupAccordionTrigger,
GroupAccordionContent
} from "$components/accordion.component";
export function GroupAccordionExample() {
return (
<GroupAccordionList class="gap-y-4">
<GroupAccordionItem class="bg-white border rounded text-slate-900">
<GroupAccordionTrigger
as="h2"
class="p-4 w-full text-center "
x-bind:class="{ 'border-b': isActive(id) }"
>
Click here and close all others.
</GroupAccordionTrigger>
<GroupAccordionContent as="p" class="p-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempus
finibus magna et dictum. Aenean volutpat et nisi id interdum. Integer
nec lectus gravida, aliquet odio a, elementum turpis. Sed efficitur
ligula lacus, ut laoreet lorem vulputate eget. Vivamus eget nulla
elementum, auctor nisi vitae, elementum tortor.
</GroupAccordionContent>
</GroupAccordionItem>
<GroupAccordionItem class="bg-black text-white border rounded">
<GroupAccordionTrigger as="h2" class="p-4 w-full text-center">
Click here and close all others.
</GroupAccordionTrigger>
<GroupAccordionContent as="p" class="p-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempus
finibus magna et dictum. Aenean volutpat et nisi id interdum. Integer
nec lectus gravida, aliquet odio a, elementum turpis. Sed efficitur
ligula lacus, ut laoreet lorem vulputate eget. Vivamus eget nulla
elementum, auctor nisi vitae, elementum tortor.
</GroupAccordionContent>
</GroupAccordionItem>
<GroupAccordionItem class="bg-slate-300 text-slate-900 border rounded">
<GroupAccordionTrigger as="h2" class="p-4 w-full text-center">
Click here and close all others.
</GroupAccordionTrigger>
<GroupAccordionContent as="p" class="p-4">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tempus
finibus magna et dictum. Aenean volutpat et nisi id interdum. Integer
nec lectus gravida, aliquet odio a, elementum turpis. Sed efficitur
ligula lacus, ut laoreet lorem vulputate eget. Vivamus eget nulla
elementum, auctor nisi vitae, elementum tortor.
</GroupAccordionContent>
</GroupAccordionItem>
</GroupAccordionList>
);
}