Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aizad/FEQ-1566/Added Accordion Component #106

Merged
merged 23 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
89c9050
feat: Accordion component
aizad-deriv Mar 6, 2024
44d4c81
chore: made improvements for Accordion component
aizad-deriv Mar 6, 2024
1c8c5fa
chore: added variants for accordion component
aizad-deriv Mar 6, 2024
f705cf7
chore: added sizing
aizad-deriv Mar 6, 2024
7b7a468
chore: added new props
aizad-deriv Mar 6, 2024
02e516c
chore: added storybook for Accordion component
aizad-deriv Mar 7, 2024
13461ab
chore: change props inside of Accordion title and content
aizad-deriv Mar 7, 2024
1688a12
Merge branch 'main' of github.com:deriv-com/ui into aizad/FEQ-1566/ad…
aizad-deriv Mar 7, 2024
aea0f58
chore: remove redundant styles
aizad-deriv Mar 7, 2024
dfe2e2a
Merge branch 'main' of github.com:deriv-com/ui into aizad/FEQ-1566/ad…
aizad-deriv Mar 7, 2024
0627157
chore: update css values based on latest changes
aizad-deriv Mar 7, 2024
b1cc35a
Merge branch 'main' of github.com:deriv-com/ui into aizad/FEQ-1566/ad…
aizad-deriv Mar 8, 2024
9061554
chore: refactor styles and add changes to storybook
aizad-deriv Mar 8, 2024
f74d5af
chore: update component
aizad-deriv Apr 2, 2024
2c7bfbb
chore: replace existing accordion with new one
aizad-deriv Apr 2, 2024
fea6511
chore: updated storybook
aizad-deriv Apr 2, 2024
3f61c06
chore: fix types in storybook
aizad-deriv Apr 2, 2024
200cd40
Merge branch 'main' of github.com:deriv-com/ui into aizad/FEQ-1566/ad…
aizad-deriv Apr 2, 2024
ffc37b6
chore: updated structure based on latest changes
aizad-deriv Apr 2, 2024
8e0b092
chore: update import statement in storybook
aizad-deriv Apr 2, 2024
8067980
chores: added test cases
aizad-deriv Apr 2, 2024
fd967f9
chore: resolve comments
aizad-deriv Apr 2, 2024
80f8010
Merge branch 'main' into aizad/FEQ-1566/add-accordion
shayan-deriv Apr 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions src/components/Accordion/Accordion.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* Style the accordion section */
$border: 1px solid var(--du-general-active);
$animation-duration: 0.3s;

.deriv-accordion {
position: relative;
display: inline-flex;
flex-direction: column;
min-width: 100%;
background-color: var(--du-general-main-2);
padding: 24px;

&--compact {
padding: 16px;
}

&--underline {
border-bottom: $border;
}

&--shadow,
&--bordered {
border-radius: $border-radius-2;
margin-bottom: 8px;

&:last-child {
margin-bottom: 0;
}
}

&--bordered {
border: $border;
}

&--shadow {
box-shadow: $deriv-box-shadow;
}

&__header {
outline: none;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
color: var(--du-text-general);
cursor: pointer;
}

&__icon {
margin-left: auto;
display: inline-block;
transition: all $animation-duration ease-in-out;

&--active {
transform: rotate(-180deg);
}
}
&__content {
width: 100%;
overflow: auto;
opacity: 0;
background-color: white;
transition: all $animation-duration ease;

&--active {
opacity: 1;
}
}

&__text {
margin-top: 24px;
color: var(--du-text-general);

&--compact {
margin-top: 16px;
}
}
}
.accordion__section {
position: relative;
display: inline-flex;
flex-direction: column;
min-width: 100%;
}
3 changes: 3 additions & 0 deletions src/components/Accordion/Chevron.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions src/components/Accordion/__test__/Accordion.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from "react";
import { render, fireEvent, screen } from "@testing-library/react";
import { Accordion } from "..";

describe("Accordion", () => {
it("renders correctly", () => {
const { getByText } = render(
<Accordion title="Test Title">Test Content</Accordion>,
);

expect(getByText("Test Title")).toBeInTheDocument();
});

it("opens and closes when the header is clicked", () => {
const { getByRole } = render(
<Accordion title="Test Title">Test Content</Accordion>,
);

screen.debug();
const button = getByRole("button");

expect(button).toHaveAttribute("aria-expanded", "false");

fireEvent.click(button);
expect(button).toHaveAttribute("aria-expanded", "true");

fireEvent.click(button);
expect(button).toHaveAttribute("aria-expanded", "false");
});
});
79 changes: 79 additions & 0 deletions src/components/Accordion/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React, { useState, useRef, ReactNode, useEffect } from "react";
import Chevron from "./Chevron.svg";
import clsx from "clsx";
import "./Accordion.scss";

type AccordionVariants = "underline" | "bordered" | "shadow";

type AccordionProps = {
children: ReactNode;
defaultOpen?: boolean;
isCompact?: boolean;
title: string;
variant?: AccordionVariants;
};

const AccordionVariant = {
bordered: "deriv-accordion--bordered",
shadow: "deriv-accordion--shadow",
underline: "deriv-accordion--underline",
} as const;

export const Accordion = ({
defaultOpen = false,
children,
isCompact = false,
title,
variant = "underline",
}: AccordionProps) => {
const [active, setActive] = useState(defaultOpen);
const [setHeight, setHeightState] = useState(defaultOpen ? "auto" : "0px");

const content = useRef<HTMLDivElement | null>(null);

useEffect(() => {
const scrollHeight = content?.current?.scrollHeight;
setHeightState(active ? `${scrollHeight}px` : "0px");
}, [active]);

const toggleAccordion = () => setActive(!active);

return (
<div
className={clsx("deriv-accordion", AccordionVariant[variant], {
"deriv-accordion--compact": isCompact,
})}
>
<button
className={clsx("deriv-accordion__header", {
"deriv-accordion__header--active": active,
})}
onClick={toggleAccordion}
aria-expanded={active}
>
<p>{title}</p>
<img
src={Chevron}
className={clsx("deriv-accordion__icon", {
"deriv-accordion__icon--active": active,
})}
/>
</button>
<div
ref={content}
style={{ maxHeight: setHeight }}
className={clsx("deriv-accordion__content", {
"deriv-accordion__content--active": active,
})}
>
<div
className={clsx("deriv-accordion__text", {
"deriv-accordion__text--compact": isCompact,
})}
>
{children}
</div>
</div>
</div>
);
};
11 changes: 6 additions & 5 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
export { Accordion } from "./components/Accordion";
export { ActionScreen } from "./components/ActionScreen";
export { Button } from "./components/Button";
export {Badge} from "./components/Badge";
export { Badge } from "./components/Badge";
export { Checkbox } from "./components/Checkbox";
export { Divider } from "./components/Divider";
export { Dialog } from "./components/Dialog"
export { Dialog } from "./components/Dialog";
export { Dropdown } from "./components/Dropdown";
export { InlineMessage } from "./components/InlineMessage";
export { Input } from "./components/Input";
export { LinearProgressBar } from './components/LinearProgressBar'
export { LinearProgressBar } from "./components/LinearProgressBar";
export { Loader } from "./components/Loader";
export { Modal } from "./components/Modal";
export { PageLayout } from "./components/PageLayout";
export { PasswordInput } from "./components/PasswordInput";
export { SideNote } from "./components/SideNote";
export { Table } from "./components/Table";
export { Tab, Tabs } from "./components/Tabs";
export { Table } from "./components/Table";
export { Text } from "./components/Text";
export { TextArea } from "./components/TextArea";
export { ToggleSwitch } from "./components/ToggleSwitch";
export { Tooltip } from "./components/Tooltip";
export { useDevice,useOnClickOutside } from "./hooks";
export { useDevice, useOnClickOutside } from "./hooks";
export { VerticalTab, VerticalTabItems } from "./components/VerticalTab";
110 changes: 110 additions & 0 deletions stories/Accordion.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import type { Meta, StoryObj } from "@storybook/react";
import { Accordion } from "../src/main";

const meta = {
title: "Components/Accordion",
component: Accordion,
parameters: {
layout: "centered",
},
tags: ["autodocs"],
args: {
children:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
defaultOpen: false,
isCompact: false,
title: "What is your return policy?",
variant: "underline",
},
argTypes: {
title: { control: { type: "text" } },
defaultOpen: { control: { type: "boolean" } },
variant: {
options: ["underline", "bordered", "shadow"],
control: { type: "select" },
},
},
} satisfies Meta<typeof Accordion>;

const styles = {
width: "800px",
color: "var(--du-text-general)",
};

const props = {
className: "theme--light",
style: styles,
};

export default meta;
type Story = StoryObj<typeof meta>;

export const Underline: Story = {
args: {
variant: "underline",
},
render: (args) => (
<div {...props}>
<Accordion {...args}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</Accordion>
</div>
),
};

export const Bordered: Story = {
args: {
variant: "bordered",
},
render: (args) => (
<div {...props}>
<Accordion {...args}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</Accordion>
</div>
),
};

export const Shadow: Story = {
args: {
variant: "shadow",
},
render: (args) => (
<div {...props}>
<Accordion {...args}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</Accordion>
</div>
),
};

export const Compact: Story = {
args: {
isCompact: true,
},
render: (args) => (
<div {...props}>
<Accordion {...args}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</Accordion>
</div>
),
};

export const DefaultOpen: Story = {
args: {
defaultOpen: true,
},
render: (args) => (
<div {...props}>
<Accordion {...args}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</Accordion>
</div>
),
};