@mr.dj2u/library-registry 0.0.0

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.
Files changed (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -0
  3. package/THIRD_PARTY_NOTICES.md +90 -0
  4. package/assets/create-expo-app/sdk-56/assets/images/expo-badge-white.png +0 -0
  5. package/assets/create-expo-app/sdk-56/assets/images/expo-badge.png +0 -0
  6. package/assets/create-expo-app/sdk-56/assets/images/expo-logo.png +0 -0
  7. package/assets/create-expo-app/sdk-56/assets/images/logo-glow.png +0 -0
  8. package/assets/create-expo-app/sdk-56/assets/images/react-logo.png +0 -0
  9. package/assets/create-expo-app/sdk-56/assets/images/react-logo@2x.png +0 -0
  10. package/assets/create-expo-app/sdk-56/assets/images/react-logo@3x.png +0 -0
  11. package/assets/create-expo-app/sdk-56/assets/images/tabIcons/explore.png +0 -0
  12. package/assets/create-expo-app/sdk-56/assets/images/tabIcons/explore@2x.png +0 -0
  13. package/assets/create-expo-app/sdk-56/assets/images/tabIcons/explore@3x.png +0 -0
  14. package/assets/create-expo-app/sdk-56/assets/images/tabIcons/home.png +0 -0
  15. package/assets/create-expo-app/sdk-56/assets/images/tabIcons/home@2x.png +0 -0
  16. package/assets/create-expo-app/sdk-56/assets/images/tabIcons/home@3x.png +0 -0
  17. package/assets/create-expo-app/sdk-56/assets/images/tutorial-web.png +0 -0
  18. package/assets/create-expo-app/sdk-56/src/app/_layout.tsx +15 -0
  19. package/assets/create-expo-app/sdk-56/src/app/explore.tsx +180 -0
  20. package/assets/create-expo-app/sdk-56/src/app/index.tsx +98 -0
  21. package/assets/create-expo-app/sdk-56/src/components/animated-icon.module.css +6 -0
  22. package/assets/create-expo-app/sdk-56/src/components/animated-icon.tsx +132 -0
  23. package/assets/create-expo-app/sdk-56/src/components/animated-icon.web.tsx +108 -0
  24. package/assets/create-expo-app/sdk-56/src/components/app-tabs.tsx +32 -0
  25. package/assets/create-expo-app/sdk-56/src/components/app-tabs.web.tsx +115 -0
  26. package/assets/create-expo-app/sdk-56/src/components/external-link.tsx +25 -0
  27. package/assets/create-expo-app/sdk-56/src/components/hint-row.tsx +35 -0
  28. package/assets/create-expo-app/sdk-56/src/components/themed-text.tsx +73 -0
  29. package/assets/create-expo-app/sdk-56/src/components/themed-view.tsx +16 -0
  30. package/assets/create-expo-app/sdk-56/src/components/ui/collapsible.tsx +65 -0
  31. package/assets/create-expo-app/sdk-56/src/components/web-badge.tsx +43 -0
  32. package/assets/create-expo-app/sdk-56/src/constants/theme.ts +65 -0
  33. package/assets/create-expo-app/sdk-56/src/global.css +9 -0
  34. package/assets/create-expo-app/sdk-56/src/hooks/use-color-scheme.ts +1 -0
  35. package/assets/create-expo-app/sdk-56/src/hooks/use-color-scheme.web.ts +21 -0
  36. package/assets/create-expo-app/sdk-56/src/hooks/use-theme.ts +14 -0
  37. package/assets/create-expo-stack/2.21.3/base/components/BackButton.tsx +23 -0
  38. package/assets/create-expo-stack/2.21.3/base/components/Button.tsx +42 -0
  39. package/assets/create-expo-stack/2.21.3/base/components/Container.tsx +14 -0
  40. package/assets/create-expo-stack/2.21.3/base/components/EditScreenInfo.tsx +36 -0
  41. package/assets/create-expo-stack/2.21.3/base/components/HeaderButton.tsx +31 -0
  42. package/assets/create-expo-stack/2.21.3/base/components/ScreenContent.tsx +40 -0
  43. package/assets/create-expo-stack/2.21.3/base/components/TabBarIcon.tsx +15 -0
  44. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/ActivityIndicator.tsx +10 -0
  45. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Avatar.tsx +32 -0
  46. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Button.tsx +141 -0
  47. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/DatePicker/DatePicker.android.tsx +77 -0
  48. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/DatePicker/DatePicker.tsx +23 -0
  49. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/DatePicker/index.ts +1 -0
  50. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Icon/Icon.ios.tsx +55 -0
  51. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Icon/Icon.tsx +58 -0
  52. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Icon/index.ts +16 -0
  53. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Icon/types.ts +19 -0
  54. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Picker.tsx +42 -0
  55. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/ProgressIndicator.tsx +68 -0
  56. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Slider.tsx +28 -0
  57. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Text.tsx +55 -0
  58. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/ThemeToggle.tsx +33 -0
  59. package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Toggle.tsx +20 -0
  60. package/assets/create-expo-stack/2.21.3-mrdj.2/src/lib/cn.ts +6 -0
  61. package/assets/create-expo-stack/2.21.3-mrdj.2/src/lib/useColorScheme.tsx +21 -0
  62. package/assets/create-expo-stack/2.21.3-mrdj.2/src/lib/useHeaderSearchBar.tsx +33 -0
  63. package/assets/create-expo-stack/2.21.3-mrdj.2/src/theme/colors.ts +123 -0
  64. package/assets/create-expo-stack/2.21.3-mrdj.2/src/theme/index.ts +32 -0
  65. package/assets/create-expo-stack/2.21.3-mrdj.2/src/theme/with-opacity.ts +155 -0
  66. package/assets/mds/routes/drawer-tabs/data.tsx +1 -0
  67. package/assets/mds/routes/drawer-tabs/index.tsx +1 -0
  68. package/assets/mds/routes/drawer-tabs/nativewindui.tsx +1 -0
  69. package/assets/mds/routes/drawer-tabs/sdk-56.tsx +1 -0
  70. package/assets/mds/routes/drawer-tabs/stylist.tsx +1 -0
  71. package/assets/mds/scripts/stylist-sync-android.mjs +39 -0
  72. package/assets/mds/src/app/exposition/data.tsx +1 -0
  73. package/assets/mds/src/app/exposition/index.tsx +1 -0
  74. package/assets/mds/src/app/exposition/nativewindui.tsx +1 -0
  75. package/assets/mds/src/app/exposition/sdk-56.tsx +1 -0
  76. package/assets/mds/src/app/exposition/stylist-sync+api.ts +241 -0
  77. package/assets/mds/src/app/exposition/stylist.tsx +1 -0
  78. package/assets/mds/src/app/onboarding/account-setup.tsx +1 -0
  79. package/assets/mds/src/app/onboarding/agreement.tsx +1 -0
  80. package/assets/mds/src/app/onboarding/terms.tsx +1 -0
  81. package/assets/mds/src/app/onboarding.tsx +1 -0
  82. package/assets/mds/src/app/settings.tsx +1 -0
  83. package/assets/mds/src/components/exposition/index.ts +8 -0
  84. package/assets/mds/src/components/exposition/notice.tsx +3 -0
  85. package/assets/mds/src/components/exposition/package-card.tsx +76 -0
  86. package/assets/mds/src/components/swmansion/animated-pressable.tsx +54 -0
  87. package/assets/mds/src/components/swmansion/gesture-card.tsx +54 -0
  88. package/assets/mds/src/components/swmansion/keyboard-form.tsx +73 -0
  89. package/assets/mds/src/components/swmansion/screens-card.tsx +40 -0
  90. package/assets/mds/src/components/swmansion/software-mansion-logo.tsx +15 -0
  91. package/assets/mds/src/components/swmansion/svg-mark.tsx +16 -0
  92. package/assets/mds/src/data/mock-app.ts +21 -0
  93. package/assets/mds/src/features/exposition/data-screen.tsx +152 -0
  94. package/assets/mds/src/features/exposition/embedded-fonts.ts +72 -0
  95. package/assets/mds/src/features/exposition/expo-sdk-56-screen.tsx +709 -0
  96. package/assets/mds/src/features/exposition/exposition-screen.tsx +191 -0
  97. package/assets/mds/src/features/exposition/nativewindui-screen.tsx +125 -0
  98. package/assets/mds/src/features/exposition/stylist-screen.tsx +3456 -0
  99. package/assets/mds/src/features/onboarding/account-setup-screen.tsx +54 -0
  100. package/assets/mds/src/features/onboarding/agreement-screen.tsx +6 -0
  101. package/assets/mds/src/features/onboarding/components/legal-document-view.tsx +103 -0
  102. package/assets/mds/src/features/onboarding/legal-documents.ts +80 -0
  103. package/assets/mds/src/features/onboarding/onboarding-screen.tsx +167 -0
  104. package/assets/mds/src/features/onboarding/terms-screen.tsx +6 -0
  105. package/assets/mds/src/features/settings/settings-screen.tsx +57 -0
  106. package/assets/mds/src/services/local-data.native.ts +103 -0
  107. package/assets/mds/src/services/local-data.ts +38 -0
  108. package/assets/mds/src/theme/font-assets.ts +3 -0
  109. package/assets/mds/src/theme/provider.tsx +59 -0
  110. package/assets/mds/src/theme/tokens.ts +180 -0
  111. package/dist/catalog.d.ts +3 -0
  112. package/dist/catalog.d.ts.map +1 -0
  113. package/dist/catalog.js +1110 -0
  114. package/dist/catalog.js.map +1 -0
  115. package/dist/index.d.ts +5 -0
  116. package/dist/index.d.ts.map +1 -0
  117. package/dist/index.js +4 -0
  118. package/dist/index.js.map +1 -0
  119. package/dist/registry.d.ts +7 -0
  120. package/dist/registry.d.ts.map +1 -0
  121. package/dist/registry.js +479 -0
  122. package/dist/registry.js.map +1 -0
  123. package/dist/types.d.ts +169 -0
  124. package/dist/types.d.ts.map +1 -0
  125. package/dist/types.js +2 -0
  126. package/dist/types.js.map +1 -0
  127. package/dist/validation.d.ts +6 -0
  128. package/dist/validation.d.ts.map +1 -0
  129. package/dist/validation.js +209 -0
  130. package/dist/validation.js.map +1 -0
  131. package/package.json +51 -0
@@ -0,0 +1,42 @@
1
+ import { forwardRef } from 'react';
2
+ import { StyleSheet, Text, TouchableOpacity, TouchableOpacityProps, View } from 'react-native';
3
+
4
+ type ButtonProps = {
5
+ title?: string;
6
+ } & TouchableOpacityProps;
7
+
8
+ export const Button = forwardRef<View, ButtonProps>(({ title, ...touchableProps }, ref) => {
9
+ return (
10
+ <TouchableOpacity ref={ref} {...touchableProps} style={[styles.button, touchableProps.style]}>
11
+ <Text style={styles.buttonText}>{title}</Text>
12
+ </TouchableOpacity>
13
+ );
14
+ });
15
+
16
+ Button.displayName = 'Button';
17
+
18
+ const styles = StyleSheet.create({
19
+ button: {
20
+ alignItems: 'center',
21
+ backgroundColor: '#6366F1',
22
+ borderRadius: 24,
23
+ elevation: 5,
24
+ flexDirection: 'row',
25
+ justifyContent: 'center',
26
+ marginHorizontal: 16,
27
+ padding: 16,
28
+ shadowColor: '#000',
29
+ shadowOffset: {
30
+ height: 2,
31
+ width: 0,
32
+ },
33
+ shadowOpacity: 0.25,
34
+ shadowRadius: 3.84,
35
+ },
36
+ buttonText: {
37
+ color: '#FFFFFF',
38
+ fontSize: 16,
39
+ fontWeight: '600',
40
+ textAlign: 'center',
41
+ },
42
+ });
@@ -0,0 +1,14 @@
1
+ import { StyleSheet, SafeAreaView } from 'react-native';
2
+
3
+ export const Container = ({ children }: { children: React.ReactNode }) => {
4
+ return <SafeAreaView style={styles.container}>{children}</SafeAreaView>;
5
+ };
6
+
7
+ const styles = StyleSheet.create({
8
+ container: {
9
+ flex: 1,
10
+ padding: 24,
11
+ backgroundColor: 'white',
12
+ },
13
+ });
14
+
@@ -0,0 +1,36 @@
1
+ import { StyleSheet, Text, View } from 'react-native';
2
+
3
+ export default function EditScreenInfo({ path }: { path: string }) {
4
+ const title = 'Open up the code for this screen:';
5
+ const description =
6
+ 'Change any of the text, save the file, and your app will automatically update.';
7
+
8
+ return (
9
+ <View style={styles.getStartedContainer}>
10
+ <Text style={styles.getStartedText}>{title}</Text>
11
+ <View style={[styles.codeHighlightContainer, styles.homeScreenFilename]}>
12
+ <Text>{path}</Text>
13
+ </View>
14
+ <Text style={styles.getStartedText}>{description}</Text>
15
+ </View>
16
+ );
17
+ }
18
+
19
+ const styles = StyleSheet.create({
20
+ codeHighlightContainer: {
21
+ borderRadius: 3,
22
+ paddingHorizontal: 4,
23
+ },
24
+ getStartedContainer: {
25
+ alignItems: 'center',
26
+ marginHorizontal: 50,
27
+ },
28
+ getStartedText: {
29
+ fontSize: 17,
30
+ lineHeight: 24,
31
+ textAlign: 'center',
32
+ },
33
+ homeScreenFilename: {
34
+ marginVertical: 7,
35
+ },
36
+ });
@@ -0,0 +1,31 @@
1
+ import { forwardRef } from 'react';
2
+ import FontAwesome from '@expo/vector-icons/FontAwesome';
3
+ import { Pressable, StyleSheet } from 'react-native';
4
+
5
+ export const HeaderButton = forwardRef<typeof Pressable, { onPress?: () => void; }>(({ onPress }, ref) => {
6
+ return (
7
+ <Pressable onPress={onPress}>
8
+ {({ pressed }) => (
9
+ <FontAwesome
10
+ name="info-circle"
11
+ size={25}
12
+ color="gray"
13
+ style={[
14
+ styles.headerRight,
15
+ {
16
+ opacity: pressed ? 0.5 : 1,
17
+ },
18
+ ]}
19
+ />
20
+ )}
21
+ </Pressable>
22
+ );
23
+ });
24
+
25
+ HeaderButton.displayName = 'HeaderButton';
26
+
27
+ export const styles = StyleSheet.create({
28
+ headerRight: {
29
+ marginRight: 15,
30
+ },
31
+ });
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import { StyleSheet, Text, View } from 'react-native';
3
+
4
+ import EditScreenInfo from './EditScreenInfo';
5
+
6
+ type ScreenContentProps = {
7
+ title: string;
8
+ path: string;
9
+ children?: React.ReactNode;
10
+ };
11
+
12
+ export const ScreenContent = ({ title, path, children }: ScreenContentProps) => {
13
+ return (
14
+ <View style={styles.container}>
15
+ <Text style={styles.title}>{title}</Text>
16
+ <View style={styles.separator} />
17
+ <EditScreenInfo path={path} />
18
+ {children}
19
+ </View>
20
+ );
21
+ };
22
+
23
+ const styles = StyleSheet.create({
24
+ container: {
25
+ alignItems: 'center',
26
+ backgroundColor: 'white',
27
+ flex: 1,
28
+ justifyContent: 'center',
29
+ },
30
+ separator: {
31
+ backgroundColor: '#d1d5db',
32
+ height: 1,
33
+ marginVertical: 30,
34
+ width: '80%',
35
+ },
36
+ title: {
37
+ fontSize: 20,
38
+ fontWeight: 'bold',
39
+ },
40
+ });
@@ -0,0 +1,15 @@
1
+ import FontAwesome from '@expo/vector-icons/FontAwesome';
2
+ import { StyleSheet } from 'react-native';
3
+
4
+ export const TabBarIcon = (props: {
5
+ name: React.ComponentProps<typeof FontAwesome>['name'];
6
+ color: string;
7
+ }) => {
8
+ return <FontAwesome size={28} style={styles.tabBarIcon} {...props} />;
9
+ };
10
+
11
+ export const styles = StyleSheet.create({
12
+ tabBarIcon: {
13
+ marginBottom: -3,
14
+ },
15
+ });
@@ -0,0 +1,10 @@
1
+ import { ActivityIndicator as RNActivityIndicator } from 'react-native';
2
+
3
+ import { useColorScheme } from '@/lib/useColorScheme';
4
+
5
+ function ActivityIndicator(props: React.ComponentProps<typeof RNActivityIndicator>) {
6
+ const { colors } = useColorScheme();
7
+ return <RNActivityIndicator color={colors.primary} {...props} />;
8
+ }
9
+
10
+ export { ActivityIndicator };
@@ -0,0 +1,32 @@
1
+ import * as AvatarPrimitive from '@rn-primitives/avatar';
2
+
3
+ import { cn } from '@/lib/cn';
4
+
5
+ function Avatar({ className, ...props }: AvatarPrimitive.RootProps) {
6
+ return (
7
+ <AvatarPrimitive.Root
8
+ className={cn('relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full', className)}
9
+ {...props}
10
+ />
11
+ );
12
+ }
13
+
14
+ function AvatarImage({ className, ...props }: AvatarPrimitive.ImageProps) {
15
+ return (
16
+ <AvatarPrimitive.Image className={cn('aspect-square h-full w-full', className)} {...props} />
17
+ );
18
+ }
19
+
20
+ function AvatarFallback({ className, ...props }: AvatarPrimitive.FallbackProps) {
21
+ return (
22
+ <AvatarPrimitive.Fallback
23
+ className={cn(
24
+ 'flex h-full w-full items-center justify-center rounded-full bg-muted',
25
+ className
26
+ )}
27
+ {...props}
28
+ />
29
+ );
30
+ }
31
+
32
+ export { Avatar, AvatarFallback, AvatarImage };
@@ -0,0 +1,141 @@
1
+ import * as Slot from '@rn-primitives/slot';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+ import { Platform, Pressable, PressableProps, View, ViewStyle } from 'react-native';
4
+
5
+ import { TextClassContext } from '@/components/nativewindui/Text';
6
+ import { cn } from '@/lib/cn';
7
+ import { useColorScheme } from '@/lib/useColorScheme';
8
+ import { COLORS } from '@/theme/colors';
9
+ import { withOpacity } from '@/theme/with-opacity';
10
+
11
+ const buttonVariants = cva('flex-row items-center justify-center gap-2', {
12
+ variants: {
13
+ variant: {
14
+ primary: 'ios:active:opacity-80 bg-primary',
15
+ secondary: 'ios:border-primary ios:active:bg-primary/5 border border-foreground/40',
16
+ tonal:
17
+ 'ios:bg-primary/10 dark:ios:bg-primary/10 ios:active:bg-primary/15 bg-primary/15 dark:bg-primary/30',
18
+ plain: 'ios:active:opacity-70',
19
+ },
20
+ size: {
21
+ none: '',
22
+ sm: 'py-1 px-2.5 rounded-full',
23
+ md: 'ios:rounded-lg py-2 ios:py-1.5 ios:px-3.5 px-5 rounded-full',
24
+ lg: 'py-2.5 px-5 ios:py-2 rounded-xl gap-2',
25
+ icon: 'ios:rounded-lg h-10 w-10 rounded-full',
26
+ },
27
+ },
28
+ defaultVariants: {
29
+ variant: 'primary',
30
+ size: 'md',
31
+ },
32
+ });
33
+
34
+ const androidRootVariants = cva('overflow-hidden', {
35
+ variants: {
36
+ size: {
37
+ none: '',
38
+ icon: 'rounded-full',
39
+ sm: 'rounded-full',
40
+ md: 'rounded-full',
41
+ lg: 'rounded-xl',
42
+ },
43
+ },
44
+ defaultVariants: {
45
+ size: 'md',
46
+ },
47
+ });
48
+
49
+ const buttonTextVariants = cva('font-medium', {
50
+ variants: {
51
+ variant: {
52
+ primary: 'text-white',
53
+ secondary: 'ios:text-primary text-foreground',
54
+ tonal: 'ios:text-primary text-foreground',
55
+ plain: 'text-foreground',
56
+ },
57
+ size: {
58
+ none: '',
59
+ icon: '',
60
+ sm: 'text-[15px] leading-5',
61
+ md: 'text-[17px] leading-7',
62
+ lg: 'text-[17px] leading-7',
63
+ },
64
+ },
65
+ defaultVariants: {
66
+ variant: 'primary',
67
+ size: 'md',
68
+ },
69
+ });
70
+
71
+ const ANDROID_RIPPLE = {
72
+ dark: {
73
+ primary: { color: withOpacity(COLORS.dark.grey3, 0.4), borderless: false },
74
+ secondary: { color: withOpacity(COLORS.dark.grey5, 0.8), borderless: false },
75
+ plain: { color: withOpacity(COLORS.dark.grey5, 0.8), borderless: false },
76
+ tonal: { color: withOpacity(COLORS.dark.grey5, 0.8), borderless: false },
77
+ },
78
+ light: {
79
+ primary: { color: withOpacity(COLORS.light.grey4, 0.4), borderless: false },
80
+ secondary: { color: withOpacity(COLORS.light.grey5, 0.4), borderless: false },
81
+ plain: { color: withOpacity(COLORS.light.grey5, 0.4), borderless: false },
82
+ tonal: { color: withOpacity(COLORS.light.grey6, 0.4), borderless: false },
83
+ },
84
+ };
85
+
86
+ // Add as class when possible: https://github.com/marklawlor/nativewind/issues/522
87
+ const BORDER_CURVE: ViewStyle = {
88
+ borderCurve: 'continuous',
89
+ };
90
+
91
+ type ButtonVariantProps = Omit<VariantProps<typeof buttonVariants>, 'variant'> & {
92
+ variant?: Exclude<VariantProps<typeof buttonVariants>['variant'], null>;
93
+ };
94
+
95
+ type AndroidOnlyButtonProps = {
96
+ /**
97
+ * ANDROID ONLY: The class name of root responsible for hidding the ripple overflow.
98
+ */
99
+ androidRootClassName?: string;
100
+ };
101
+
102
+ type ButtonProps = PressableProps & ButtonVariantProps & AndroidOnlyButtonProps;
103
+
104
+ const Root = Platform.OS === 'android' ? View : Slot.Pressable;
105
+
106
+ function Button({
107
+ className,
108
+ variant = 'primary',
109
+ size,
110
+ style = BORDER_CURVE,
111
+ androidRootClassName,
112
+ ...props
113
+ }: ButtonProps) {
114
+ const { colorScheme } = useColorScheme();
115
+
116
+ return (
117
+ <TextClassContext.Provider value={buttonTextVariants({ variant, size })}>
118
+ <Root
119
+ className={Platform.select({
120
+ ios: undefined,
121
+ default: androidRootVariants({
122
+ size,
123
+ className: androidRootClassName,
124
+ }),
125
+ })}>
126
+ <Pressable
127
+ className={cn(
128
+ props.disabled && 'opacity-50',
129
+ buttonVariants({ variant, size, className })
130
+ )}
131
+ style={style}
132
+ android_ripple={ANDROID_RIPPLE[colorScheme][variant]}
133
+ {...props}
134
+ />
135
+ </Root>
136
+ </TextClassContext.Provider>
137
+ );
138
+ }
139
+
140
+ export { Button, buttonTextVariants, buttonVariants };
141
+ export type { ButtonProps };
@@ -0,0 +1,77 @@
1
+ import DateTimePicker, { DateTimePickerAndroid } from '@react-native-community/datetimepicker';
2
+ import * as React from 'react';
3
+ import { View } from 'react-native';
4
+
5
+ import { Button } from '@/components/nativewindui/Button';
6
+ import { Text } from '@/components/nativewindui/Text';
7
+ import { cn } from '@/lib/cn';
8
+
9
+ export function DatePicker(
10
+ props: React.ComponentProps<typeof DateTimePicker> & {
11
+ mode: 'date' | 'time' | 'datetime';
12
+ } & {
13
+ materialDateClassName?: string;
14
+ materialDateLabel?: string;
15
+ materialDateLabelClassName?: string;
16
+ materialTimeClassName?: string;
17
+ materialTimeLabel?: string;
18
+ materialTimeLabelClassName?: string;
19
+ }
20
+ ) {
21
+ const show = (currentMode: 'time' | 'date') => () => {
22
+ DateTimePickerAndroid.open({
23
+ value: props.value,
24
+ onChange: props.onChange,
25
+ mode: currentMode,
26
+ minimumDate: props.minimumDate,
27
+ maximumDate: props.maximumDate,
28
+ });
29
+ };
30
+
31
+ return (
32
+ <View className="flex-row gap-2.5">
33
+ {props.mode.includes('date') && (
34
+ <View className={cn('relative pt-1.5', props.materialDateClassName)}>
35
+ <Button
36
+ variant="plain"
37
+ androidRootClassName="rounded-none"
38
+ onPress={show('date')}
39
+ className="border-foreground/30 rounded border px-2.5 py-3 active:opacity-80">
40
+ <Text className="py-px text-sm">
41
+ {new Intl.DateTimeFormat('en-US', {
42
+ dateStyle: 'medium',
43
+ }).format(props.value)}
44
+ </Text>
45
+ </Button>
46
+ <View
47
+ className={cn('absolute left-2 top-0 bg-card px-1', props.materialDateLabelClassName)}>
48
+ <Text variant="caption2" className="text-[10px] opacity-60">
49
+ {props.materialDateLabel ?? 'Date'}
50
+ </Text>
51
+ </View>
52
+ </View>
53
+ )}
54
+ {props.mode.includes('time') && (
55
+ <View className={cn('relative pt-1.5', props.materialTimeClassName)}>
56
+ <Button
57
+ variant="plain"
58
+ androidRootClassName="rounded-none"
59
+ onPress={show('time')}
60
+ className="border-foreground/30 rounded border px-2.5 py-3 active:opacity-80">
61
+ <Text className="py-px text-sm">
62
+ {new Intl.DateTimeFormat('en-US', {
63
+ timeStyle: 'short',
64
+ }).format(props.value)}
65
+ </Text>
66
+ </Button>
67
+ <View
68
+ className={cn('absolute left-2 top-0 bg-card px-1', props.materialTimeLabelClassName)}>
69
+ <Text variant="caption2" className="text-[10px] opacity-60">
70
+ {props.materialTimeLabel ?? 'Time'}
71
+ </Text>
72
+ </View>
73
+ </View>
74
+ )}
75
+ </View>
76
+ );
77
+ }
@@ -0,0 +1,23 @@
1
+ import DateTimePicker from '@react-native-community/datetimepicker';
2
+ import * as React from 'react';
3
+
4
+ export function DatePicker({
5
+ materialDateClassName: _materialDateClassName,
6
+ materialDateLabel: _materialDateLabel,
7
+ materialDateLabelClassName: _materialDateLabelClassName,
8
+ materialTimeClassName: _materialTimeClassName,
9
+ materialTimeLabel: _materialTimeLabel,
10
+ materialTimeLabelClassName: _materialTimeLabelClassName,
11
+ ...props
12
+ }: React.ComponentProps<typeof DateTimePicker> & {
13
+ mode: 'date' | 'time' | 'datetime';
14
+ } & {
15
+ materialDateClassName?: string;
16
+ materialDateLabel?: string;
17
+ materialDateLabelClassName?: string;
18
+ materialTimeClassName?: string;
19
+ materialTimeLabel?: string;
20
+ materialTimeLabelClassName?: string;
21
+ }) {
22
+ return <DateTimePicker {...props} />;
23
+ }
@@ -0,0 +1,55 @@
1
+ import { SymbolView } from 'expo-symbols';
2
+ import type { ComponentProps } from 'react';
3
+
4
+ import type { IconProps } from './types';
5
+
6
+ import { useColorScheme } from '@/lib/useColorScheme';
7
+
8
+ function Icon({
9
+ materialCommunityIcon: _materialCommunityIcon,
10
+ materialIcon: _materialIcon,
11
+ sfSymbol,
12
+ name,
13
+ color,
14
+ size = 24,
15
+ ...props
16
+ }: IconProps) {
17
+ const { colors } = useColorScheme();
18
+ const symbolName = (name ?? 'questionmark') as ComponentProps<typeof SymbolView>['name'];
19
+
20
+ return (
21
+ <SymbolView
22
+ {...props}
23
+ {...sfSymbol}
24
+ name={symbolName}
25
+ tintColor={rgbaToHex(color ?? colors.foreground)}
26
+ size={size}
27
+ resizeMode="scaleAspectFit"
28
+ />
29
+ );
30
+ }
31
+
32
+ export { Icon };
33
+
34
+ // TODO: seems like the need to convert rgba to hex color is a bug in expo-symbols, accordion to the docs, it should accept a hex color, but it doesn't.
35
+
36
+ function rgbaToHex(color: string): string {
37
+ if (!color) return 'black';
38
+ const rgbaRegex =
39
+ /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(\d*\.?\d+))?\s*\)$/i;
40
+ const match = color.match(rgbaRegex);
41
+
42
+ if (!match) {
43
+ return color;
44
+ }
45
+
46
+ const [, rStr, gStr, bStr, aStr] = match;
47
+ const r = Math.min(255, parseInt(rStr));
48
+ const g = Math.min(255, parseInt(gStr));
49
+ const b = Math.min(255, parseInt(bStr));
50
+ const a = aStr !== undefined ? Math.round(parseFloat(aStr) * 255) : 255;
51
+
52
+ const toHex = (n: number) => n.toString(16).padStart(2, '0');
53
+
54
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}${a < 255 ? toHex(a) : ''}`;
55
+ }
@@ -0,0 +1,58 @@
1
+ import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
2
+ import MaterialIcons from '@expo/vector-icons/MaterialIcons';
3
+ import {
4
+ SF_SYMBOLS_TO_MATERIAL_COMMUNITY_ICONS,
5
+ SF_SYMBOLS_TO_MATERIAL_ICONS,
6
+ } from 'rn-icon-mapper';
7
+
8
+ import type { IconProps } from './types';
9
+
10
+ import { useColorScheme } from '@/lib/useColorScheme';
11
+
12
+ function Icon({
13
+ name,
14
+ materialCommunityIcon,
15
+ materialIcon,
16
+ sfSymbol: _sfSymbol,
17
+ size = 24,
18
+ ...props
19
+ }: IconProps) {
20
+ const { colors } = useColorScheme();
21
+ const defaultColor = colors.foreground;
22
+
23
+ if (materialCommunityIcon) {
24
+ return (
25
+ <MaterialCommunityIcons
26
+ size={size}
27
+ color={defaultColor}
28
+ {...props}
29
+ {...materialCommunityIcon}
30
+ />
31
+ );
32
+ }
33
+ if (materialIcon) {
34
+ return <MaterialIcons size={size} color={defaultColor} {...props} {...materialIcon} />;
35
+ }
36
+ const materialCommunityIconName =
37
+ SF_SYMBOLS_TO_MATERIAL_COMMUNITY_ICONS[
38
+ name as keyof typeof SF_SYMBOLS_TO_MATERIAL_COMMUNITY_ICONS
39
+ ];
40
+ if (materialCommunityIconName) {
41
+ return (
42
+ <MaterialCommunityIcons
43
+ name={materialCommunityIconName}
44
+ size={size}
45
+ color={defaultColor}
46
+ {...props}
47
+ />
48
+ );
49
+ }
50
+ const materialIconName =
51
+ SF_SYMBOLS_TO_MATERIAL_ICONS[name as keyof typeof SF_SYMBOLS_TO_MATERIAL_ICONS];
52
+ if (materialIconName) {
53
+ return <MaterialIcons name={materialIconName} size={size} color={defaultColor} {...props} />;
54
+ }
55
+ return <MaterialCommunityIcons name="help" size={size} color={defaultColor} {...props} />;
56
+ }
57
+
58
+ export { Icon };
@@ -0,0 +1,16 @@
1
+ import { cssInterop } from 'nativewind';
2
+
3
+ import { Icon } from './Icon';
4
+
5
+ cssInterop(Icon, {
6
+ className: {
7
+ target: 'style',
8
+ nativeStyleToProp: {
9
+ color: 'color',
10
+ height: 'size',
11
+ width: 'size',
12
+ },
13
+ },
14
+ });
15
+
16
+ export { Icon };
@@ -0,0 +1,19 @@
1
+ import type MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
2
+ import type MaterialIcons from '@expo/vector-icons/MaterialIcons';
3
+ import type { SymbolViewProps } from 'expo-symbols';
4
+ import type { IconMapper } from 'rn-icon-mapper';
5
+
6
+ type MaterialCommunityIconsProps = React.ComponentProps<typeof MaterialCommunityIcons>;
7
+ type MaterialIconsProps = React.ComponentProps<typeof MaterialIcons>;
8
+ type SymbolIconProps = Omit<SymbolViewProps, 'name'> & { name: string };
9
+
10
+ type Style = SymbolIconProps['style'] &
11
+ MaterialIconsProps['style'] &
12
+ MaterialCommunityIconsProps['style'];
13
+
14
+ type IconProps = IconMapper<SymbolIconProps, MaterialIconsProps, MaterialCommunityIconsProps> & {
15
+ style?: Style;
16
+ className?: string;
17
+ };
18
+
19
+ export type { IconProps };
@@ -0,0 +1,42 @@
1
+ import { Picker as RNPicker } from '@react-native-picker/picker';
2
+ import { Platform, View } from 'react-native';
3
+
4
+ import { cn } from '@/lib/cn';
5
+ import { useColorScheme } from '@/lib/useColorScheme';
6
+
7
+ export function Picker<T>({
8
+ mode = 'dropdown',
9
+ style,
10
+ dropdownIconColor,
11
+ dropdownIconRippleColor,
12
+ className,
13
+ ...props
14
+ }: React.ComponentProps<typeof RNPicker<T>>) {
15
+ const { colors } = useColorScheme();
16
+ return (
17
+ <View
18
+ className={cn(
19
+ 'ios:shadow-sm ios:shadow-black/5 rounded-md border border-background bg-background',
20
+ className
21
+ )}>
22
+ <RNPicker
23
+ mode={mode}
24
+ style={
25
+ style ?? {
26
+ backgroundColor: colors.root,
27
+ borderRadius: 8,
28
+ }
29
+ }
30
+ {...(Platform.OS === 'android'
31
+ ? {
32
+ dropdownIconColor: dropdownIconColor ?? colors.foreground,
33
+ dropdownIconRippleColor: dropdownIconRippleColor ?? colors.foreground,
34
+ }
35
+ : {})}
36
+ {...props}
37
+ />
38
+ </View>
39
+ );
40
+ }
41
+
42
+ export const PickerItem = RNPicker.Item;