Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | import type React from "react";
import { NativeTabs } from "expo-router/unstable-native-tabs";
import { useCSSVariable } from "uniwind";
import type { IconName } from "~components/icons";
import { IconFamily, glyphMapping } from "~components/icons.native";
import type { FileRouteTypes } from "~web/entry/routeTree.gen";
type ShowProps = {
useShow?: () => boolean;
};
export type MenuElement = {
iconName: IconName;
text: string;
pathname: FileRouteTypes["to"];
useBadgeAmount?: () => number;
} & ShowProps;
const useZero = () => 0;
const useTrue = () => true;
type Props = {
elements: (MenuElement & {
ItemWrapper?: React.FC<React.PropsWithChildren>;
PageWrapper?: React.FC<React.PropsWithChildren>;
})[];
};
export const Page: React.FC<Props> = ({ elements }) => {
/* oxlint-disable react-hooks/rules-of-hooks */
// We're pretty sure amount of these elements is stable, but running hooks inside a callback is not an option
// And we can't move tabs outside because NativeTabs don't digest wrapped Triggers
const shows = elements.map(({ useShow = useTrue }) => useShow());
const badgeAmounts = elements.map(({ useBadgeAmount = useZero }) =>
useBadgeAmount(),
);
/* oxlint-enable react-hooks/rules-of-hooks */
const foregroundColor = useCSSVariable(`--heroui-foreground`) as string;
const backgroundColor = useCSSVariable(`--heroui-background`) as string;
const primaryColor = useCSSVariable(`--heroui-primary`) as string;
return (
<NativeTabs
labelStyle={{
default: {
color: foregroundColor,
},
selected: {
color: primaryColor,
},
}}
iconColor={{
default: foregroundColor,
selected: primaryColor,
}}
>
{elements.map(({ text, pathname, iconName }, index) => (
<NativeTabs.Trigger
key={pathname}
name={pathname.slice(1)}
hidden={!shows[index]}
contentStyle={{ backgroundColor }}
>
<NativeTabs.Trigger.Label>{text}</NativeTabs.Trigger.Label>
<NativeTabs.Trigger.Icon
src={
<NativeTabs.Trigger.VectorIcon
family={IconFamily}
name={glyphMapping[iconName]}
/>
}
/>
{badgeAmounts[index] ? (
<NativeTabs.Trigger.Badge>
{badgeAmounts[index].toString()}
</NativeTabs.Trigger.Badge>
) : null}
</NativeTabs.Trigger>
))}
</NativeTabs>
);
};
|