Skip to content

Commit

Permalink
feat: render AppList with react-virtualized
Browse files Browse the repository at this point in the history
  • Loading branch information
amoshydra committed Feb 18, 2024
1 parent cb28d85 commit 61a384e
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 28 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.1",
"react-router-dom": "^6.22.0",
"react-virtualized": "^9.22.5",
"rehype-highlight": "^7.0.0",
"rehype-sanitize": "^6.0.0",
"rehype-shift-heading": "^2.0.0",
Expand All @@ -37,6 +38,7 @@
"@redux-devtools/extension": "^3.3.0",
"@types/react": "^18.2.55",
"@types/react-dom": "^18.2.19",
"@types/react-virtualized": "^9.21.29",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@vitejs/plugin-react": "^4.2.1",
Expand Down
99 changes: 73 additions & 26 deletions src/components/AppList.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,52 @@
import { css } from "@emotion/react";
import { AppItem } from "../api/banglejs/interface";
import { AppListItem } from "./AppListItem";
import { HTMLAttributes } from "react";
import { CSSProperties, HTMLAttributes, useLayoutEffect, useRef, useState } from "react";
import { Link } from "react-router-dom";
import { ListRowRenderer, List } from 'react-virtualized/dist/es/List';

export interface AppListProps extends HTMLAttributes<HTMLDivElement> {
export interface AppListProps {
isLoading: boolean;
error: Error | null;
data: AppItem[]
data: AppItem[];
className?: string;
style?: CSSProperties;
}

const getDimension = (element: HTMLElement) => {
return {
height: element.parentElement!.clientHeight,
width: element.parentElement!.clientWidth,
}
};

export const AppList = ({ isLoading, error, data: apps, ...props }: AppListProps) => {
const [ dimension, setDimension ] = useState({ width: 0, height: 0 });
const ref = useRef<HTMLDivElement>(null);

useLayoutEffect(() => {
const element = ref.current;
const resizeHandler = () => {
if (element) {
setDimension(getDimension(element))
}
};

const observer = new ResizeObserver(() => {
resizeHandler()
});
resizeHandler();

if (element) observer.observe(element);

return () => {
if (element) {
observer.unobserve(element);
observer.disconnect();
}
}
}, [])


if (isLoading) {
return <MessageWrapper>Fetching store...</MessageWrapper>
Expand All @@ -19,34 +55,45 @@ export const AppList = ({ isLoading, error, data: apps, ...props }: AppListProps
return <MessageWrapper>Error fetching store, please try again later...</MessageWrapper>
}

const RowRenderer: ListRowRenderer = (p) => {
const app = apps[p.index];

return (
<Link
key={p.key}
style={p.style}
to={`/apps/${app.id}`}
css={css`
color: inherit;
&:hover {
color: inherit;
}
`}
>
<AppListItem
key={app.id}
app={app}
/>
</Link>
);
}

return (
<div
{...props}
ref={ref}
css={css`
display: flex;
flex-direction: column;
height: 100%;
`}
>
{
apps!.map(app => {
return (
<Link
to={`/apps/${app.id}`}
css={css`
color: inherit;
&:hover {
color: inherit;
}
`}
>
<AppListItem
key={app.id}
app={app}
/>
</Link>
)
})
}
<List
{...props}
aria-readonly={undefined}
width={dimension.width}
height={dimension.height}
rowCount={apps.length}
rowHeight={126}
rowRenderer={RowRenderer}
/>
</div>
)
};
Expand Down
42 changes: 40 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"

"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.23.2":
"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.23.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.7":
version "7.23.9"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7"
integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==
Expand Down Expand Up @@ -722,6 +722,14 @@
dependencies:
"@types/react" "*"

"@types/react-virtualized@^9.21.29":
version "9.21.29"
resolved "https://registry.yarnpkg.com/@types/react-virtualized/-/react-virtualized-9.21.29.tgz#480b647f43a42f8e414d1af49a0ccd9b16537655"
integrity sha512-+ODVQ+AyKngenj4OPpg43Hz4B9Rdjuz1Naxu9ypNc3Cjo0WVZTYhqXfF/Nm38i8PV/YXECRIl4mTAZK5hq2B+g==
dependencies:
"@types/prop-types" "*"
"@types/react" "*"

"@types/react@*", "@types/react@^18.2.55":
version "18.2.55"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.55.tgz#38141821b7084404b5013742bc4ae08e44da7a67"
Expand Down Expand Up @@ -1000,6 +1008,11 @@ client-only@^0.0.1:
resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==

clsx@^1.0.4:
version "1.2.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==

color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
Expand Down Expand Up @@ -1114,6 +1127,14 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"

dom-helpers@^5.1.3:
version "5.2.1"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
dependencies:
"@babel/runtime" "^7.8.7"
csstype "^3.0.2"

electron-to-chromium@^1.4.648:
version "1.4.665"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.665.tgz#681700bd590b0e5a3be66e3e2874ce62abcf5da5"
Expand Down Expand Up @@ -2371,7 +2392,7 @@ prelude-ls@^1.2.1:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==

prop-types@^15.8.1:
prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
Expand Down Expand Up @@ -2415,6 +2436,11 @@ react-is@^16.13.1, react-is@^16.7.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==

react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==

react-refresh@^0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e"
Expand All @@ -2435,6 +2461,18 @@ react-router@6.22.0:
dependencies:
"@remix-run/router" "1.15.0"

react-virtualized@^9.22.5:
version "9.22.5"
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.5.tgz#bfb96fed519de378b50d8c0064b92994b3b91620"
integrity sha512-YqQMRzlVANBv1L/7r63OHa2b0ZsAaDp1UhVNEdUaXI8A5u6hTpA5NYtUueLH2rFuY/27mTGIBl7ZhqFKzw18YQ==
dependencies:
"@babel/runtime" "^7.7.2"
clsx "^1.0.4"
dom-helpers "^5.1.3"
loose-envify "^1.4.0"
prop-types "^15.7.2"
react-lifecycles-compat "^3.0.4"

react@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
Expand Down

0 comments on commit 61a384e

Please sign in to comment.