feat: added accordion component
This commit is contained in:
@@ -0,0 +1,54 @@
|
|||||||
|
.accordionItem {
|
||||||
|
border-bottom: 1px solid var(--Base-Border-Subtle);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
padding: var(--Spacing-x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card .summary {
|
||||||
|
padding: var(--Spacing-x1) var(--Spacing-x-one-and-half);
|
||||||
|
border-radius: var(--Corner-radius-Medium);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq .summary {
|
||||||
|
padding: var(--Spacing-x2) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq .content {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--Spacing-x2);
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--Base-Text-High-contrast);
|
||||||
|
font-family: var(--typography-Body-Bold-fontFamily);
|
||||||
|
font-size: var(--typography-Body-Bold-fontSize);
|
||||||
|
font-weight: var(--typography-Body-Bold-fontWeight);
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary:hover,
|
||||||
|
.summary:focus {
|
||||||
|
background-color: var(--Base-Surface-Primary-light-Hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 0 var(--Spacing-x-one-and-half);
|
||||||
|
overflow: hidden;
|
||||||
|
max-height: 0;
|
||||||
|
transition: max-height 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chevron {
|
||||||
|
transition: transform 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
details[open] .chevron {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { VariantProps } from "class-variance-authority"
|
||||||
|
|
||||||
|
import { accordionItemVariants } from "./variants"
|
||||||
|
|
||||||
|
export interface AccordionItemProps
|
||||||
|
extends React.HtmlHTMLAttributes<HTMLDetailsElement>,
|
||||||
|
VariantProps<typeof accordionItemVariants> {
|
||||||
|
title: string
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { useRef } from "react"
|
||||||
|
|
||||||
|
import { ChevronDownIcon } from "@/components/Icons"
|
||||||
|
|
||||||
|
import { AccordionItemProps } from "./accordionItem"
|
||||||
|
import { accordionItemVariants } from "./variants"
|
||||||
|
|
||||||
|
import styles from "./accordionItem.module.css"
|
||||||
|
|
||||||
|
export default function AccordionItem({
|
||||||
|
children,
|
||||||
|
title,
|
||||||
|
variant,
|
||||||
|
}: AccordionItemProps) {
|
||||||
|
const contentRef = useRef<HTMLDivElement>(null)
|
||||||
|
const detailsRef = useRef<HTMLDetailsElement>(null)
|
||||||
|
|
||||||
|
function toggleAccordion() {
|
||||||
|
const details = detailsRef.current
|
||||||
|
const content = contentRef.current
|
||||||
|
if (details && content) {
|
||||||
|
if (details.open) {
|
||||||
|
content.style.maxHeight = `${content.scrollHeight}px`
|
||||||
|
content.addEventListener(
|
||||||
|
"transitionend",
|
||||||
|
() => {
|
||||||
|
// Remove maxHeight after transition to allow content to transition multiple times
|
||||||
|
content.style.maxHeight = "none"
|
||||||
|
},
|
||||||
|
{ once: true }
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
content.style.maxHeight = "0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li className={accordionItemVariants({ variant })}>
|
||||||
|
<details ref={detailsRef} onToggle={toggleAccordion}>
|
||||||
|
<summary className={styles.summary}>
|
||||||
|
<span>{title}</span>
|
||||||
|
<ChevronDownIcon className={styles.chevron} color="burgundy" />
|
||||||
|
</summary>
|
||||||
|
<div ref={contentRef} className={styles.content}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { cva } from "class-variance-authority"
|
||||||
|
|
||||||
|
import styles from "./accordionItem.module.css"
|
||||||
|
|
||||||
|
export const accordionItemVariants = cva(styles.accordionItem, {
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
card: styles.card,
|
||||||
|
faq: styles.faq,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: "card",
|
||||||
|
},
|
||||||
|
})
|
||||||
11
components/TempDesignSystem/Accordion/accordion.module.css
Normal file
11
components/TempDesignSystem/Accordion/accordion.module.css
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
.accordion {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
border-radius: var(--Corner-radius-Medium);
|
||||||
|
background-color: var(--Base-Surface-Primary-light-Normal);
|
||||||
|
}
|
||||||
|
.faq {
|
||||||
|
background-color: var(--Base-Background-Primary-Normal);
|
||||||
|
}
|
||||||
7
components/TempDesignSystem/Accordion/accordion.ts
Normal file
7
components/TempDesignSystem/Accordion/accordion.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { VariantProps } from "class-variance-authority"
|
||||||
|
|
||||||
|
import { accordionVariants } from "./variants"
|
||||||
|
|
||||||
|
export interface AccordionProps
|
||||||
|
extends React.HtmlHTMLAttributes<HTMLUListElement>,
|
||||||
|
VariantProps<typeof accordionVariants> {}
|
||||||
22
components/TempDesignSystem/Accordion/index.tsx
Normal file
22
components/TempDesignSystem/Accordion/index.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { Children, cloneElement, isValidElement } from "react"
|
||||||
|
|
||||||
|
import { AccordionItemProps } from "./AccordionItem/accordionItem"
|
||||||
|
import { AccordionProps } from "./accordion"
|
||||||
|
import { accordionVariants } from "./variants"
|
||||||
|
|
||||||
|
export default function Accordion({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
variant,
|
||||||
|
}: AccordionProps) {
|
||||||
|
return (
|
||||||
|
<ul className={accordionVariants({ className, variant })}>
|
||||||
|
{Children.map(children, (child) => {
|
||||||
|
if (isValidElement<AccordionItemProps>(child)) {
|
||||||
|
return cloneElement(child, { variant })
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
{/* {children} */}
|
||||||
|
</ul>
|
||||||
|
)
|
||||||
|
}
|
||||||
15
components/TempDesignSystem/Accordion/variants.ts
Normal file
15
components/TempDesignSystem/Accordion/variants.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { cva } from "class-variance-authority"
|
||||||
|
|
||||||
|
import styles from "./accordion.module.css"
|
||||||
|
|
||||||
|
export const accordionVariants = cva(styles.accordion, {
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
card: styles.card,
|
||||||
|
faq: styles.faq,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: "card",
|
||||||
|
},
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user