Skip to content

Commit

Permalink
Init
Browse files Browse the repository at this point in the history
  • Loading branch information
czystyl committed Sep 28, 2021
1 parent 48a5e92 commit 4e571d3
Show file tree
Hide file tree
Showing 5 changed files with 6,139 additions and 10 deletions.
38 changes: 28 additions & 10 deletions App.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import React, { useState } from "react";
import { SafeAreaView, ScrollView, StyleSheet, View, Text } from "react-native";
import List from "./src/List";
import Button from "./src/Button";
import { dataStructure } from "./src/treeData";

export default function App() {
const [selected, setSelected] = useState<number | null>(null);

return (
<View style={styles.container}>
<Text>Open up App.tsx to start working on your app!</Text>
<StatusBar style="auto" />
</View>
<SafeAreaView style={styles.container}>
<ScrollView>
<List<{ id: number; name: string }>
treeData={dataStructure}
selectedItemId={selected}
buttonComponent={(itemData) => {
const isSelected = itemData.id === selected;

return (
<Button
onPress={() => {
setSelected(isSelected ? null : itemData.id);
}}
isSelected={isSelected}
title={`${itemData?.name} + ${itemData.children?.length ?? 0}`}
/>
);
}}
/>
</ScrollView>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
34 changes: 34 additions & 0 deletions src/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from "react";
import { StyleSheet, Text, TouchableHighlight, View } from "react-native";

type ButtonProps = {
onPress: () => void;
isSelected: boolean;
title: string;
};

export default function Button(props: ButtonProps) {
return (
<TouchableHighlight onPress={props.onPress}>
<View
style={{
backgroundColor: props.isSelected ? "slateblue" : "red",
flexDirection: "column",
margin: 5,
padding: 15,
}}
>
<Text>{props.title}</Text>
</View>
</TouchableHighlight>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
90 changes: 90 additions & 0 deletions src/List.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, { useState } from "react";
import { SafeAreaView, Text, View } from "react-native";

import { dataStructure, DataStructure } from "./treeData";

type ListProps<T extends DataStructure> = {
level?: number;
selectedItemId: T["id"] | null | undefined;
buttonComponent: (data: DataStructure, level: number) => React.ReactNode;
treeData: T[];
};

export default function List<T extends DataStructure>(props: ListProps<T>) {
const [itemMeasure, setItemMeasure] = useState<{
[key: number]: { height: number; y: number };
}>({});
const [height, setHeight] = useState(0);

const level = props.level ?? 0;

return (
<SafeAreaView style={{ flex: 1 }}>
<View style={{ flexDirection: "row", flexWrap: "wrap" }}>
{props.treeData.map((item, index) => {
const isSelected = props.selectedItemId === item.id;

return (
<React.Fragment key={`${level}-${item.id}`}>
<View
style={isSelected ? { marginBottom: height } : undefined}
onLayout={(event) => {
const { x, y, height, width } = event.nativeEvent.layout;

setItemMeasure((prev) => ({
...prev,
[item.id]: { x, y, height, width },
}));
}}
>
{props.buttonComponent(item, level)}
</View>

{isSelected ? (
<View
onLayout={(event) => {
setHeight(event.nativeEvent.layout.height);
}}
style={{
zIndex: level,
width: "100%",
position: "absolute",
top:
// height is for button andd Y is the movement
(itemMeasure[item.id]?.height ?? 0) +
(itemMeasure[item.id]?.y ?? 0),
}}
>
<View style={{ backgroundColor: getRandomColor(level) }}>
<Text style={{ fontSize: 25, color: "white" }}>
Level: {level}-{item.name}={item.children?.length ?? 0}
childrens
</Text>

{item.children ? (
<Text style={{ fontSize: 15, color: "white" }}>
Render children
</Text>
) : null}
</View>
</View>
) : null}
</React.Fragment>
);
})}
</View>
</SafeAreaView>
);
}

function getRandomColor(level: number) {
return (
"rgb(" +
Math.floor((level / 100) * 256) +
"," +
Math.floor((level / 10) * 256) +
"," +
Math.floor((level / 10) * 256) +
")"
);
}
56 changes: 56 additions & 0 deletions src/treeData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
export type DataStructure = {
id: number;
name: string;
children?: DataStructure[];
};

export const dataStructure: DataStructure[] = [
{
id: 1,
name: "Parent1",
children: [
{ id: 11, name: "child1" },
{ id: 12, name: "child2" },
{ id: 13, name: "child3" },
{ id: 14, name: "child4" },
],
},
{
id: 2,
name: "Parent2",
children: [
{ id: 21, name: "child1" },
{ id: 22, name: "child2" },
{ id: 23, name: "child3" },
{ id: 24, name: "child4" },
],
},
{
id: 3,
name: "Parent3",
children: [
{ id: 31, name: "child1" },
{ id: 32, name: "child2" },
{ id: 33, name: "child3" },
{ id: 34, name: "child4" },
],
},
{
id: 4,
name: "Parent4",
},
{
id: 5,
name: "Parent5",
},
{
id: 6,
name: "Parent6",
children: [
{ id: 61, name: "child1" },
{ id: 62, name: "child2" },
{ id: 63, name: "child3" },
{ id: 64, name: "child4" },
],
},
];
Loading

0 comments on commit 4e571d3

Please sign in to comment.