Skip to content

Commit

Permalink
perf: refactor Panel to lazy load heavy imports (#535)
Browse files Browse the repository at this point in the history
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new nested `Panel` component within the `CustomCard` for
enhanced profile interaction.
- Enhanced user interaction with updated `MenuItem` behavior in the
`CustomCard`.
  
- **Refactor**
- Implemented lazy loading for modal components in the `Panel` to
optimize performance and loading times.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
aversini authored Apr 26, 2024
1 parent 7af6083 commit 840113b
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 71 deletions.
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

0 comments on commit 840113b

Please sign in to comment.