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

perf: refactor Panel to lazy load heavy imports #535

Merged
merged 3 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
56 changes: 36 additions & 20 deletions examples/with-vite/src/components/CustomCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Card, Menu, MenuItem } from "@versini/ui-components";
import { Card, Menu, MenuItem, Panel } from "@versini/ui-components";
import {
IconChart,
IconHistory,
Expand All @@ -7,28 +7,44 @@ import {
IconSettings,
} from "@versini/ui-icons";
import { Flexgrid, FlexgridItem } from "@versini/ui-system";
import { useState } from "react";
import { CommonTemplate } from "./CommonTemplate";

export const CustomCard = () => {
const [open, setOpen] = useState(false);
const onOpenChange = () => {
setOpen(!open);
};
return (
<Card
header={
<Flexgrid alignHorizontal="space-between">
<FlexgridItem>
<h2 className="m-0 mb-1">Kitchen Sink</h2>
</FlexgridItem>
<FlexgridItem>
<Menu icon={<IconSettings />}>
<MenuItem label="Profile" icon={<IconProfile />} />
<MenuItem label="Statistics" icon={<IconChart />} />
<MenuItem label="History" icon={<IconHistory />} />
<MenuItem label="About" icon={<IconInfo />} />
</Menu>
</FlexgridItem>
</Flexgrid>
}
>
<CommonTemplate />
</Card>
<>
<Panel title="Profile" open={open} onOpenChange={onOpenChange}>
Hello Profile
</Panel>
<Card
header={
<Flexgrid alignHorizontal="space-between">
<FlexgridItem>
<h2 className="m-0 mb-1">Kitchen Sink</h2>
</FlexgridItem>
<FlexgridItem>
<Menu icon={<IconSettings />}>
<MenuItem
label="Profile"
icon={<IconProfile />}
onClick={() => {
setOpen(true);
}}
/>
<MenuItem label="Statistics" icon={<IconChart />} />
<MenuItem label="History" icon={<IconHistory />} />
<MenuItem label="About" icon={<IconInfo />} />
</Menu>
</FlexgridItem>
</Flexgrid>
}
>
<CommonTemplate />
</Card>
</>
);
};
56 changes: 36 additions & 20 deletions examples/with-webpack/src/components/CustomCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Card, Menu, MenuItem } from "@versini/ui-components";
import { Card, Menu, MenuItem, Panel } from "@versini/ui-components";
import {
IconChart,
IconHistory,
Expand All @@ -7,28 +7,44 @@ import {
IconSettings,
} from "@versini/ui-icons";
import { Flexgrid, FlexgridItem } from "@versini/ui-system";
import { useState } from "react";
import { CommonTemplate } from "./CommonTemplate";

export const CustomCard = () => {
const [open, setOpen] = useState(false);
const onOpenChange = () => {
setOpen(!open);
};
return (
<Card
header={
<Flexgrid alignHorizontal="space-between">
<FlexgridItem>
<h2 className="m-0 mb-1">Kitchen Sink</h2>
</FlexgridItem>
<FlexgridItem>
<Menu icon={<IconSettings />}>
<MenuItem label="Profile" icon={<IconProfile />} />
<MenuItem label="Statistics" icon={<IconChart />} />
<MenuItem label="History" icon={<IconHistory />} />
<MenuItem label="About" icon={<IconInfo />} />
</Menu>
</FlexgridItem>
</Flexgrid>
}
>
<CommonTemplate />
</Card>
<>
<Panel title="Profile" open={open} onOpenChange={onOpenChange}>
Hello Profile
</Panel>
<Card
header={
<Flexgrid alignHorizontal="space-between">
<FlexgridItem>
<h2 className="m-0 mb-1">Kitchen Sink</h2>
</FlexgridItem>
<FlexgridItem>
<Menu icon={<IconSettings />}>
<MenuItem
label="Profile"
icon={<IconProfile />}
onClick={() => {
setOpen(true);
}}
/>
<MenuItem label="Statistics" icon={<IconChart />} />
<MenuItem label="History" icon={<IconHistory />} />
<MenuItem label="About" icon={<IconInfo />} />
</Menu>
</FlexgridItem>
</Flexgrid>
}
>
<CommonTemplate />
</Card>
</>
);
};
73 changes: 46 additions & 27 deletions packages/ui-components/src/components/Panel/Panel.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import { IconClose } from "@versini/ui-icons";
import {
Modal,
ModalClose,
ModalContent,
ModalDescription,
ModalHeading,
} from "@versini/ui-private";
import { useEffect, useRef } from "react";

import { Suspense, lazy, useEffect, useRef } from "react";

import { ButtonIcon } from "../";
import type { PanelProps } from "./PanelTypes";
import { TYPE_PANEL, getPanelClassName } from "./utilities";

const lazyLoad = (componentName: string) => {
return lazy(() =>
import("@versini/ui-private").then((module) => ({
default: module[componentName] as React.ComponentType<any>,
})),
);
};

const Modal = lazyLoad("Modal");
const ModalClose = lazyLoad("ModalClose");
const ModalContent = lazyLoad("ModalContent");
const ModalDescription = lazyLoad("ModalDescription");
const ModalHeading = lazyLoad("ModalHeading");

export const Panel = ({
open,
onOpenChange,
Expand Down Expand Up @@ -42,26 +50,37 @@ export const Panel = ({
}, [title, open]);

return (
<Modal open={open} onOpenChange={onOpenChange}>
<ModalContent className={panelClassName.main}>
<div className="flex flex-row-reverse items-center justify-between">
<ModalClose
className={panelClassName.close}
trigger={
<ButtonIcon mode="dark" focusMode="light" noBorder label="Close">
<IconClose />
</ButtonIcon>
}
/>
<ModalHeading className={panelClassName.header}>{title}</ModalHeading>
</div>
<Suspense fallback={<div />}>
{open && (
<Modal open={open} onOpenChange={onOpenChange}>
<ModalContent className={panelClassName.main}>
<div className="flex flex-row-reverse items-center justify-between">
<ModalClose
className={panelClassName.close}
trigger={
<ButtonIcon
mode="dark"
focusMode="light"
noBorder
label="Close"
>
<IconClose />
</ButtonIcon>
}
/>
<ModalHeading className={panelClassName.header}>
{title}
</ModalHeading>
</div>

<ModalDescription className={panelClassName.content}>
{children}
</ModalDescription>
<ModalDescription className={panelClassName.content}>
{children}
</ModalDescription>

{footer && <div className={panelClassName.footer}>{footer}</div>}
</ModalContent>
</Modal>
{footer && <div className={panelClassName.footer}>{footer}</div>}
</ModalContent>
</Modal>
)}
</Suspense>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe("Panel (exceptions)", () => {
describe("Panel modifiers", () => {
it("should render a responsive panel", async () => {
render(<SimplePanel />);
const panel = screen.getByRole("dialog");
const panel = await screen.findByRole("dialog");

expectToHaveClasses(panel, [
PANEL_CLASSNAME,
Expand All @@ -46,7 +46,7 @@ describe("Panel modifiers", () => {

it("should render a responsive panel with dark borders", async () => {
render(<SimplePanel borderMode="dark" />);
const panel = screen.getByRole("dialog");
const panel = await screen.findByRole("dialog");

expectToHaveClasses(panel, [
PANEL_CLASSNAME,
Expand All @@ -68,7 +68,7 @@ describe("Panel modifiers", () => {

it("should render a responsive messagebox", async () => {
render(<SimplePanel kind="messagebox" />);
const panel = screen.getByRole("dialog");
const panel = await screen.findByRole("dialog");

expectToHaveClasses(panel, [
MESSAGEBOX_CLASSNAME,
Expand All @@ -88,7 +88,7 @@ describe("Panel modifiers", () => {

it("should render a responsive messagebox with dark borders", async () => {
render(<SimplePanel kind="messagebox" borderMode="dark" />);
const panel = screen.getByRole("dialog");
const panel = await screen.findByRole("dialog");

expectToHaveClasses(panel, [
MESSAGEBOX_CLASSNAME,
Expand Down
Loading