Skip to content

Commit

Permalink
Fix Flyout
Browse files Browse the repository at this point in the history
  • Loading branch information
vineethasok committed Oct 20, 2023
1 parent 42a941e commit c8380c2
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 19 deletions.
6 changes: 3 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ const App = () => {
description="test2"
/>
<Flyout.Body>
hadksjhadksjhaskdjhaksdjhkajsdhkajshdkjashdkjashd
Flyout Text
<Select>
<Select.Item value="test">test</Select.Item>
<Select.Item value="test2">test2</Select.Item>
Expand Down Expand Up @@ -154,7 +154,7 @@ const App = () => {
description="test2"
/>
<Flyout.Body>
hadksjhadksjhaskdjhaksdjhkajsdhkajshdkjashdkjashd
Flyout Text
<Select>
<Select.Item value="test">test</Select.Item>
<Select.Item value="test2">test2</Select.Item>
Expand Down Expand Up @@ -189,7 +189,7 @@ const App = () => {
description="test2"
/>
<Flyout.Body>
hadksjhadksjhaskdjhaksdjhkajsdhkajshdkjashdkjashd
Flyout Text
<Select>
<Select.Item value="test">test</Select.Item>
<Select.Item value="test2">test2</Select.Item>
Expand Down
79 changes: 79 additions & 0 deletions src/components/Flyout/Flyout.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { Button } from "..";
import { Flyout, FlyoutProps } from "./Flyout";

interface Props extends FlyoutProps {
title: string;
description?: string;
showClose?: boolean;
}

const FlyoutExample = ({ title, description, showClose, ...props }: Props) => {
return (
<Flyout {...props}>
<Flyout.Trigger>Flyout Trigger</Flyout.Trigger>
<Flyout.Content strategy="fixed">
<Flyout.Header
title={title}
description={description}
/>
<Flyout.Body>
<Flyout.Element>Content1 long text content</Flyout.Element>
</Flyout.Body>
<Flyout.Footer showClose={showClose}>
<Button>Test Primary</Button>
</Flyout.Footer>
</Flyout.Content>
</Flyout>
);
};
export default {
component: FlyoutExample,
title: "Display/Flyout",
tags: ["form-field", "select", "autodocs"],
argTypes: {
title: { control: "text" },
description: { control: "text" },
showClose: { control: "boolean" },
},
};

export const Playground = {
args: {
title: "Title",
description: "Description",
showClose: true,
},
parameters: {
docs: {
source: {
transform: (_: string, story: { args: Props; [x: string]: unknown }) => {
const { title, description, showClose, ...props } = story.args;
return `<Flyout\n
${Object.entries(props)
.flatMap(([key, value]) =>
typeof value === "boolean"
? value
? ` ${key}`
: []
: ` ${key}=${typeof value == "string" ? `"${value}"` : `{${value}}`}`
)
.join("\n")}
>
<Flyout.Header
title="${title}"
description="${description}"
/>
<Flyout.Body>
<Flyout.Element>Content1 long text content</Flyout.Element>
</Flyout.Body>
<Flyout.Footer showClose={${showClose}}>
<Button>Test Primary</Button>
</Flyout.Footer>
</Flyout>
`;
},
},
},
},
};
69 changes: 69 additions & 0 deletions src/components/Flyout/Flyout.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { fireEvent } from "@testing-library/react";
import { Flyout } from "./Flyout";
import { renderCUI } from "@/utils/test-utils";
import { Button } from "..";
import { DialogProps } from "@radix-ui/react-dialog";

describe("Flyout", () => {
const renderFlyout = (props: DialogProps) => {
return renderCUI(
<Flyout {...props}>
<Flyout.Trigger>
<Button iconLeft="user">Flyout Fixed</Button>
</Flyout.Trigger>
<Flyout.Content strategy="fixed">
<Flyout.Header
title="test1"
description="test2"
/>
<Flyout.Body>Flyout Text</Flyout.Body>
<Flyout.Footer showClose>
<Button type="primary">Primary Button</Button>
</Flyout.Footer>
</Flyout.Content>
</Flyout>
);
};
it("should open flyout on click", () => {
const { queryByText } = renderFlyout({});
const selectTrigger = queryByText("Flyout Fixed");
expect(selectTrigger).not.toBeNull();
expect(queryByText("Flyout Text")).toBeNull();
selectTrigger && fireEvent.click(selectTrigger);

expect(queryByText("Flyout Text")).not.toBeNull();
expect(queryByText("test1")).not.toBeNull();
});

it("should open on updating open param", () => {
const { queryByText } = renderFlyout({
open: true,
});
expect(queryByText("Flyout Text")).not.toBeNull();
});

it("should close flyout on clicking close Button in header", () => {
const { queryByText, getByTestId } = renderFlyout({});
const selectTrigger = queryByText("Flyout Fixed");
expect(selectTrigger).not.toBeNull();
expect(queryByText("Flyout Text")).toBeNull();
selectTrigger && fireEvent.click(selectTrigger);

expect(queryByText("Flyout Text")).not.toBeNull();
expect(queryByText("test1")).not.toBeNull();
fireEvent.click(getByTestId("flyout-header-close-btn"));
expect(queryByText("Flyout Text")).toBeNull();
});

it("should close flyout on clicking close Button in footer", () => {
const { queryByText, getByText } = renderFlyout({});
const selectTrigger = queryByText("Flyout Fixed");
expect(selectTrigger).not.toBeNull();
expect(queryByText("Flyout Text")).toBeNull();
selectTrigger && fireEvent.click(selectTrigger);

expect(queryByText("Flyout Text")).not.toBeNull();
fireEvent.click(getByText("Cancel"));
expect(queryByText("Flyout Text")).toBeNull();
});
});
37 changes: 22 additions & 15 deletions src/components/Flyout/Flyout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import * as Dialog from "@radix-ui/react-dialog";
import { Button, IconButton, Separator } from "..";
import styled from "styled-components";

export const Flyout = (props: Dialog.DialogProps) => {
export type FlyoutProps = Dialog.DialogProps;

export const Flyout = (props: FlyoutProps) => {
return <Dialog.Root {...props} />;
};

Expand All @@ -22,7 +24,7 @@ Flyout.Trigger = Trigger;

type FlyoutSizeType = "narrow" | "wide";
type Strategy = "relative" | "absolute" | "fixed";
interface DialogContentProps extends Dialog.DialogContentProps {
export interface DialogContentProps extends Dialog.DialogContentProps {
container?: HTMLElement | null;
showOverlay?: boolean;
showClose?: boolean;
Expand All @@ -39,13 +41,14 @@ const FlyoutContent = styled(Dialog.Content)<{
flex-direction: column;
align-items: center;
width: 100%;
height: 100%;
overflow: hidden;
flex: 1;
top: 0;
right: 0;
bottom: 0;
${({ theme, $size = "narrow", $strategy }) => `
position: ${$strategy};
height: ${$strategy === "relative" ? "100%" : "auto"};
width: ${theme.click.flyout.size[$size].width};
padding: ${theme.click.flyout.space.y} ${theme.click.flyout.space.x};
gap: ${theme.click.flyout.space.gap};
Expand All @@ -54,11 +57,13 @@ const FlyoutContent = styled(Dialog.Content)<{
box-shadow: -6px 0px 10px 0px ${
theme.click.flyout.shadow.default
}, -5px 0px 20px 0px ${theme.click.flyout.shadow.default};
@media (max-width: 1024px) {
${
$strategy === "relative"
? `
@media (max-width: 1024px) {
position: absolute !important;
position: absolute !important;`
: ""
}
overflow: hidden;
transform: translateX(calc(100% - 50px));
transition: 0.3s ease-in-out;
Expand All @@ -69,9 +74,6 @@ const FlyoutContent = styled(Dialog.Content)<{
left: auto;
}
}
`
: ""
}
`}
`;
const FlyoutContainer = styled.div`
Expand Down Expand Up @@ -131,7 +133,7 @@ Flyout.Element = Element;

interface TitleHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
title: string;
description: string;
description?: string;
children?: never;
}

Expand All @@ -140,7 +142,7 @@ interface ChildrenHeaderProps extends HTMLAttributes<HTMLDivElement> {
description?: never;
}

type HeaderProps = TitleHeaderProps | ChildrenHeaderProps;
export type FlyoutHeaderProps = TitleHeaderProps | ChildrenHeaderProps;

const FlyoutHeaderContainer = styled.div`
display: flex;
Expand All @@ -163,24 +165,29 @@ const FlyoutTitle = styled(Dialog.Title)`
${({ theme }) => `
color: ${theme.click.flyout.color.title.default};
font: ${theme.typography.styles.product.titles.xl};
margin: 0;
padding: 0;
`}
`;

const FlyoutDescription = styled(Dialog.Description)`
${({ theme }) => `
color: ${theme.click.flyout.color.description.default};
font: ${theme.typography.styles.product.text.normal.md};
margin: 0;
padding: 0;
`}
`;

const Header = ({ title, description, children, ...props }: HeaderProps) => {
const Header = ({ title, description, children, ...props }: FlyoutHeaderProps) => {
if (children) {
return (
<FlyoutContainer>
<FlyoutHeaderContainer {...props}>
<FlexGrow>{children}</FlexGrow>
<Dialog.Close asChild>
<IconButton
data-testid="flyout-header-close-btn"
icon="cross"
type="ghost"
size="xs"
Expand All @@ -199,8 +206,9 @@ const Header = ({ title, description, children, ...props }: HeaderProps) => {
<FlyoutTitle>{title}</FlyoutTitle>
{description && <FlyoutDescription>{description}</FlyoutDescription>}
</FlexGrow>
<Dialog.Close>
<Dialog.Close asChild>
<IconButton
data-testid="flyout-header-close-btn"
icon="cross"
type="ghost"
size="xs"
Expand All @@ -227,7 +235,7 @@ const Body = (props: HTMLAttributes<HTMLDivElement>) => <FlyoutBody {...props} /
Body.displayName = "Flyout.Body";
Flyout.Body = Body;

interface FooterProps extends HTMLAttributes<HTMLDivElement> {
export interface FlyoutFooterProps extends HTMLAttributes<HTMLDivElement> {
cancelText?: string;
showClose?: boolean;
}
Expand All @@ -236,15 +244,14 @@ const FlyoutFooter = styled.div`
display: flex;
justify-content: flex-end;
align-items: center;
width: 100%;
${({ theme }) => `
row-gap: ${theme.click.flyout.space.content["row-gap"]};
column-gap: ${theme.click.flyout.space.content["column-gap"]};
padding: 0 ${theme.click.flyout.space.content.x};
`}
`;

const Footer = ({ cancelText, showClose, children, ...props }: FooterProps) => {
const Footer = ({ cancelText, showClose, children, ...props }: FlyoutFooterProps) => {
return (
<FlyoutContainer>
<Separator size="lg" />
Expand Down
2 changes: 1 addition & 1 deletion src/components/Select/MultiSelect.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ ${
Content2
</MultiSelect.Item>
<MultiSelect.Item value="content3">Content3</MultiSelect.Item>
</Select>
</MultiSelect>
`
: ""
}`;
Expand Down
1 change: 1 addition & 0 deletions src/components/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type { ToastProps } from "./Toast/Toast";
export type { SelectOptionListItem } from "./Select/common/types";
export type { MultiSelectProps } from "./Select/MultiSelect";
export type { PanelProps } from "./Panel/Panel";
export type { FlyoutProps, FlyoutFooterProps, FlyoutHeaderProps } from "./Flyout/Flyout";

export type States = "default" | "active" | "disabled" | "error" | "hover";
export type HorizontalDirection = "start" | "end";
Expand Down

0 comments on commit c8380c2

Please sign in to comment.