Skip to content

Commit

Permalink
feat: add ModuleNavigation component
Browse files Browse the repository at this point in the history
  • Loading branch information
mastro993 committed Apr 30, 2024
1 parent 3cd3947 commit 99d065e
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 0 deletions.
44 changes: 44 additions & 0 deletions example/src/pages/Modules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ModuleCheckout,
ModuleCredential,
ModuleIDP,
ModuleNavigation,
ModulePaymentNotice,
useIOExperimentalDesign,
useIOTheme
Expand Down Expand Up @@ -256,6 +257,41 @@ const renderModuleCredential = () => (
</>
);

const renderModuleNavigation = () => (
<>
<ComponentViewerBox name="ModuleNavigation">
<View>
<ModuleNavigation
icon="spid"
title="SPID"
subtitle="Usa credenziali e app (o SMS)"
onPress={mockFn}
/>
</View>
</ComponentViewerBox>
<ComponentViewerBox name="ModuleNavigation, with Badge">
<View>
<ModuleNavigation
icon="spid"
title="SPID"
subtitle="Usa credenziali e app (o SMS)"
onPress={mockFn}
badge={{
text: "IN arrivo",
variant: "blue",
outline: true
}}
/>
</View>
</ComponentViewerBox>
<ComponentViewerBox name="ModuleNavigation, loading">
<View>
<ModuleNavigation isLoading={true} />
</View>
</ComponentViewerBox>
</>
);

const Modules = () => {
const { isExperimental, setExperimental } = useIOExperimentalDesign();
const theme = useIOTheme();
Expand Down Expand Up @@ -306,6 +342,14 @@ const Modules = () => {
ModuleCredential
</H2>
{renderModuleCredential()}
<H2
color={theme["textHeading-default"]}
weight={"SemiBold"}
style={{ marginBottom: 16, marginTop: 16 }}
>
ModuleNavigation
</H2>
{renderModuleNavigation()}
</Screen>
);
};
Expand Down
116 changes: 116 additions & 0 deletions src/components/modules/ModuleNavigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import React from "react";
import {
Image,
ImageSourcePropType,
ImageURISource,
StyleSheet,
View
} from "react-native";
import Placeholder from "rn-placeholder";
import {
IOListItemVisualParams,
IOModuleStyles,
IOSelectionListItemVisualParams,
IOStyles,
useIOTheme
} from "../../core";
import { WithTestID } from "../../utils/types";
import { Badge } from "../badge";
import { IOIcons, Icon } from "../icons";
import { VSpacer } from "../spacer";
import { Chip, LabelSmallAlt } from "../typography";
import {
PressableModuleBase,
PressableModuleBaseProps
} from "./PressableModuleBase";

type LoadingProps = {
isLoading: true;
};

type ImageProps =
| { icon: IOIcons; image?: never }
| { icon?: never; image: ImageURISource | ImageSourcePropType };

type BaseProps = {
isLoading?: false;
title: string;
subtitle?: string;
badge?: Badge;
} & ImageProps &
PressableModuleBaseProps;

type ModuleNavigationProps = LoadingProps | BaseProps;

export const ModuleNavigation = (props: WithTestID<ModuleNavigationProps>) => {
const theme = useIOTheme();

if (props.isLoading) {
return <ModuleNavigationSkeleton />;
}

const { icon, image, title, subtitle, onPress, badge, ...pressableProps } =
props;

const iconComponent = (
<>
{icon && <Icon name={icon} size={24} color="grey-300" />}
{image && (
<Image
source={image}
style={styles.image}
accessibilityIgnoresInvertColors={true}
/>
)}
</>
);

return (
<PressableModuleBase {...pressableProps} onPress={onPress}>
<View>{iconComponent}</View>
<View style={{ flexGrow: 1, flexShrink: 1, paddingHorizontal: 8 }}>
<LabelSmallAlt
color="blueIO-500"
numberOfLines={2}
lineBreakMode="middle"
>
{title}
</LabelSmallAlt>
{subtitle && <Chip color="grey-700">{subtitle}</Chip>}
</View>
<View>
{badge ? (
<Badge {...badge} />
) : onPress ? (
<Icon
name="chevronRightListItem"
color={theme["interactiveElem-default"]}
size={IOListItemVisualParams.chevronSize}
/>
) : null}
</View>
</PressableModuleBase>
);
};

const ModuleNavigationSkeleton = () => (
<View style={IOModuleStyles.button}>
<View style={[IOStyles.row, IOStyles.alignCenter]}>
<Placeholder.Box animate="fade" width={24} height={24} radius={8} />
<View style={{ paddingHorizontal: 8 }}>
<Placeholder.Box animate="fade" width={96} height={19} radius={8} />
<VSpacer size={4} />
<Placeholder.Box animate="fade" width={180} height={16} radius={8} />
</View>
</View>
<Placeholder.Box animate="fade" width={64} height={22} radius={8} />
</View>
);

const styles = StyleSheet.create({
image: {
width: IOSelectionListItemVisualParams.iconSize,
height: IOSelectionListItemVisualParams.iconSize,
resizeMode: "contain"
}
});
1 change: 1 addition & 0 deletions src/components/modules/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export * from "./ModuleAttachment";
export * from "./ModuleCheckout";
export * from "./ModuleCredential";
export * from "./ModuleIDP";
export * from "./ModuleNavigation";
export * from "./ModulePaymentNotice";
export * from "./PressableModuleBase";

0 comments on commit 99d065e

Please sign in to comment.