Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1a85e46
feat: add toggle theme and update 'select' component in expo-styleshe…
mehradotdev Aug 18, 2025
bef0a61
fix: minor styling issues
mehradotdev Aug 18, 2025
14eaa2c
feat: add 'accordion', 'alert-dialog', 'aspect-ratio', 'avatar' compo…
mehradotdev Aug 20, 2025
d817f55
chore: remove unused 'icons' code
mehradotdev Aug 21, 2025
b5b6679
feat: add 'checkbox', 'collapsible', 'context-menu', 'dialog' compone…
mehradotdev Aug 21, 2025
f22c865
feat: add 'dropdown-menu', 'hover-card', 'menubar', 'navigation-menu'…
mehradotdev Aug 24, 2025
d5a20d6
feat: add 'popover', 'progress', 'radio-group' in expo-stylesheet app
mehradotdev Aug 24, 2025
e65dbfa
feat: add 'separator', 'slider', 'switch', 'table', 'tabs' in expo-st…
mehradotdev Aug 25, 2025
8e2d4c1
feat: add 'toggle-group', 'toggle', 'toolbar', 'tooltip' in expo-styl…
mehradotdev Aug 26, 2025
fa464cb
chore: add npm command to run expo-stylesheet app
mehradotdev Aug 26, 2025
906d07c
fix: some buttons are not highlighted when pressed
mehradotdev Aug 26, 2025
03c2115
fix: styling issues of landing page for Web Platform
mehradotdev Aug 26, 2025
35b5f75
fix: Web related styling issues in 'accordion', 'alert-dialog'
mehradotdev Aug 27, 2025
c28c0c3
fix: Web related styling issues in 'collapsible', 'checkbox', 'contex…
mehradotdev Aug 28, 2025
6e6c7ea
fix: Web related styling issues in 'navigation-menu', 'dropdown-menu'…
mehradotdev Aug 29, 2025
c1c7153
fix: Web styling issues in 'popover', 'progress', 'radio-group', 'sel…
mehradotdev Aug 30, 2025
96d83f8
fix: Web styling issues in 'separator', 'slider', 'switch', 'table'
mehradotdev Aug 31, 2025
f1d9042
fix: Web styling issues in 'toolbar', 'tooltip', 'tabs', 'toggle', 't…
mehradotdev Sep 1, 2025
25e9164
fix: minor styling issues in navigation-menu
mehradotdev Sep 1, 2025
563ff99
chore: fontWeight must be a string in React Native
mehradotdev Sep 1, 2025
5ceffff
chore: implement some CodeRabbit suggestion
mehradotdev Sep 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions apps/expo-stylesheet/app/(components)/accordion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { View, StyleSheet } from 'react-native';
import { useTheme } from '@react-navigation/native';
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from '~/components/ui/accordion';
import { Text } from '~/components/ui/text';

export default function AccordionScreen() {
const { colors } = useTheme();

return (
<View style={[styles.container]}>
<Accordion type='multiple' collapsible defaultValue={['item-1']} style={styles.accordion}>
<AccordionItem value='item-1'>
<AccordionTrigger>
<Text style={{ color: colors.text }}>Is it accessible?</Text>
</AccordionTrigger>
<AccordionContent>
<Text style={{ color: colors.text }}>
Yes. It adheres to the WAI-ARIA design pattern.
</Text>
</AccordionContent>
</AccordionItem>

<AccordionItem value='item-2'>
<AccordionTrigger>
<Text style={{ color: colors.text }}>What are universal components?</Text>
</AccordionTrigger>
<AccordionContent>
<Text style={{ color: colors.text }}>
In the world of React Native, universal components are components that work on both
web and native platforms.
</Text>
</AccordionContent>
</AccordionItem>

<AccordionItem value='item-3'>
<AccordionTrigger>
<Text style={{ color: colors.text }}>Is this component universal?</Text>
</AccordionTrigger>
<AccordionContent>
<Text style={{ color: colors.text }}>
Yes. Try it out on the web, iOS, and/or Android.
</Text>
</AccordionContent>
</AccordionItem>
</Accordion>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 24,
},
accordion: {
width: '100%',
maxWidth: 384,
},
});
53 changes: 53 additions & 0 deletions apps/expo-stylesheet/app/(components)/alert-dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { View, StyleSheet } from 'react-native';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from '~/components/ui/alert-dialog';
import { Button } from '~/components/ui/button';
import { Text } from '~/components/ui/text';

export default function AlertDialogScreen() {
return (
<View style={styles.container}>
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant='outline'>
<Text>Show Alert Dialog</Text>
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. This will permanently delete your account and remove
your data from our servers.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>
<Text>Cancel</Text>
</AlertDialogCancel>
<AlertDialogAction>
<Text>Continue</Text>
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
37 changes: 37 additions & 0 deletions apps/expo-stylesheet/app/(components)/aspect-ratio.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import { View, StyleSheet } from 'react-native';
import { AspectRatio } from '~/components/ui/aspect-ratio';
import { H1 } from '~/components/ui/typography';

export default function AspectRatioScreen() {
return (
<View style={styles.container}>
<View style={styles.wrapper}>
<AspectRatio ratio={16 / 9}>
<View style={[styles.innerBox]}>
<H1 style={{ color: '#fff' }}>16:9</H1>
</View>
</AspectRatio>
</View>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
wrapper: {
width: '50%',
},
innerBox: {
backgroundColor: '#3b82f6',
height: '100%',
width: '100%',
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
},
});
28 changes: 28 additions & 0 deletions apps/expo-stylesheet/app/(components)/avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { View, StyleSheet } from 'react-native';
import { Avatar, AvatarFallback, AvatarImage } from '~/components/ui/avatar';
import { Text } from '~/components/ui/text';

const GITHUB_AVATAR_URI = 'https://github.com/mrzachnugent.png';

export default function AvatarScreen() {
return (
<View style={styles.container}>
<Avatar alt="Zach Nugent's Avatar">
<AvatarImage source={{ uri: GITHUB_AVATAR_URI }} />
<AvatarFallback>
<Text>ZN</Text>
</AvatarFallback>
</Avatar>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 24, // p-6
gap: 48, // gap-12
},
});
43 changes: 43 additions & 0 deletions apps/expo-stylesheet/app/(components)/checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as React from 'react';
import { Platform, View, StyleSheet } from 'react-native';
import { Checkbox } from '~/components/ui/checkbox';
import { Label } from '~/components/ui/label';

export default function CheckboxScreen() {
const [checked, setChecked] = React.useState(false);

return (
<View style={styles.container}>
<View style={styles.row}>
<Checkbox
id='checkbox'
aria-labelledby='terms'
checked={checked}
onCheckedChange={setChecked}
/>
<Label
nativeID='terms'
onPress={Platform.select({ web: undefined, default: () => setChecked((prev) => !prev) })}
htmlFor='checkbox'
>
Accept terms and conditions
</Label>
</View>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 24,
gap: 48,
},
row: {
flexDirection: 'row',
gap: 12,
alignItems: 'center',
},
});
115 changes: 115 additions & 0 deletions apps/expo-stylesheet/app/(components)/collapsible.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import * as React from 'react';
import { Platform, Text, View, StyleSheet } from 'react-native';
import Animated, { FadeInDown, LinearTransition } from 'react-native-reanimated';
import { ChevronsDownUp, ChevronsUpDown } from 'lucide-react-native';
import { useTheme } from '@react-navigation/native';
import { Button } from '~/components/ui/button';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '~/components/ui/collapsible';

export default function CollapsibleScreen() {
const [open, setOpen] = React.useState(false);
const { colors } = useTheme();

return (
<View style={styles.container}>
<Collapsible asChild open={open} onOpenChange={setOpen}>
<Animated.View layout={Platform.OS !== 'web' ? LinearTransition : undefined}>
<View style={styles.contentWrapper}>
<View style={styles.header}>
<Text style={[styles.headerText, { color: colors.text }]}>
@peduarte starred 3 repositories
</Text>
<CollapsibleTrigger asChild>
<Button variant='ghost' size='icon'>
{open ? (
<ChevronsDownUp size={16} color={colors.text} />
) : (
<ChevronsUpDown size={16} color={colors.text} />
)}
<Text style={styles.srOnly}>Toggle</Text>
</Button>
</CollapsibleTrigger>
</View>

<View style={[styles.card, { borderColor: colors.border }]}>
<Text style={[styles.cardText, { color: colors.text }]}>@radix-ui/primitives</Text>
</View>

<CollapsibleContent style={styles.collapsibleContent}>
<CollapsibleItem delay={100}>@radix-ui/react</CollapsibleItem>
<CollapsibleItem delay={200}>@stitches/core</CollapsibleItem>
</CollapsibleContent>
</View>
</Animated.View>
</Collapsible>
</View>
);
}

function CollapsibleItem({ children, delay }: { children: string; delay: number }) {
const { colors } = useTheme();

if (Platform.OS === 'web') {
return (
<View style={[styles.card, { borderColor: colors.border }]}>
<Text style={[styles.cardText, { color: colors.text }]}>{children}</Text>
</View>
);
}

return (
<Animated.View
entering={FadeInDown.duration(200).delay(delay)}
style={[styles.card, { borderColor: colors.border }]}
>
<Text style={[styles.cardText, { color: colors.text }]}>{children}</Text>
</Animated.View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 24,
},
contentWrapper: {
width: '100%',
maxWidth: 350,
gap: 8,
},
header: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
gap: 16,
paddingHorizontal: 16,
},
headerText: {
fontSize: Platform.OS === 'web' ? 14 : 16,
fontWeight: '600',
},
card: {
borderWidth: 1,
borderRadius: 6,
paddingHorizontal: 16,
paddingVertical: 12,
},
cardText: {
fontSize: Platform.OS === 'web' ? 14 : 16,
lineHeight: 20,
},
collapsibleContent: {
gap: 8,
},
srOnly: {
position: 'absolute',
width: 1,
height: 1,
margin: -1,
padding: 0,
borderWidth: 0,
overflow: 'hidden',
},
});
Loading