Skip to content

Commit ed160a8

Browse files
committed
feat: add FaqAccordion
1 parent b68b738 commit ed160a8

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { Meta, StoryObj } from "@storybook/react"
2+
3+
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "."
4+
5+
const meta = {
6+
title: "FaqAccordion",
7+
component: Accordion,
8+
decorators: [
9+
(Story) => (
10+
<div className="">
11+
<Story />
12+
</div>
13+
),
14+
],
15+
} satisfies Meta<typeof Accordion>
16+
17+
export default meta
18+
19+
export const FaqAccordion: StoryObj = {
20+
render: () => (
21+
<Accordion type="single" collapsible>
22+
<AccordionItem value="item-1">
23+
<AccordionTrigger>
24+
<h2 className="text-start text-base md:text-xl">
25+
Why is there no &apos;official&apos; Ethereum L2?
26+
</h2>
27+
</AccordionTrigger>
28+
29+
<AccordionContent>
30+
Just as there is no &apos;official&apos; Ethereum client, there is no
31+
&apos;official&apos; Ethereum layer 2. Ethereum is permissionless -
32+
technically anyone can create a layer 2! Multiple teams will implement
33+
their version of a layer 2, and the ecosystem as a whole will benefit
34+
from a diversity of design approaches that are optimized for different
35+
use cases. Much like we have multiple Ethereum clients developed by
36+
multiple teams in order to have diversity in the network, this too
37+
will be how layer 2s develop in the future.
38+
</AccordionContent>
39+
</AccordionItem>
40+
<AccordionItem value="item-2">
41+
<AccordionTrigger>
42+
<h2 className="text-start text-base md:text-xl">
43+
Why is there no &apos;official&apos; Ethereum L2?
44+
</h2>
45+
</AccordionTrigger>
46+
<AccordionContent>
47+
Just as there is no &apos;official&apos; Ethereum client, there is no
48+
&apos;official&apos; Ethereum layer 2. Ethereum is permissionless -
49+
technically anyone can create a layer 2! Multiple teams will implement
50+
their version of a layer 2, and the ecosystem as a whole will benefit
51+
from a diversity of design approaches that are optimized for different
52+
use cases. Much like we have multiple Ethereum clients developed by
53+
multiple teams in order to have diversity in the network, this too
54+
will be how layer 2s develop in the future.
55+
</AccordionContent>
56+
</AccordionItem>
57+
</Accordion>
58+
),
59+
}

src/components/FaqAccordian/index.tsx

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import React from "react"
2+
import { MdChevronRight } from "react-icons/md"
3+
import * as AccordionPrimitive from "@radix-ui/react-accordion"
4+
5+
import { cn } from "@/lib/utils/cn"
6+
7+
import * as RootAccordion from "../../../tailwind/ui/accordion"
8+
9+
const AccordionTrigger = React.forwardRef<
10+
React.ElementRef<typeof AccordionPrimitive.Trigger>,
11+
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
12+
>(({ className, children, ...props }, ref) => (
13+
// p-4 hover:bg-background-highlight
14+
<AccordionPrimitive.Header className="flex w-full">
15+
<AccordionPrimitive.Trigger
16+
ref={ref}
17+
className={cn(
18+
"px-4 py-3 md:px-8 md:py-6",
19+
"flex flex-1 items-center justify-between gap-2",
20+
"border-t border-body-light",
21+
"focus-visible:outline-1 focus-visible:-outline-offset-1 focus-visible:outline-primary-hover",
22+
"group cursor-pointer text-start font-medium",
23+
"transition-all [&[data-state=open]>svg]:-rotate-90",
24+
className
25+
)}
26+
{...props}
27+
>
28+
{children}
29+
30+
<MdChevronRight
31+
className={cn(
32+
"size-[1em] shrink-0 p-1 text-2xl md:size-[1.25em]",
33+
"rounded-full border",
34+
"group-hover:border-primary group-hover:text-primary group-hover:shadow-md group-hover:shadow-primary-low-contrast",
35+
"transition-transform duration-200"
36+
)}
37+
/>
38+
</AccordionPrimitive.Trigger>
39+
</AccordionPrimitive.Header>
40+
))
41+
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
42+
43+
// TODO: Prop types
44+
const Accordion = ({ children, ...props }) => {
45+
return (
46+
<RootAccordion.Accordion
47+
type="single"
48+
collapsible
49+
className={cn(
50+
"rounded border border-body-light first:border-t-0",
51+
"overflow-hidden bg-background",
52+
props?.className
53+
)}
54+
{...props}
55+
>
56+
{children}
57+
</RootAccordion.Accordion>
58+
)
59+
}
60+
const AccordionItem = React.forwardRef<
61+
React.ElementRef<typeof AccordionPrimitive.Item>,
62+
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
63+
>(({ className, ...props }, ref) => (
64+
<AccordionPrimitive.Item
65+
ref={ref}
66+
className={cn("hover:bg-background-highlight", className)}
67+
{...props}
68+
/>
69+
))
70+
AccordionItem.displayName = "AccordionItem"
71+
72+
const AccordionContent = React.forwardRef<
73+
React.ElementRef<typeof AccordionPrimitive.Content>,
74+
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
75+
>(({ className, children, ...props }, ref) => (
76+
<AccordionPrimitive.Content
77+
ref={ref}
78+
className={cn(
79+
"overflow-hidden px-4 text-sm md:px-8",
80+
"transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
81+
)}
82+
{...props}
83+
>
84+
<div className={cn("border-t border-body-light py-3 md:py-6", className)}>
85+
{children}
86+
</div>
87+
</AccordionPrimitive.Content>
88+
))
89+
90+
AccordionContent.displayName = AccordionPrimitive.Content.displayName
91+
92+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger }

0 commit comments

Comments
 (0)