Skip to content

Commit

Permalink
feat: a bit more appealing drum machine example
Browse files Browse the repository at this point in the history
  • Loading branch information
michalsek committed Oct 27, 2024
1 parent edd3cd8 commit 3615673
Show file tree
Hide file tree
Showing 39 changed files with 1,904 additions and 251 deletions.
2 changes: 2 additions & 0 deletions apps/common-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"@react-navigation/native": "*",
"@react-navigation/native-stack": "*",
"@react-navigation/stack": "*",
"@shopify/react-native-skia": "*",
"@swmansion/icons": "*",
"react": "*",
"react-dom": "*",
"react-native": "*",
Expand Down
7 changes: 6 additions & 1 deletion apps/common-app/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import type { FC } from 'react';
import Animated from 'react-native-reanimated';
import { createStackNavigator } from '@react-navigation/stack';
import { FlatList, StyleSheet, Text, Pressable } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
Expand All @@ -11,6 +12,8 @@ import { layout, colors } from './styles';

const Stack = createStackNavigator();

Animated.addWhitelistedNativeProps({ text: true });

const HomeScreen: FC = () => {
const navigation = useNavigation<MainStackProps>();

Expand Down Expand Up @@ -47,7 +50,7 @@ const App: FC = () => {
headerStyle: {
backgroundColor: colors.main,
},
headerTintColor: colors.white,
headerTintColor: '#fff',
}}
>
<Stack.Screen
Expand Down Expand Up @@ -76,9 +79,11 @@ const styles = StyleSheet.create({
title: {
fontSize: 24,
fontWeight: '700',
color: colors.white,
},
subtitle: {
opacity: 0.6,
color: colors.white,
},
button: {
paddingVertical: layout.spacing * 2,
Expand Down
6 changes: 4 additions & 2 deletions apps/common-app/src/components/Container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import type { PropsWithChildren, FC } from 'react';
import { StyleProp, ViewStyle } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { colors } from '../styles';

type ContainerProps = PropsWithChildren<{
style?: StyleProp<ViewStyle>;
Expand All @@ -10,15 +11,16 @@ type ContainerProps = PropsWithChildren<{

const Container: FC<ContainerProps> = (props) => {
const { children, style, centered } = props;

return (
<SafeAreaView
style={[
{
flex: 1,
padding: 8,
padding: 24,
},
centered && { justifyContent: 'center', alignItems: 'center' },
style,
style ?? { backgroundColor: colors.background },
]}
>
{children}
Expand Down
121 changes: 121 additions & 0 deletions apps/common-app/src/components/Select.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { useState } from 'react';
// @ts-expect-error
import { Icon } from '@swmansion/icons';
import { ScrollView } from 'react-native-gesture-handler';
import { Modal, View, Text, Pressable, StyleSheet } from 'react-native';

import { colors } from '../styles';
import withSeparators from '../utils/withSeparators';
import Spacer from './Spacer';

interface SelectProps<T extends string> {
value: T;
options: T[];
onChange: (value: T) => void;
}

function Select<T extends string>(props: SelectProps<T>) {
const { options, value, onChange } = props;
const [isModalOpen, setModalOpen] = useState(false);

const renderSeparator = (index: number) => (
<View key={index} style={styles.separator} />
);

const renderOption = (option: T) => (
<Pressable
key={option}
onPress={() => {
onChange(option);
setModalOpen(false);
}}
>
<View style={styles.optionRow}>
<Icon
size={24}
color={colors.white}
name={option === value ? 'check-circle' : 'circle'}
/>
<Spacer.Horizontal size={12} />
<Text style={styles.selectText}>{option}</Text>
</View>
</Pressable>
);

return (
<>
<Pressable onPress={() => setModalOpen(true)}>
<View style={styles.selectBox}>
<Text style={styles.selectText}>{value}</Text>
<Icon
size={34}
type="broken"
name="list-pointers"
color={colors.white}
/>
</View>
</Pressable>
<Modal visible={isModalOpen} animationType="fade" transparent>
<View style={styles.modalBg} />
<Pressable
style={styles.modalSpacer}
onPress={() => {
setModalOpen(false);
}}
/>
<View style={styles.modalContainer}>
<ScrollView>
{withSeparators(options, renderSeparator, renderOption)}
</ScrollView>
</View>
</Modal>
</>
);
}

export default Select;

const styles = StyleSheet.create({
selectBox: {
borderWidth: 1,
borderColor: '#999',
borderRadius: 8,
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 12,
},
selectText: {
flex: 1,
color: colors.white,
fontSize: 16,
paddingVertical: 12,
},
modalBg: {
backgroundColor: '#00000040',
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
},
modalSpacer: {
flex: 3,
},
modalContainer: {
flex: 2,
backgroundColor: '#222',
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
padding: 24,
},
optionRow: {
flexDirection: 'row',
alignItems: 'center',
},
separator: {
height: 1,
backgroundColor: '#333',
marginHorizontal: 12,
marginVertical: 6,
},
});
Loading

0 comments on commit 3615673

Please sign in to comment.