Skip to content

Commit

Permalink
feat: accordion component
Browse files Browse the repository at this point in the history
  • Loading branch information
alexanderl19 committed Nov 9, 2023
1 parent 63d9c03 commit 516477b
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 64 deletions.
3 changes: 2 additions & 1 deletion apps/site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
"dependencies": {
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-navigation-menu": "^1.1.4",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toast": "^1.1.5",
"clsx": "^2.0.0",
"lucide-react": "^0.292.0",
"next": "13.5.6",
"react": "^18",
"react-dom": "^18"
Expand All @@ -30,6 +30,7 @@
"eslint-config-next": "13.5.6",
"postcss": "^8",
"postcss-nesting": "^12.0.1",
"sass": "^1.69.5",
"tailwindcss": "^3",
"typescript": "^5"
}
Expand Down
80 changes: 80 additions & 0 deletions apps/site/src/lib/components/Accordion/Accordion.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
.root {
color: black;
}

.item {
border-bottom: 2px #36352f solid;
}

.trigger {
width: 100%;
padding: 20px 0;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #fff;

font-size: 24px;
font-weight: 700;
line-height: 150%; /* 36px */

.icons {
$icon-size: 24px;

position: relative;
width: $icon-size;
height: $icon-size;

& > * {
position: absolute;
left: 0;
top: 0;
width: $icon-size;
height: $icon-size;
opacity: 0;
}
}

&[data-state="closed"] .plusIcon {
opacity: 1;
}
&[data-state="open"] .minusIcon {
opacity: 1;
}
}

.content {
font-size: 20px;
font-weight: 500;
line-height: 125%;
overflow: hidden;

.contentPadding {
padding-bottom: 24px;
}

@keyframes slideDown {
from {
height: 0;
}
to {
height: var(--radix-accordion-content-height);
}
}

@keyframes slideUp {
from {
height: var(--radix-accordion-content-height);
}
to {
height: 0;
}
}

&[data-state="open"] {
animation: slideDown 300ms cubic-bezier(0.87, 0, 0.13, 1);
}
&[data-state="closed"] {
animation: slideUp 300ms cubic-bezier(0.87, 0, 0.13, 1);
}
}
70 changes: 70 additions & 0 deletions apps/site/src/lib/components/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"use client";

import React from "react";
import * as RadixAccordion from "@radix-ui/react-accordion";
import { Plus, Minus } from "lucide-react";
import clsx from "clsx";

import styles from "./Accordion.module.scss";

export const Root = React.forwardRef<
React.ElementRef<typeof RadixAccordion.Root>,
React.ComponentPropsWithoutRef<typeof RadixAccordion.Root>
>(({ children, className, ...props }, forwardedRef) => (
<RadixAccordion.Root
className={clsx(styles.root, className)}
{...props}
ref={forwardedRef}
>
{children}
</RadixAccordion.Root>
));
Root.displayName = RadixAccordion.Root.displayName;

export const Item = React.forwardRef<
React.ElementRef<typeof RadixAccordion.Item>,
React.ComponentPropsWithoutRef<typeof RadixAccordion.Item>
>(({ children, className, ...props }, forwardedRef) => (
<RadixAccordion.Item
className={clsx(styles.item, className)}
{...props}
ref={forwardedRef}
>
{children}
</RadixAccordion.Item>
));
Item.displayName = RadixAccordion.Item.displayName;

export const Trigger = React.forwardRef<
React.ElementRef<typeof RadixAccordion.Trigger>,
React.ComponentPropsWithoutRef<typeof RadixAccordion.Trigger>
>(({ children, className, ...props }, forwardedRef) => (
<RadixAccordion.Header>
<RadixAccordion.Trigger
className={clsx(styles.trigger, className)}
{...props}
ref={forwardedRef}
>
{children}
<div className={styles.icons}>
<Plus size={24} className={styles.plusIcon} aria-hidden />
<Minus size={24} className={styles.minusIcon} aria-hidden />
</div>
</RadixAccordion.Trigger>
</RadixAccordion.Header>
));
Trigger.displayName = "AccordionTrigger";

export const Content = React.forwardRef<
React.ElementRef<typeof RadixAccordion.Content>,
React.ComponentPropsWithoutRef<typeof RadixAccordion.Content>
>(({ children, className, ...props }, forwardedRef) => (
<RadixAccordion.Content
className={clsx(styles.content, className)}
{...props}
ref={forwardedRef}
>
<div className={styles.contentPadding}>{children}</div>
</RadixAccordion.Content>
));
Content.displayName = RadixAccordion.Content.displayName;
1 change: 1 addition & 0 deletions apps/site/src/lib/components/Accordion/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Root, Item, Trigger, Content } from "./Accordion";
Loading

0 comments on commit 516477b

Please sign in to comment.