feat: fragment route component into smaller components

This improves rendering performance especially during selection mode toggling.
This commit is contained in:
thecodrr
2020-04-21 11:36:09 +05:00
parent 0040fd5650
commit 5aca5adb0b

View File

@@ -6,96 +6,12 @@ import { useStore } from "../stores/app-store";
import { useStore as useSelectionStore } from "../stores/selection-store";
function Route(props) {
const toggleSideMenu = useStore((store) => store.toggleSideMenu);
const isSelectionMode = useSelectionStore((store) => store.isSelectionMode);
const toggleSelectionMode = useSelectionStore(
(store) => store.toggleSelectionMode
);
const selectAll = useSelectionStore((store) => store.selectAll);
const shouldSelectAll = useSelectionStore((store) => store.shouldSelectAll);
const navigator = props.params.navigator || props.navigator;
return (
<ThemeProvider>
<Flex flexDirection="column" px={2}>
{(props.route.title || props.route.params.title) && (
<>
<Flex alignItems="center" justifyContent="space-between">
<Flex alignItems="center" py={2}>
{props.canGoBack && (
<Box
onClick={props.backAction}
ml={-2}
height={38}
width={38}
>
<Icon.ChevronLeft size={38} color="fontPrimary" />
</Box>
)}
<Box
onClick={toggleSideMenu}
height={38}
ml={-5}
sx={{
display: ["block", "none", "none"],
}}
>
<Icon.Menu size={38} />
</Box>
<Heading
fontSize="heading"
color={props.route.titleColor || "text"}
>
{props.route.title || props.route.params.title}
</Heading>
</Flex>
{props.route.options && isSelectionMode && (
<Flex>
{props.route.options.map((option) => (
<Box
key={option.key}
onClick={option.onClick}
mx={2}
sx={{ cursor: "pointer" }}
>
<option.icon />
</Box>
))}
</Flex>
)}
</Flex>
{props.route.params.subtitle && (
<Text
variant="title"
color="primary"
sx={{
marginBottom: 2,
cursor: isSelectionMode ? "pointer" : "normal",
}}
>
{props.route.params.subtitle}
</Text>
)}
{isSelectionMode && (
<Flex
alignItems="center"
mb={2}
sx={{ cursor: "pointer" }}
onClick={() => {
if (shouldSelectAll) {
toggleSelectionMode(false);
} else {
selectAll();
}
}}
>
{shouldSelectAll ? <Icon.Check /> : <Icon.CircleEmpty />}
<Text ml={1} variant="title" color="primary">
{shouldSelectAll ? "Unselect" : "Select all"}
</Text>
</Flex>
)}
</>
)}
<Header {...props} />
</Flex>
{props.route.component && (
<props.route.component navigator={navigator} {...props.params} />
@@ -104,3 +20,104 @@ function Route(props) {
);
}
export default Route;
function Header(props) {
const { route, canGoBack, backAction } = props;
const { title, titleColor, params, options } = route;
const toggleSideMenu = useStore((store) => store.toggleSideMenu);
if (!title && !params.title) return null;
return (
<>
<Flex alignItems="center" justifyContent="space-between">
<Flex alignItems="center" py={2}>
{canGoBack && (
<Box onClick={backAction} ml={-2} height={38} width={38}>
<Icon.ChevronLeft size={38} color="fontPrimary" />
</Box>
)}
<Box
onClick={toggleSideMenu}
height={38}
ml={-5}
sx={{
display: ["block", "none", "none"],
}}
>
<Icon.Menu size={38} />
</Box>
<Heading fontSize="heading" color={titleColor || "text"}>
{title || params.title}
</Heading>
</Flex>
<SelectionOptions options={options} />
</Flex>
{params.subtitle && (
<Text
variant="title"
color="primary"
sx={{
marginBottom: 2,
cursor: "normal",
}}
>
{params.subtitle}
</Text>
)}
<SelectionBox />
</>
);
}
function SelectionOptions(props) {
const { options } = props;
const isSelectionMode = useSelectionStore((store) => store.isSelectionMode);
if (!isSelectionMode || !options) return null;
return (
<Flex>
{options.map((option) => (
<Box
key={option.key}
onClick={option.onClick}
mx={2}
sx={{ cursor: "pointer" }}
>
<option.icon />
</Box>
))}
</Flex>
);
}
function SelectionBox() {
const toggleSelectionMode = useSelectionStore(
(store) => store.toggleSelectionMode
);
const selectAll = useSelectionStore((store) => store.selectAll);
const shouldSelectAll = useSelectionStore((store) => store.shouldSelectAll);
const isSelectionMode = useSelectionStore((store) => store.isSelectionMode);
if (!isSelectionMode) return null;
return (
<Flex
alignItems="center"
mb={2}
sx={{ cursor: "pointer" }}
onClick={() => {
if (shouldSelectAll) {
toggleSelectionMode(false);
} else {
selectAll();
}
}}
>
{shouldSelectAll ? <Icon.Check /> : <Icon.CircleEmpty />}
<Text ml={1} variant="title" color="primary">
{shouldSelectAll ? "Unselect all" : "Select all"}
</Text>
</Flex>
);
}