Skip to content

Commit c31ca06

Browse files
authored
Merge pull request #393 from mrzachnugent/@zach/react-19asfy
feat: remove forwardRef + minor refactoring
2 parents 6872b4a + db78b33 commit c31ca06

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+2584
-2841
lines changed

apps/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@react-native-reusables/cli",
3-
"version": "0.4.0",
3+
"version": "0.4.1",
44
"description": "Add react-native-reusables to your project.",
55
"publishConfig": {
66
"access": "public"

apps/cli/src/items/components.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export const COMPONENTS = [
7878
name: 'badge',
7979
dependencies: [],
8080
icons: [],
81-
npmPackages: ['@rn-primitives/slot', '@rn-primitives/types'],
81+
npmPackages: ['@rn-primitives/slot'],
8282
paths: [
8383
{
8484
from: './node_modules/@rnr/reusables/src/components/ui/badge.tsx',
@@ -93,7 +93,7 @@ export const COMPONENTS = [
9393
name: 'button',
9494
dependencies: ['text'],
9595
icons: [],
96-
npmPackages: ['@rn-primitives/types'],
96+
npmPackages: [],
9797
paths: [
9898
{
9999
from: './node_modules/@rnr/reusables/src/components/ui/button.tsx',
@@ -108,7 +108,7 @@ export const COMPONENTS = [
108108
name: 'card',
109109
dependencies: ['text'],
110110
icons: [],
111-
npmPackages: ['@rn-primitives/types'],
111+
npmPackages: [],
112112
paths: [
113113
{
114114
from: './node_modules/@rnr/reusables/src/components/ui/card.tsx',
@@ -408,7 +408,7 @@ export const COMPONENTS = [
408408
name: 'text',
409409
dependencies: [],
410410
icons: [],
411-
npmPackages: ['@rn-primitives/slot', '@rn-primitives/types'],
411+
npmPackages: ['@rn-primitives/slot'],
412412
paths: [
413413
{
414414
from: './node_modules/@rnr/reusables/src/components/ui/text.tsx',
@@ -468,7 +468,7 @@ export const COMPONENTS = [
468468
name: 'typography',
469469
dependencies: [],
470470
icons: [],
471-
npmPackages: ['@rn-primitives/slot', '@rn-primitives/types'],
471+
npmPackages: ['@rn-primitives/slot'],
472472
paths: [
473473
{
474474
from: './node_modules/@rnr/reusables/src/components/ui/typography.tsx',

apps/showcase/app/(tabs)/components/primitives.tsx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { useScrollToTop } from '@react-navigation/native';
22
import { FlashList } from '@shopify/flash-list';
3+
import { Link } from 'expo-router';
34
import * as React from 'react';
45
import { View } from 'react-native';
56
import { Button } from '~/components/ui/button';
67
import { Input } from '~/components/ui/input';
78
import { Text } from '~/components/ui/text';
89
import { PRIMITIVES } from '~/lib/constants';
10+
import { ExternalLink } from '~/lib/icons/ExternalLink';
911
import { cn } from '~/lib/utils';
1012

1113
export default function PrimitivesScreen() {
@@ -33,18 +35,20 @@ export default function PrimitivesScreen() {
3335
estimatedItemSize={49}
3436
showsVerticalScrollIndicator={false}
3537
renderItem={({ item, index }) => (
36-
<Button
37-
disabled
38-
variant='secondary'
39-
size='lg'
40-
className={cn(
41-
'opacity-100 bg-secondary/40 pl-4 pr-1.5 border-x border-t border-foreground/5 rounded-none flex-row justify-center',
42-
index === 0 && 'rounded-t-lg',
43-
index === data.length - 1 && 'border-b rounded-b-lg'
44-
)}
45-
>
46-
<Text className='text-xl'>{toOptions(item)}</Text>
47-
</Button>
38+
<Link href={`https://rnprimitives.com/${item}`} asChild>
39+
<Button
40+
variant='secondary'
41+
size='lg'
42+
className={cn(
43+
'bg-secondary/40 px-4 border-x border-t border-foreground/5 rounded-none flex-row justify-between',
44+
index === 0 && 'rounded-t-lg',
45+
index === data.length - 1 && 'border-b rounded-b-lg'
46+
)}
47+
>
48+
<Text className='text-xl'>@rn-primitives/{item}</Text>
49+
<ExternalLink size={16} className='text-foreground/50' />
50+
</Button>
51+
</Link>
4852
)}
4953
ListFooterComponent={<View className='py-4' />}
5054
/>

apps/showcase/app/(tabs)/index.tsx

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { Link } from 'expo-router';
21
import * as React from 'react';
32
import { Platform, View } from 'react-native';
43
import {
@@ -46,7 +45,6 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '~/components/ui/tooltip
4645
import { Muted } from '~/components/ui/typography';
4746
import { CalendarDays } from '~/lib/icons/CalendarDays';
4847
import { ChevronDown } from '~/lib/icons/ChevronDown';
49-
import { ChevronRight } from '~/lib/icons/ChevronRight';
5048
import { Info } from '~/lib/icons/Info';
5149
import { cn } from '~/lib/utils';
5250

@@ -57,7 +55,7 @@ export default function ExampleScreen() {
5755
<CardHeader>
5856
<View className='flex-row gap-3'>
5957
<CardTitle className='pt-1'>Team Members</CardTitle>
60-
<Tooltip delayDuration={150}>
58+
<Tooltip delayDuration={300}>
6159
<TooltipTrigger className='web:focus:outline-none'>
6260
<Info size={Platform.OS == 'web' ? 14 : 16} className='text-foreground' />
6361
</TooltipTrigger>
@@ -105,14 +103,6 @@ export default function ExampleScreen() {
105103
</View>
106104
</CardContent>
107105
</Card>
108-
<View className='items-center'>
109-
<Link href='/form' asChild>
110-
<Button variant='link' className='flex-row'>
111-
<Text>Go To Form</Text>
112-
<ChevronRight className='text-foreground' size={18} />
113-
</Button>
114-
</Link>
115-
</View>
116106
</View>
117107
);
118108
}

apps/showcase/app/_layout.tsx

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { DeprecatedUi } from '@rnr/reusables';
55
import { Stack } from 'expo-router';
66
import { StatusBar } from 'expo-status-bar';
77
import * as React from 'react';
8-
import { Platform } from 'react-native';
8+
import { Appearance, Platform } from 'react-native';
99
import { GestureHandlerRootView } from 'react-native-gesture-handler';
1010
import { ThemeToggle } from '~/components/ThemeToggle';
1111
import { Text } from '~/components/ui/text';
@@ -34,28 +34,16 @@ export const unstable_settings = {
3434
initialRouteName: '(tabs)',
3535
};
3636

37-
export default function RootLayout() {
38-
const hasMounted = React.useRef(false);
39-
const { colorScheme, isDarkColorScheme } = useColorScheme();
40-
const [isColorSchemeLoaded, setIsColorSchemeLoaded] = React.useState(false);
41-
42-
useIsomorphicLayoutEffect(() => {
43-
if (hasMounted.current) {
44-
return;
45-
}
37+
const usePlatformSpecificSetup = Platform.select({
38+
web: useSetWebBackgroundClassName,
39+
android: useSetAndroidNavigationBar,
40+
default: noop,
41+
});
4642

47-
if (Platform.OS === 'web') {
48-
// Adds the background color to the html element to prevent white background on overscroll.
49-
document.documentElement.classList.add('bg-background');
50-
}
51-
setAndroidNavigationBar(colorScheme);
52-
setIsColorSchemeLoaded(true);
53-
hasMounted.current = true;
54-
}, []);
43+
export default function RootLayout() {
44+
const { isDarkColorScheme } = useColorScheme();
5545

56-
if (!isColorSchemeLoaded) {
57-
return null;
58-
}
46+
usePlatformSpecificSetup();
5947

6048
return (
6149
<ThemeProvider value={isDarkColorScheme ? DARK_THEME : LIGHT_THEME}>
@@ -95,9 +83,6 @@ export default function RootLayout() {
9583
);
9684
}
9785

98-
const useIsomorphicLayoutEffect =
99-
Platform.OS === 'web' && typeof window === 'undefined' ? React.useEffect : React.useLayoutEffect;
100-
10186
function toOptions(name: string) {
10287
const title = name
10388
.split('-')
@@ -109,3 +94,21 @@ function toOptions(name: string) {
10994
.join(' ');
11095
return title;
11196
}
97+
98+
const useIsomorphicLayoutEffect =
99+
Platform.OS === 'web' && typeof window === 'undefined' ? React.useEffect : React.useLayoutEffect;
100+
101+
function useSetWebBackgroundClassName() {
102+
useIsomorphicLayoutEffect(() => {
103+
// Adds the background color to the html element to prevent white background on overscroll.
104+
document.documentElement.classList.add('bg-background');
105+
}, []);
106+
}
107+
108+
function useSetAndroidNavigationBar() {
109+
React.useLayoutEffect(() => {
110+
setAndroidNavigationBar(Appearance.getColorScheme() ?? 'light');
111+
}, []);
112+
}
113+
114+
function noop() {}

apps/showcase/app/modal.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ import {
1717
import { Text } from '~/components/ui/text';
1818
import { H1, Muted } from '~/components/ui/typography';
1919

20-
const CUSTOM_PORTAL_HOST_NAME = 'modal-example';
21-
const WindowOverlay = Platform.OS === 'ios' ? FullWindowOverlay : React.Fragment;
20+
const IOS_PORTAL_HOST_NAME = 'modal-example';
2221

2322
export default function ModalScreen() {
2423
const insets = useSafeAreaInsets();
@@ -50,7 +49,8 @@ export default function ModalScreen() {
5049
<SelectContent
5150
insets={contentInsets}
5251
className='w-full'
53-
portalHost={CUSTOM_PORTAL_HOST_NAME}
52+
portalHost={Platform.select({ ios: IOS_PORTAL_HOST_NAME })}
53+
sideOffset={Platform.select({ ios: 16 })}
5454
>
5555
<SelectGroup>
5656
<SelectLabel>Roles</SelectLabel>
@@ -83,9 +83,11 @@ export default function ModalScreen() {
8383
</View>
8484
</View>
8585
</View>
86-
<WindowOverlay>
87-
<PortalHost name={CUSTOM_PORTAL_HOST_NAME} />
88-
</WindowOverlay>
86+
{Platform.OS === 'ios' && (
87+
<FullWindowOverlay>
88+
<PortalHost name={IOS_PORTAL_HOST_NAME} />
89+
</FullWindowOverlay>
90+
)}
8991
</>
9092
);
9193
}

apps/showcase/app/navigation-menu.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type { ViewRef } from '@rn-primitives/types';
21
import { useNavigation } from 'expo-router';
32
import * as React from 'react';
43
import { Platform, Pressable, StyleSheet, View } from 'react-native';
@@ -153,14 +152,16 @@ const components: { title: string; href: string; description: string }[] = [
153152
},
154153
];
155154

156-
const ListItem = React.forwardRef<
157-
ViewRef,
158-
React.ComponentPropsWithoutRef<typeof View> & { title: string; href: string }
159-
>(({ className, title, children, ...props }, ref) => {
155+
type ListItemProps = Omit<React.ComponentProps<typeof NavigationMenuLink>, 'children'> & {
156+
children: React.ReactNode;
157+
title: string;
158+
href: string;
159+
};
160+
161+
function ListItem({ className, title, children, ...props }: ListItemProps) {
160162
return (
161163
<View role='listitem'>
162164
<NavigationMenuLink
163-
ref={ref}
164165
className={cn(
165166
'web:block web:select-none gap-1 rounded-md p-3 leading-none no-underline text-foreground web:outline-none web:transition-colors web:hover:bg-accent active:bg-accent web:hover:text-accent-foreground web:focus:bg-accent web:focus:text-accent-foreground',
166167
className
@@ -176,5 +177,4 @@ const ListItem = React.forwardRef<
176177
</NavigationMenuLink>
177178
</View>
178179
);
179-
});
180-
ListItem.displayName = 'ListItem';
180+
}

apps/showcase/components/ThemeToggle.tsx

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { setAndroidNavigationBar } from '~/lib/android-navigation-bar';
33
import { MoonStar } from '~/lib/icons/MoonStar';
44
import { Sun } from '~/lib/icons/Sun';
55
import { useColorScheme } from '~/lib/useColorScheme';
6-
import { cn } from '~/lib/utils';
76

87
export function ThemeToggle() {
98
const { isDarkColorScheme, setColorScheme } = useColorScheme();
@@ -17,22 +16,15 @@ export function ThemeToggle() {
1716
return (
1817
<Pressable
1918
onPress={toggleColorScheme}
20-
className='web:ring-offset-background web:transition-colors web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2'
19+
className='web:ring-offset-background web:transition-colors web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2 active:opacity-70'
2120
>
22-
{({ pressed }) => (
23-
<View
24-
className={cn(
25-
'flex-1 aspect-square pt-0.5 justify-center items-start web:px-5',
26-
pressed && 'opacity-70'
27-
)}
28-
>
29-
{isDarkColorScheme ? (
30-
<MoonStar className='text-foreground' size={23} strokeWidth={1.25} />
31-
) : (
32-
<Sun className='text-foreground' size={24} strokeWidth={1.25} />
33-
)}
34-
</View>
35-
)}
21+
<View className='flex-1 aspect-square pt-0.5 justify-center items-start web:px-5'>
22+
{isDarkColorScheme ? (
23+
<MoonStar className='text-foreground' size={23} strokeWidth={1.25} />
24+
) : (
25+
<Sun className='text-foreground' size={24} strokeWidth={1.25} />
26+
)}
27+
</View>
3628
</Pressable>
3729
);
3830
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { Lib } from '@rnr/reusables';
2+
export const { ExternalLink } = Lib.Icons;

apps/showcase/package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,10 @@
2222
"@rn-primitives/aspect-ratio": "~1.2.0",
2323
"@rn-primitives/collapsible": "~1.2.0",
2424
"@rn-primitives/label": "~1.2.0",
25-
"@rn-primitives/portal": "~1.2.0",
25+
"@rn-primitives/portal": "~1.3.0",
2626
"@rn-primitives/slider": "~1.2.0",
2727
"@rn-primitives/toast": "~1.2.0",
2828
"@rn-primitives/toolbar": "~1.2.0",
29-
"@rn-primitives/types": "~1.2.0",
3029
"@rnr/reusables": "workspace:*",
3130
"@shopify/flash-list": "1.7.6",
3231
"@tanstack/react-table": "^8.11.7",
@@ -58,8 +57,7 @@
5857
"react-native-web": "~0.20.0",
5958
"tailwind-merge": "^2.2.1",
6059
"tailwindcss-animate": "^1.0.7",
61-
"zod": "^3.22.4",
62-
"zustand": "^4.4.7"
60+
"zod": "^3.22.4"
6361
},
6462
"devDependencies": {
6563
"@babel/core": "^7.26.0",

0 commit comments

Comments
 (0)