create-expo-stack 2.7.0-next.2960d96 → 2.7.0-next.2a20d82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,18 +6,29 @@ import {
6
6
  <% if (props.stylingPackage?.options.selectedComponents.includes('alert')) { %>
7
7
  Alert,
8
8
  <% } %>
9
+ <% if (
10
+ props.stylingPackage?.options.selectedComponents.includes('alert') ||
11
+ props.stylingPackage?.options.selectedComponents.includes('action-sheet') ||
12
+ props.stylingPackage?.options.selectedComponents.includes('activity-view') ||
13
+ props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')
14
+ ) { %>
9
15
  Button as RNButton,
10
16
  ButtonProps,
17
+ <% } %>
11
18
  Linking,
19
+ <% if (props.stylingPackage?.options.selectedComponents.includes('alert') || props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %>
12
20
  Platform,
21
+ <% } %>
13
22
  <% if (props.stylingPackage?.options.selectedComponents.includes('dropdown-menu')) { %>
14
23
  Pressable,
15
24
  <% } %>
16
25
  <% if (props.stylingPackage?.options.selectedComponents.includes('activity-view')) { %>
17
26
  Share,
18
27
  <% } %>
28
+ useWindowDimensions,
19
29
  View,
20
30
  } from 'react-native';
31
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
21
32
  <% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %>
22
33
  import { useActionSheet } from '@expo/react-native-action-sheet';
23
34
  <% } %>
@@ -68,14 +79,19 @@ cssInterop(FlashList, {
68
79
  className: 'style',
69
80
  contentContainerClassName: 'contentContainerStyle',
70
81
  });
71
-
82
+ <% if (
83
+ props.stylingPackage?.options.selectedComponents.includes('alert') ||
84
+ props.stylingPackage?.options.selectedComponents.includes('action-sheet') ||
85
+ props.stylingPackage?.options.selectedComponents.includes('activity-view') ||
86
+ props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')
87
+ ) { %>
72
88
  function DefaultButton({ color, ...props }: ButtonProps) {
73
89
  const { colors } = useColorScheme();
74
90
  return <RNButton color={color ?? colors.primary} {...props} />;
75
91
  }
76
-
92
+ <% } %>
77
93
  export default function Screen() {
78
- const searchValue = useHeaderSearchBar();
94
+ const searchValue = useHeaderSearchBar({ hideWhenScrolling: COMPONENTS.length === 0 });
79
95
 
80
96
  const data = searchValue
81
97
  ? COMPONENTS.filter((c) => c.name.toLowerCase().includes(searchValue.toLowerCase()))
@@ -88,30 +104,28 @@ export default function Screen() {
88
104
  data={data}
89
105
  estimatedItemSize={200}
90
106
  contentContainerClassName="py-4"
91
- centerContent={data.length === 0}
92
107
  extraData={searchValue}
108
+ <% if (props.stylingPackage?.options.selectedComponents.includes('selectable-text')) { %>
93
109
  removeClippedSubviews={false} // used for selecting text on android
110
+ <% } %>
94
111
  keyExtractor={keyExtractor}
95
112
  ItemSeparatorComponent={renderItemSeparator}
96
113
  renderItem={renderItem}
97
- ListEmptyComponent={ListEmptyComponent}
114
+ ListEmptyComponent={COMPONENTS.length === 0 ? ListEmptyComponent : undefined}
98
115
  />
99
116
  );
100
117
  }
101
118
 
102
- const SEARCH_BAR_HEIGHT = 52;
103
-
104
119
  function ListEmptyComponent() {
105
120
  const insets = useSafeAreaInsets();
121
+ const dimensions = useWindowDimensions();
106
122
  const headerHeight = useHeaderHeight();
107
123
  const { colors } = useColorScheme();
124
+ const height = dimensions.height - headerHeight - insets.bottom - insets.top;
125
+
108
126
  return (
109
- <>
110
- {Platform.OS === 'ios' && (
111
- <View style={{ height: headerHeight + SEARCH_BAR_HEIGHT + insets.top - insets.bottom }} />
112
- )}
113
- <View className='flex-1 items-center justify-center px-12 gap-1'>
114
- <Icon name='folder-plus-outline' size={42} color={colors.grey} />
127
+ <View style={{ height }} className="flex-1 items-center justify-center gap-1 px-12">
128
+ <Icon name="file-plus-outline" size={42} color={colors.grey} />
115
129
  <Text variant='title3' className='pb-1 text-center font-semibold'>
116
130
  No Components Installed
117
131
  </Text>
@@ -127,11 +141,10 @@ function ListEmptyComponent() {
127
141
  {' website.'}
128
142
  </Text>
129
143
  </View>
130
- </>
131
144
  );
132
145
  }
133
146
 
134
- type ComponentItem = { name: string; component: () => React.JSX.Element };
147
+ type ComponentItem = { name: string; component: React.FC };
135
148
 
136
149
  function keyExtractor(item: ComponentItem) {
137
150
  return item.name;
@@ -159,12 +172,14 @@ function Card({ children, title }: { children: React.ReactNode; title: string })
159
172
  </View>
160
173
  );
161
174
  }
162
-
175
+ <% if (props.stylingPackage?.options.selectedComponents.includes('ratings-indicator')) { %>
176
+ let hasRequestedReview = false;
177
+ <% } %>
163
178
  const COMPONENTS: ComponentItem[] = [
164
179
  <% if (props.stylingPackage?.options.selectedComponents.includes('picker')) { %>
165
180
  {
166
181
  name: 'Picker',
167
- component: () => {
182
+ component: function PickerExample() {
168
183
  const { colors } = useColorScheme();
169
184
  const [picker, setPicker] = React.useState('blue');
170
185
  return (
@@ -204,7 +219,7 @@ const COMPONENTS: ComponentItem[] = [
204
219
  <% if (props.stylingPackage?.options.selectedComponents.includes('date-picker')) { %>
205
220
  {
206
221
  name: 'Date Picker',
207
- component: () => {
222
+ component: function DatePickerExample() {
208
223
  const [date, setDate] = React.useState(new Date());
209
224
  return (
210
225
  <View className='items-center'>
@@ -223,7 +238,7 @@ const COMPONENTS: ComponentItem[] = [
223
238
  <% if (props.stylingPackage?.options.selectedComponents.includes('segmented-control')) { %>
224
239
  {
225
240
  name: 'Segmented Controls',
226
- component: () => {
241
+ component: function SegmentedControlsExample() {
227
242
  const [segment, setSegment] = React.useState(0);
228
243
  return (
229
244
  <SegmentedControl
@@ -240,7 +255,7 @@ const COMPONENTS: ComponentItem[] = [
240
255
  <% if (props.stylingPackage?.options.selectedComponents.includes('slider')) { %>
241
256
  {
242
257
  name: 'Slider',
243
- component: () => {
258
+ component: function SliderExample() {
244
259
  const [sliderValue, setSliderValue] = React.useState(0.5);
245
260
  return <Slider value={sliderValue} onValueChange={setSliderValue} />;
246
261
  },
@@ -249,7 +264,7 @@ const COMPONENTS: ComponentItem[] = [
249
264
  <% if (props.stylingPackage?.options.selectedComponents.includes('toggle')) { %>
250
265
  {
251
266
  name: 'Toggle',
252
- component: () => {
267
+ component: function ToggleExample() {
253
268
  const [switchValue, setSwitchValue] = React.useState(true);
254
269
  return (
255
270
  <View className='items-center'>
@@ -262,7 +277,7 @@ const COMPONENTS: ComponentItem[] = [
262
277
  <% if (props.stylingPackage?.options.selectedComponents.includes('context-menu')) { %>
263
278
  {
264
279
  name: 'Context Menu',
265
- component: () => {
280
+ component: function ContextMenuExample() {
266
281
  const [isChecked, setIsChecked] = React.useState(true);
267
282
  return (
268
283
  <View>
@@ -303,9 +318,9 @@ const COMPONENTS: ComponentItem[] = [
303
318
  <% if (props.stylingPackage?.options.selectedComponents.includes('dropdown-menu')) { %>
304
319
  {
305
320
  name: 'Dropdown Menu',
306
- component: () => {
321
+ component: function DropdownMenuExample() {
307
322
  const { colors } = useColorScheme();
308
- const [menu, setMenu] = React.useState<'blue' | 'red'>('blue');
323
+ const [menu, setMenu] = React.useState<'primary' | 'destructive'>('primary');
309
324
 
310
325
  return (
311
326
  <View className='items-center'>
@@ -326,24 +341,24 @@ const COMPONENTS: ComponentItem[] = [
326
341
  </DropdownMenu.Trigger>
327
342
  <DropdownMenu.Content>
328
343
  <DropdownMenu.CheckboxItem
329
- key='red'
330
- value={menu === 'red'}
344
+ key='destructive'
345
+ value={menu === 'destructive'}
331
346
  onValueChange={() => {
332
- setMenu('red');
347
+ setMenu('destructive');
333
348
  }}
334
349
  >
335
350
  <DropdownMenu.ItemIndicator />
336
- <DropdownMenu.ItemTitle children='red' />
351
+ <DropdownMenu.ItemTitle children='destructive' />
337
352
  </DropdownMenu.CheckboxItem>
338
353
  <DropdownMenu.CheckboxItem
339
- key='blue'
340
- value={menu === 'blue'}
354
+ key='primary'
355
+ value={menu === 'primary'}
341
356
  onValueChange={() => {
342
- setMenu('blue');
357
+ setMenu('primary');
343
358
  }}
344
359
  >
345
360
  <DropdownMenu.ItemIndicator />
346
- <DropdownMenu.ItemTitle children='blue' />
361
+ <DropdownMenu.ItemTitle children='primary' />
347
362
  </DropdownMenu.CheckboxItem>
348
363
  </DropdownMenu.Content>
349
364
  </DropdownMenu.Root>
@@ -355,14 +370,14 @@ const COMPONENTS: ComponentItem[] = [
355
370
  <% if (props.stylingPackage?.options.selectedComponents.includes('progress-indicator')) { %>
356
371
  {
357
372
  name: 'Progress Indicator',
358
- component: () => {
373
+ component: function ProgressIndicatorExample() {
359
374
  const [progress, setProgress] = React.useState(13);
360
375
  let id: ReturnType<typeof setInterval> | null = null;
361
376
  React.useEffect(() => {
362
377
  if (!id) {
363
378
  id = setInterval(() => {
364
379
  setProgress((prev) => (prev >= 99 ? 0 : prev + 5));
365
- }, Math.random() * 3000);
380
+ }, 1000);
366
381
  }
367
382
  return () => {
368
383
  if (id) clearInterval(id);
@@ -379,7 +394,7 @@ const COMPONENTS: ComponentItem[] = [
379
394
  <% if (props.stylingPackage?.options.selectedComponents.includes('activity-indicator')) { %>
380
395
  {
381
396
  name: 'Activity Indicator',
382
- component: () => {
397
+ component: function ActivityIndicatorExample() {
383
398
  return (
384
399
  <View className='p-4 items-center'>
385
400
  <ActivityIndicator />
@@ -391,14 +406,14 @@ const COMPONENTS: ComponentItem[] = [
391
406
  <% if (props.stylingPackage?.options.selectedComponents.includes('alert')) { %>
392
407
  {
393
408
  name: 'Alert',
394
- component: () => {
409
+ component: function AlertExample() {
395
410
  const { colors } = useColorScheme();
396
411
  return (
397
412
  <View className='items-center'>
398
413
  <DefaultButton
399
- color={colors.red}
414
+ color={colors.destructive}
400
415
  onPress={() => {
401
- if (Platform.OS == 'ios') {
416
+ if (Platform.OS === 'ios') {
402
417
  Alert.prompt(
403
418
  'Delete account?',
404
419
  'Enter your password to delete your account.',
@@ -447,7 +462,7 @@ const COMPONENTS: ComponentItem[] = [
447
462
  <% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %>
448
463
  {
449
464
  name: 'Action Sheet',
450
- component: () => {
465
+ component: function ActionSheetExample() {
451
466
  const { colorScheme, colors } = useColorScheme();
452
467
  const { showActionSheetWithOptions } = useActionSheet();
453
468
  return (
@@ -497,49 +512,51 @@ const COMPONENTS: ComponentItem[] = [
497
512
  <% if (props.stylingPackage?.options.selectedComponents.includes('text')) { %>
498
513
  {
499
514
  name: 'Text',
500
- component: () => (
501
- <View className='gap-2'>
502
- <Text variant='largeTitle' className='text-center'>
503
- Large Title
504
- </Text>
505
- <Text variant='title1' className='text-center'>
506
- Title 1
507
- </Text>
508
- <Text variant='title2' className='text-center'>
509
- Title 2
510
- </Text>
511
- <Text variant='title3' className='text-center'>
512
- Title 3
513
- </Text>
514
- <Text variant='heading' className='text-center'>
515
- Heading
516
- </Text>
517
- <Text variant='body' className='text-center'>
518
- Body
519
- </Text>
520
- <Text variant='callout' className='text-center'>
521
- Callout
522
- </Text>
523
- <Text variant='subhead' className='text-center'>
524
- Subhead
525
- </Text>
526
- <Text variant='footnote' className='text-center'>
527
- Footnote
528
- </Text>
529
- <Text variant='caption1' className='text-center'>
530
- Caption 1
531
- </Text>
532
- <Text variant='caption2' className='text-center'>
533
- Caption 2
534
- </Text>
535
- </View>
536
- ),
515
+ component: function TextExample() {
516
+ return (
517
+ <View className='gap-2'>
518
+ <Text variant='largeTitle' className='text-center'>
519
+ Large Title
520
+ </Text>
521
+ <Text variant='title1' className='text-center'>
522
+ Title 1
523
+ </Text>
524
+ <Text variant='title2' className='text-center'>
525
+ Title 2
526
+ </Text>
527
+ <Text variant='title3' className='text-center'>
528
+ Title 3
529
+ </Text>
530
+ <Text variant='heading' className='text-center'>
531
+ Heading
532
+ </Text>
533
+ <Text variant='body' className='text-center'>
534
+ Body
535
+ </Text>
536
+ <Text variant='callout' className='text-center'>
537
+ Callout
538
+ </Text>
539
+ <Text variant='subhead' className='text-center'>
540
+ Subhead
541
+ </Text>
542
+ <Text variant='footnote' className='text-center'>
543
+ Footnote
544
+ </Text>
545
+ <Text variant='caption1' className='text-center'>
546
+ Caption 1
547
+ </Text>
548
+ <Text variant='caption2' className='text-center'>
549
+ Caption 2
550
+ </Text>
551
+ </View>
552
+ );
553
+ },
537
554
  },
538
555
  <% } %>
539
- <% if (props.stylingPackage?.options.selectedComponents.includes('actionable-text')) { %>
556
+ <% if (props.stylingPackage?.options.selectedComponents.includes('selectable-text')) { %>
540
557
  {
541
- name: 'Actionable Text',
542
- component: () => {
558
+ name: 'Selectable Text',
559
+ component: function SelectableTextExample() {
543
560
  return (
544
561
  <Text uiTextView selectable>
545
562
  Long press or double press this text
@@ -551,61 +568,99 @@ const COMPONENTS: ComponentItem[] = [
551
568
  <% if (props.stylingPackage?.options.selectedComponents.includes('ratings-indicator')) { %>
552
569
  {
553
570
  name: 'Ratings Indicator',
554
- component: () => (
555
- <View className='items-center'>
556
- <DefaultButton
557
- color='orange'
558
- onPress={async () => {
571
+ component: function RatingsIndicatorExample() {
572
+ React.useEffect(() => {
573
+ async function showRequestReview() {
574
+ if (hasRequestedReview) return;
575
+ try {
559
576
  if (await StoreReview.hasAction()) {
560
- StoreReview.requestReview();
577
+ await StoreReview.requestReview();
561
578
  }
562
- if (Platform.OS === 'android') {
563
- Alert.alert(
564
- 'Android Demo',
565
- 'Store review is not available for Android demo'
566
- );
567
- }
568
- }}
569
- title='Rate this app'
570
- />
571
- </View>
572
- ),
579
+ } catch (error) {
580
+ console.log(
581
+ 'FOR ANDROID: Make sure you meet all conditions to be able to test and use it: https://developer.android.com/guide/playcore/in-app-review/test#troubleshooting',
582
+ error
583
+ );
584
+ } finally {
585
+ hasRequestedReview = true;
586
+ }
587
+ }
588
+ const timeout = setTimeout(() => {
589
+ showRequestReview();
590
+ }, 1000);
591
+
592
+ return () => clearTimeout(timeout);
593
+ }, []);
594
+
595
+ return (
596
+ <View className="gap-3">
597
+ <Text className="pb-2 text-center font-semibold">Please follow the guidelines.</Text>
598
+ <View className="flex-row">
599
+ <Text className="w-6 text-center text-muted-foreground">·</Text>
600
+ <View className="flex-1">
601
+ <Text variant="caption1" className="text-muted-foreground">
602
+ Don't call StoreReview.requestReview() from a button
603
+ </Text>
604
+ </View>
605
+ </View>
606
+ <View className="flex-row">
607
+ <Text className="w-6 text-center text-muted-foreground">·</Text>
608
+ <View className="flex-1">
609
+ <Text variant="caption1" className="text-muted-foreground">
610
+ Don't request a review when the user is doing something time sensitive.
611
+ </Text>
612
+ </View>
613
+ </View>
614
+ <View className="flex-row">
615
+ <Text className="w-6 text-center text-muted-foreground">·</Text>
616
+ <View className="flex-1">
617
+ <Text variant="caption1" className="text-muted-foreground">
618
+ Don't ask the user any questions before or while presenting the rating button or
619
+ card.
620
+ </Text>
621
+ </View>
622
+ </View>
623
+ </View>
624
+ );
625
+ },
573
626
  },
574
627
  <% } %>
575
628
  <% if (props.stylingPackage?.options.selectedComponents.includes('activity-view')) { %>
576
629
  {
577
630
  name: 'Activity View',
578
- component: () => (
579
- <View className='items-center'>
580
- <DefaultButton
581
- onPress={async () => {
582
- try {
583
- const result = await Share.share({
584
- message: 'NativeWindUI | Familiar interface, native feel.',
585
- });
586
- if (result.action === Share.sharedAction) {
587
- if (result.activityType) {
588
- // shared with activity type of result.activityType
589
- } else {
590
- // shared
631
+ component: function ActivityViewExample() {
632
+ return (
633
+ <View className='items-center'>
634
+ <DefaultButton
635
+ onPress={async () => {
636
+ try {
637
+ const result = await Share.share({
638
+ message: 'NativeWindUI | Familiar interface, native feel.',
639
+ });
640
+ if (result.action === Share.sharedAction) {
641
+ if (result.activityType) {
642
+ // shared with activity type of result.activityType
643
+ } else {
644
+ // shared
645
+ }
646
+ } else if (result.action === Share.dismissedAction) {
647
+ // dismissed
591
648
  }
592
- } else if (result.action === Share.dismissedAction) {
593
- // dismissed
649
+ } catch (error: any) {
650
+ Alert.alert(error.message);
594
651
  }
595
- } catch (error: any) {
596
- Alert.alert(error.message);
597
- }
598
- }}
599
- title='Share a message'
600
- />
601
- </View>
602
- ),
652
+ }}
653
+ title='Share a message'
654
+ />
655
+ </View>
656
+ );
657
+ },
603
658
  },
604
659
  <% } %>
605
660
  <% if (props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %>
606
661
  {
607
662
  name: 'Bottom Sheet',
608
- component: () => {
663
+ component: function BottomSheetExample() {
609
664
  const { colorScheme } = useColorScheme();
610
665
  const bottomSheetModalRef = useSheetRef();
611
666
 
@@ -633,7 +688,7 @@ const COMPONENTS: ComponentItem[] = [
633
688
  <% if (props.stylingPackage?.options.selectedComponents.includes('avatar')) { %>
634
689
  {
635
690
  name: 'Avatar',
636
- component: () => {
691
+ component: function AvatarExample() {
637
692
  const GITHUB_AVATAR_URI = 'https://github.com/mrzachnugent.png';
638
693
  return (
639
694
  <View className='items-center'>
@@ -1,31 +1,32 @@
1
- import { Text } from '~/components/nativewind-ui/Text';
2
- import { Link } from 'expo-router';
1
+ import { Icon } from '@roninoss/icons';
3
2
  import { StatusBar } from 'expo-status-bar';
4
- import { useColorScheme } from 'nativewind';
5
- import { Platform, View } from 'react-native';
3
+ import { Linking, Platform, View } from 'react-native';
4
+
5
+ import { Text } from '~/components/nativewind-ui/Text';
6
+ import { useColorScheme } from '~/lib/useColorScheme';
6
7
 
7
8
  export default function ModalScreen() {
8
- const { colorScheme } = useColorScheme();
9
+ const { colors, colorScheme } = useColorScheme();
9
10
  return (
10
11
  <>
11
12
  <StatusBar
12
- style={
13
- Platform.OS === 'ios'
14
- ? 'light'
15
- : colorScheme === 'dark'
16
- ? 'light'
17
- : 'dark'
18
- }
13
+ style={Platform.OS === 'ios' ? 'light' : colorScheme === 'dark' ? 'light' : 'dark'}
19
14
  />
20
- <View className='flex-1 justify-center items-center gap-8 pb-12'>
21
- <View className='items-center gap-2'>
22
- <Text variant='largeTitle' className='font-bold'>
15
+ <View className="flex-1 items-center justify-center gap-1 px-12">
16
+ <Icon name="file-plus-outline" size={42} color={colors.grey} />
17
+ <Text variant="title3" className="pb-1 text-center font-semibold">
18
+ NativeWindUI
19
+ </Text>
20
+ <Text color="tertiary" variant="subhead" className="pb-4 text-center">
21
+ You can install any of the free components from the{' '}
22
+ <Text
23
+ onPress={() => Linking.openURL('https://nativewindui.com')}
24
+ variant="subhead"
25
+ className="text-primary">
23
26
  NativeWindUI
24
27
  </Text>
25
- <Link href={'https://nativewindui.com/'}>
26
- <Text className='text-primary'>https://nativewindui.com/</Text>
27
- </Link>
28
- </View>
28
+ {' website.'}
29
+ </Text>
29
30
  </View>
30
31
  </>
31
32
  );
@@ -6,5 +6,5 @@ export function ActivityIndicator(
6
6
  props: React.ComponentPropsWithoutRef<typeof RNActivityIndicator>
7
7
  ) {
8
8
  const { colors } = useColorScheme();
9
- return <RNActivityIndicator color={colors.blue} {...props} />;
9
+ return <RNActivityIndicator color={colors.primary} {...props} />;
10
10
  }
@@ -4,7 +4,7 @@ import DateTimePicker, {
4
4
  import * as React from 'react';
5
5
  import { Pressable, View } from 'react-native';
6
6
 
7
- import { Text } from '~/components/Text';
7
+ import { Text } from '~/components/nativewind-ui/Text';
8
8
 
9
9
  export function DatePicker(
10
10
  props: React.ComponentProps<typeof DateTimePicker> & {
@@ -14,12 +14,12 @@ export function Slider({
14
14
  return (
15
15
  <RNSlider
16
16
  thumbTintColor={
17
- thumbTintColor ?? Platform.OS === 'ios' ? COLORS.white : colors.blue
17
+ thumbTintColor ?? Platform.OS === 'ios' ? COLORS.white : colors.primary
18
18
  }
19
- minimumTrackTintColor={minimumTrackTintColor ?? colors.blue}
19
+ minimumTrackTintColor={minimumTrackTintColor ?? colors.primary}
20
20
  maximumTrackTintColor={
21
21
  maximumTrackTintColor ?? Platform.OS === 'android'
22
- ? colors.blue
22
+ ? colors.primary
23
23
  : undefined
24
24
  }
25
25
  {...props}
@@ -1,11 +1,17 @@
1
1
  import { VariantProps, cva } from 'class-variance-authority';
2
- import { cssInterop } from 'nativewind';
3
2
  import * as React from 'react';
3
+ <% if (props.stylingPackage?.options.selectedComponents.includes('selectable-text')) { %>
4
4
  import { UITextView } from 'react-native-uitextview';
5
+ import { cssInterop } from 'nativewind';
6
+ <% } else { %>
7
+ import { Text as RNText } from 'react-native';
8
+ <% } %>
5
9
 
6
10
  import { cn } from '~/lib/cn';
7
11
 
12
+ <% if (props.stylingPackage?.options.selectedComponents.includes('selectable-text')) { %>
8
13
  cssInterop(UITextView, { className: 'style' });
14
+ <% } %>
9
15
 
10
16
  const textVariants = cva('text-foreground', {
11
17
  variants: {
@@ -37,6 +43,7 @@ const textVariants = cva('text-foreground', {
37
43
 
38
44
  const TextClassContext = React.createContext<string | undefined>(undefined);
39
45
 
46
+ <% if (props.stylingPackage?.options.selectedComponents.includes('selectable-text')) { %>
40
47
  function Text({
41
48
  className,
42
49
  variant,
@@ -51,5 +58,22 @@ function Text({
51
58
  />
52
59
  );
53
60
  }
61
+ <% } else { %>
62
+ function Text({
63
+ className,
64
+ variant,
65
+ color,
66
+ ...props
67
+ }: React.ComponentPropsWithoutRef<typeof RNText> & VariantProps<typeof textVariants>) {
68
+ const textClassName = React.useContext(TextClassContext);
69
+ return (
70
+ <RNText
71
+ className={cn(textVariants({ variant, color }), textClassName, className)}
72
+ {...props}
73
+ />
74
+ );
75
+ }
76
+ <% } %>
77
+
54
78
 
55
79
  export { Text, TextClassContext, textVariants };
@@ -1,5 +1,5 @@
1
1
  import { Icon } from '@roninoss/icons';
2
- import { Appearance, Pressable, View } from 'react-native';
2
+ import { Pressable, View } from 'react-native';
3
3
  import Animated, { LayoutAnimationConfig, ZoomInRotate } from 'react-native-reanimated';
4
4
 
5
5
  import { cn } from '~/lib/cn';
@@ -7,7 +7,7 @@ import { useColorScheme } from '~/lib/useColorScheme';
7
7
  import { COLORS } from '~/theme/colors';
8
8
 
9
9
  export function ThemeToggle() {
10
- const { colorScheme, toggleColorScheme } = useColorScheme();
10
+ const { colorScheme, setColorScheme } = useColorScheme();
11
11
  return (
12
12
  <LayoutAnimationConfig skipEntering>
13
13
  <Animated.View
@@ -16,9 +16,7 @@ export function ThemeToggle() {
16
16
  entering={ZoomInRotate}>
17
17
  <Pressable
18
18
  onPress={() => {
19
- // ColorScheme is set with `Appearance` as well for the iOS header search placeholder text: https://github.com/software-mansion/react-native-screens/discussions/1758
20
- Appearance.setColorScheme(colorScheme === 'dark' ? 'light' : 'dark');
21
- toggleColorScheme();
19
+ setColorScheme(colorScheme === 'dark' ? 'light' : 'dark');
22
20
  }}
23
21
  className="opacity-80">
24
22
  {colorScheme === 'dark'