created separate types for each element type in order to handle the different props more sanely

This commit is contained in:
Clément Le Bihan
2023-04-09 23:33:17 +02:00
parent 69fbbd5e00
commit f725a89c0c
2 changed files with 111 additions and 88 deletions

View File

@@ -10,39 +10,56 @@ type DropdownOption = {
value: string;
};
const getElementTypeNode = (
type: ElementType,
text?: string,
options?: DropdownOption[],
onToggle?: (value: boolean) => void,
toggleValue?: boolean,
defaultToggleValue?: boolean,
onSelect?: (value: string) => void
): React.ReactNode => {
switch (type) {
case "text":
return (
<Text
style={{
opacity: 0.6,
}}
>
{text}
</Text>
);
case "toggle":
return (
<Switch
onToggle={onToggle}
isChecked={toggleValue ?? false}
defaultIsChecked={defaultToggleValue}
/>
);
case "dropdown":
return <Text>Dropdown</Text>;
default:
return <Text>Default</Text>;
}
type ElementTextProps = {
text: string;
};
type ElementToggleProps = {
onToggle: (value: boolean) => void;
value: boolean;
defaultValue?: boolean;
};
type ElementDropdownProps = {
options: DropdownOption[];
onSelect: (value: string) => void;
value: string;
defaultValue?: string;
};
const getElementTextNode = ({ text, type }: ElementTextProps) => {
return (
<Text
style={{
opacity: 0.6,
}}
>
{text}
</Text>
);
};
const getElementToggleNode = ({
onToggle,
value,
defaultValue,
}: ElementToggleProps) => {
return (
<Switch
onToggle={onToggle}
isChecked={value ?? false}
defaultIsChecked={defaultValue}
/>
);
};
const getElementDropdownNode = ({
options,
onSelect,
value,
defaultValue,
}: ElementDropdownProps) => {
return <Text>Dropdown</Text>;
};
type ElementProps = {
@@ -54,12 +71,7 @@ type ElementProps = {
onPress?: () => void;
// node is only used if type is "custom"
node?: React.ReactNode;
onToggle?: (value: boolean) => void;
toggleValue?: boolean;
defaultToggleValue?: boolean;
text?: string;
options?: DropdownOption[];
onSelect?: (value: string) => void;
data?: ElementTextProps | ElementToggleProps | ElementDropdownProps;
};
const Element = ({
@@ -70,12 +82,7 @@ const Element = ({
disabled,
onPress,
node,
onToggle,
toggleValue,
defaultToggleValue,
text,
options,
onSelect,
data,
}: ElementProps) => {
return (
<Row
@@ -92,17 +99,20 @@ const Element = ({
<Text>{title}</Text>
</Box>
<Box>
{type === "custom"
? node
: getElementTypeNode(
type ?? "default",
text,
options,
onToggle,
toggleValue,
defaultToggleValue,
onSelect
)}
{(() => {
switch (type) {
case "text":
return getElementTextNode(data as ElementTextProps);
case "toggle":
return getElementToggleNode(data as ElementToggleProps);
case "dropdown":
return getElementDropdownNode(data as ElementDropdownProps);
case "custom":
return node;
default:
return <Text>Unknown type</Text>;
}
})()}
</Box>
</Row>
);

View File

@@ -59,19 +59,15 @@ const ProfileSettings = ({ navigation }: { navigation: any }) => {
paddingTop: 40,
}}
>
<Column style={{
width: "100%",
alignItems: "center",
}}>
<Column
style={{
width: "100%",
alignItems: "center",
}}
>
<Center>
<Avatar size="2xl" source={{ uri: user.data.avatar }}>
{getInitials(user.name)}
<Avatar.Badge bg="gray.300" size={35}>
<IconButton
size={"sm"}
icon={<Icon as={FontAwesome5} name="edit" />}
/>
</Avatar.Badge>
</Avatar>
</Center>
<ElementList
@@ -84,57 +80,74 @@ const ProfileSettings = ({ navigation }: { navigation: any }) => {
{
type: "text",
title: "Username",
text: user.name,
data: {
text: user.name,
},
},
{
type: "text",
title: "Email",
text: user.email,
data: {
text: user.email,
},
},
{
type: "text",
title: "ID",
text: user.id,
data: {
text: user.id,
},
},
{
type: "text",
title: "Party played",
text: user.data.partyPlayed,
data: {
text: user.data.partyPlayed,
},
},
{
type: "text",
title: "XP",
text: user.data.xp,
data: {
text: user.data.xp,
},
},
{
type: "text",
title: "Date de création",
text: user.data.createdAt,
data: {
text: user.data.createdAt,
},
},
{
type: "toggle",
title: "Notifications",
onToggle: (value) => {
console.log(value);
setToggle(value);
data: {
value: toggle,
onToggle: () => {
console.log("toggle", toggle);
setToggle(!toggle);
},
},
toggleValue: toggle,
},
{
type: "dropdown",
title: "Langue",
options: [
{
label: "Français",
value: "fr",
},
{
label: "English",
value: "en",
},
],
onSelect: (value) => console.log(value),
}
data: {
value: "fr",
options: [
{
label: "Français",
value: "fr",
},
{
label: "English",
value: "en",
},
],
onSelect: (value) => console.log(value),
},
},
]}
/>
</Column>