@campxdev/react-native-blueprint 0.1.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.
- package/LICENSE +20 -0
- package/README.md +358 -0
- package/lib/module/app/_layout.js +23 -0
- package/lib/module/app/_layout.js.map +1 -0
- package/lib/module/assets/icons/weather_icons/drizzle.png +0 -0
- package/lib/module/assets/icons/weather_icons/foggy.png +0 -0
- package/lib/module/assets/icons/weather_icons/freezing_rain.png +0 -0
- package/lib/module/assets/icons/weather_icons/partly_cloudy.png +0 -0
- package/lib/module/assets/icons/weather_icons/rainy.png +0 -0
- package/lib/module/assets/icons/weather_icons/showers.png +0 -0
- package/lib/module/assets/icons/weather_icons/sunny_weather.png +0 -0
- package/lib/module/assets/icons/weather_icons/thunderstorm.png +0 -0
- package/lib/module/assets/icons/weather_icons/thunderstorm_hail.png +0 -0
- package/lib/module/components/theme-config.js +265 -0
- package/lib/module/components/theme-config.js.map +1 -0
- package/lib/module/components/ui/Accordion.js +228 -0
- package/lib/module/components/ui/Accordion.js.map +1 -0
- package/lib/module/components/ui/Alert-Dialog.js +266 -0
- package/lib/module/components/ui/Alert-Dialog.js.map +1 -0
- package/lib/module/components/ui/Alert.js +107 -0
- package/lib/module/components/ui/Alert.js.map +1 -0
- package/lib/module/components/ui/AppBar.js +403 -0
- package/lib/module/components/ui/AppBar.js.map +1 -0
- package/lib/module/components/ui/Aspect-Ratio.js +27 -0
- package/lib/module/components/ui/Aspect-Ratio.js.map +1 -0
- package/lib/module/components/ui/Avatar.js +97 -0
- package/lib/module/components/ui/Avatar.js.map +1 -0
- package/lib/module/components/ui/Badge.js +127 -0
- package/lib/module/components/ui/Badge.js.map +1 -0
- package/lib/module/components/ui/Bottom-Sheet.js +144 -0
- package/lib/module/components/ui/Bottom-Sheet.js.map +1 -0
- package/lib/module/components/ui/Button.js +88 -0
- package/lib/module/components/ui/Button.js.map +1 -0
- package/lib/module/components/ui/Card.js +176 -0
- package/lib/module/components/ui/Card.js.map +1 -0
- package/lib/module/components/ui/Checkbox.js +65 -0
- package/lib/module/components/ui/Checkbox.js.map +1 -0
- package/lib/module/components/ui/Collapsible.js +42 -0
- package/lib/module/components/ui/Collapsible.js.map +1 -0
- package/lib/module/components/ui/Context-Menu.js +287 -0
- package/lib/module/components/ui/Context-Menu.js.map +1 -0
- package/lib/module/components/ui/Custom-Card.js +202 -0
- package/lib/module/components/ui/Custom-Card.js.map +1 -0
- package/lib/module/components/ui/Dialog.js +202 -0
- package/lib/module/components/ui/Dialog.js.map +1 -0
- package/lib/module/components/ui/Dropdown-Menu.js +421 -0
- package/lib/module/components/ui/Dropdown-Menu.js.map +1 -0
- package/lib/module/components/ui/Floating-Action.js +50 -0
- package/lib/module/components/ui/Floating-Action.js.map +1 -0
- package/lib/module/components/ui/Greeting-Card.js +392 -0
- package/lib/module/components/ui/Greeting-Card.js.map +1 -0
- package/lib/module/components/ui/Hover-Card.js +96 -0
- package/lib/module/components/ui/Hover-Card.js.map +1 -0
- package/lib/module/components/ui/Icon.js +73 -0
- package/lib/module/components/ui/Icon.js.map +1 -0
- package/lib/module/components/ui/Input.js +74 -0
- package/lib/module/components/ui/Input.js.map +1 -0
- package/lib/module/components/ui/Label.js +44 -0
- package/lib/module/components/ui/Label.js.map +1 -0
- package/lib/module/components/ui/Menubar.js +375 -0
- package/lib/module/components/ui/Menubar.js.map +1 -0
- package/lib/module/components/ui/Native-Only-Animated-View.js +41 -0
- package/lib/module/components/ui/Native-Only-Animated-View.js.map +1 -0
- package/lib/module/components/ui/NavBar.js +352 -0
- package/lib/module/components/ui/NavBar.js.map +1 -0
- package/lib/module/components/ui/Popover.js +101 -0
- package/lib/module/components/ui/Popover.js.map +1 -0
- package/lib/module/components/ui/Progress.js +124 -0
- package/lib/module/components/ui/Progress.js.map +1 -0
- package/lib/module/components/ui/Radio-Group.js +75 -0
- package/lib/module/components/ui/Radio-Group.js.map +1 -0
- package/lib/module/components/ui/Select.js +269 -0
- package/lib/module/components/ui/Select.js.map +1 -0
- package/lib/module/components/ui/Separator.js +58 -0
- package/lib/module/components/ui/Separator.js.map +1 -0
- package/lib/module/components/ui/SizedBox.js +101 -0
- package/lib/module/components/ui/SizedBox.js.map +1 -0
- package/lib/module/components/ui/Skeleton.js +57 -0
- package/lib/module/components/ui/Skeleton.js.map +1 -0
- package/lib/module/components/ui/Slider.js +169 -0
- package/lib/module/components/ui/Slider.js.map +1 -0
- package/lib/module/components/ui/Switch.js +55 -0
- package/lib/module/components/ui/Switch.js.map +1 -0
- package/lib/module/components/ui/Table.js +150 -0
- package/lib/module/components/ui/Table.js.map +1 -0
- package/lib/module/components/ui/Tabs.js +106 -0
- package/lib/module/components/ui/Tabs.js.map +1 -0
- package/lib/module/components/ui/Text.js +69 -0
- package/lib/module/components/ui/Text.js.map +1 -0
- package/lib/module/components/ui/Textarea.js +88 -0
- package/lib/module/components/ui/Textarea.js.map +1 -0
- package/lib/module/components/ui/Theme-Toggle.js +156 -0
- package/lib/module/components/ui/Theme-Toggle.js.map +1 -0
- package/lib/module/components/ui/Toast.js +101 -0
- package/lib/module/components/ui/Toast.js.map +1 -0
- package/lib/module/components/ui/Toggle-Group.js +129 -0
- package/lib/module/components/ui/Toggle-Group.js.map +1 -0
- package/lib/module/components/ui/Toggle.js +106 -0
- package/lib/module/components/ui/Toggle.js.map +1 -0
- package/lib/module/components/ui/Tooltip.js +106 -0
- package/lib/module/components/ui/Tooltip.js.map +1 -0
- package/lib/module/components/ui/index.js +45 -0
- package/lib/module/components/ui/index.js.map +1 -0
- package/lib/module/index.js +19 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/lib/ThemeProvider.js +173 -0
- package/lib/module/lib/ThemeProvider.js.map +1 -0
- package/lib/module/lib/cornerRadius.js +164 -0
- package/lib/module/lib/cornerRadius.js.map +1 -0
- package/lib/module/lib/fonts.js +25 -0
- package/lib/module/lib/fonts.js.map +1 -0
- package/lib/module/lib/theme.js +212 -0
- package/lib/module/lib/theme.js.map +1 -0
- package/lib/module/lib/utils.js +137 -0
- package/lib/module/lib/utils.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/package.json +208 -0
- package/src/app/_layout.tsx +25 -0
- package/src/assets/icons/weather_icons/drizzle.png +0 -0
- package/src/assets/icons/weather_icons/foggy.png +0 -0
- package/src/assets/icons/weather_icons/freezing_rain.png +0 -0
- package/src/assets/icons/weather_icons/partly_cloudy.png +0 -0
- package/src/assets/icons/weather_icons/rainy.png +0 -0
- package/src/assets/icons/weather_icons/showers.png +0 -0
- package/src/assets/icons/weather_icons/sunny_weather.png +0 -0
- package/src/assets/icons/weather_icons/thunderstorm.png +0 -0
- package/src/assets/icons/weather_icons/thunderstorm_hail.png +0 -0
- package/src/components/theme-config.ts +331 -0
- package/src/components/ui/Accordion.tsx +253 -0
- package/src/components/ui/Alert-Dialog.tsx +295 -0
- package/src/components/ui/Alert.tsx +137 -0
- package/src/components/ui/AppBar.tsx +551 -0
- package/src/components/ui/Aspect-Ratio.tsx +25 -0
- package/src/components/ui/Avatar.tsx +103 -0
- package/src/components/ui/Badge.tsx +121 -0
- package/src/components/ui/Bottom-Sheet.tsx +224 -0
- package/src/components/ui/Button.tsx +100 -0
- package/src/components/ui/Card.tsx +185 -0
- package/src/components/ui/Checkbox.tsx +81 -0
- package/src/components/ui/Collapsible.tsx +40 -0
- package/src/components/ui/Context-Menu.tsx +407 -0
- package/src/components/ui/Custom-Card.tsx +226 -0
- package/src/components/ui/Dialog.tsx +240 -0
- package/src/components/ui/Dropdown-Menu.tsx +544 -0
- package/src/components/ui/Floating-Action.tsx +54 -0
- package/src/components/ui/Greeting-Card.tsx +471 -0
- package/src/components/ui/Hover-Card.tsx +101 -0
- package/src/components/ui/Icon.tsx +75 -0
- package/src/components/ui/Input.tsx +90 -0
- package/src/components/ui/Label.tsx +48 -0
- package/src/components/ui/Menubar.tsx +509 -0
- package/src/components/ui/Native-Only-Animated-View.tsx +37 -0
- package/src/components/ui/NavBar.tsx +397 -0
- package/src/components/ui/Popover.tsx +110 -0
- package/src/components/ui/Progress.tsx +138 -0
- package/src/components/ui/Radio-Group.tsx +79 -0
- package/src/components/ui/Select.tsx +344 -0
- package/src/components/ui/Separator.tsx +68 -0
- package/src/components/ui/SizedBox.tsx +116 -0
- package/src/components/ui/Skeleton.tsx +55 -0
- package/src/components/ui/Slider.tsx +222 -0
- package/src/components/ui/Switch.tsx +67 -0
- package/src/components/ui/Table.tsx +170 -0
- package/src/components/ui/Tabs.tsx +119 -0
- package/src/components/ui/Text.tsx +73 -0
- package/src/components/ui/Textarea.tsx +93 -0
- package/src/components/ui/Theme-Toggle.tsx +204 -0
- package/src/components/ui/Toast.tsx +127 -0
- package/src/components/ui/Toggle-Group.tsx +160 -0
- package/src/components/ui/Toggle.tsx +122 -0
- package/src/components/ui/Tooltip.tsx +117 -0
- package/src/components/ui/index.ts +42 -0
- package/src/index.tsx +24 -0
- package/src/lib/ThemeProvider.tsx +204 -0
- package/src/lib/cornerRadius.ts +160 -0
- package/src/lib/fonts.ts +28 -0
- package/src/lib/theme.ts +151 -0
- package/src/lib/utils.ts +146 -0
package/src/lib/theme.ts
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { DarkTheme, DefaultTheme, type Theme } from '@react-navigation/native';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Custom theme colors based on your Figma design tokens
|
|
5
|
+
* Using your categorized color system:
|
|
6
|
+
* 1. Surfaces - Page and card backgrounds
|
|
7
|
+
* 2. Text - All text colors with opacity variants
|
|
8
|
+
* 3. Primary - Main buttons and CTAs
|
|
9
|
+
* 4. Secondary - Secondary buttons
|
|
10
|
+
* 5. Tertiary/Accent - Highlights and selections
|
|
11
|
+
* 6. Borders - All borders and dividers
|
|
12
|
+
* 7. Highlights - Status/semantic colors
|
|
13
|
+
* 8. Brand - Brand accent colors (use sparingly)
|
|
14
|
+
*/
|
|
15
|
+
export const THEME = {
|
|
16
|
+
light: {
|
|
17
|
+
// === 1. SURFACES ===
|
|
18
|
+
background: 'hsl(210, 17%, 97%)', // #F7F8FA
|
|
19
|
+
card: 'hsl(0, 0%, 100%)', // #FFFFFF
|
|
20
|
+
popover: 'hsl(0, 0%, 100%)', // #FFFFFF
|
|
21
|
+
muted: 'hsl(0, 0%, 100%)', // #FFFFFF
|
|
22
|
+
|
|
23
|
+
// === 2. TEXT ===
|
|
24
|
+
foreground: 'hsl(0, 0%, 7%)', // #121212
|
|
25
|
+
cardForeground: 'hsl(0, 0%, 7%)', // #121212
|
|
26
|
+
popoverForeground: 'hsl(0, 0%, 7%)', // #121212
|
|
27
|
+
mutedForeground: 'hsla(0, 0%, 7%, 0.7)', // #121212 at 70%
|
|
28
|
+
|
|
29
|
+
// === 3. PRIMARY (Main buttons, CTAs) ===
|
|
30
|
+
primary: 'hsl(200, 13%, 11%)', // #161A1D - Near black
|
|
31
|
+
primaryForeground: 'hsl(0, 0%, 100%)', // #FFFFFF
|
|
32
|
+
|
|
33
|
+
// === 4. SECONDARY (Secondary buttons) ===
|
|
34
|
+
secondary: 'hsl(218, 14%, 53%)', // #64748B
|
|
35
|
+
secondaryForeground: 'hsl(0, 0%, 100%)', // #FFFFFF
|
|
36
|
+
|
|
37
|
+
// === 5. TERTIARY/ACCENT (Highlights, selections) ===
|
|
38
|
+
accent: 'hsl(356, 76%, 57%)', // #E43341 - Crimson
|
|
39
|
+
accentForeground: 'hsl(0, 0%, 100%)', // #FFFFFF
|
|
40
|
+
|
|
41
|
+
// === 6. BORDERS ===
|
|
42
|
+
border: 'hsl(214, 32%, 84%)', // #CBD5E1
|
|
43
|
+
input: 'hsl(214, 32%, 84%)', // #CBD5E1
|
|
44
|
+
ring: 'hsl(200, 13%, 11%)', // #161A1D - Same as primary
|
|
45
|
+
|
|
46
|
+
// === 7. HIGHLIGHTS ===
|
|
47
|
+
destructive: 'hsl(356, 87%, 57%)', // #F2353C - Red
|
|
48
|
+
destructiveForeground: 'hsl(0, 0%, 100%)',
|
|
49
|
+
success: 'hsl(88, 37%, 52%)', // #88B053 - Green
|
|
50
|
+
info: 'hsl(189, 45%, 51%)', // #4BAABE - Blue
|
|
51
|
+
warning: 'hsl(28, 81%, 57%)', // #ED9035 - Orange
|
|
52
|
+
|
|
53
|
+
// === 8. BRAND COLORS (Custom - use manually) ===
|
|
54
|
+
brand1: 'hsl(252, 97%, 25%)', // #1E027F - Deep violet
|
|
55
|
+
brand2: 'hsl(356, 76%, 57%)', // #E43341 - Crimson
|
|
56
|
+
brand3: 'hsl(304, 69%, 33%)', // #931C88 - Magenta
|
|
57
|
+
|
|
58
|
+
// === CHART COLORS ===
|
|
59
|
+
chart1: 'hsl(88, 37%, 52%)', // #88B053 - Green
|
|
60
|
+
chart2: 'hsl(189, 45%, 51%)', // #4BAABE - Blue
|
|
61
|
+
chart3: 'hsl(28, 81%, 57%)', // #ED9035 - Orange
|
|
62
|
+
chart4: 'hsl(254, 46%, 42%)', // #573DAB - Purple
|
|
63
|
+
chart5: 'hsl(348, 78%, 60%)', // #EA4A6B - Pink
|
|
64
|
+
|
|
65
|
+
// === MISC ===
|
|
66
|
+
radius: '0.5rem',
|
|
67
|
+
},
|
|
68
|
+
dark: {
|
|
69
|
+
// === 1. SURFACES ===
|
|
70
|
+
background: 'hsl(200, 13%, 10%)', // #161A1D
|
|
71
|
+
card: 'hsl(180, 14%, 13%)', // #1D2727
|
|
72
|
+
popover: 'hsl(180, 14%, 13%)', // #1D2727
|
|
73
|
+
muted: 'hsl(180, 14%, 13%)', // #1D2727
|
|
74
|
+
|
|
75
|
+
// === 2. TEXT ===
|
|
76
|
+
foreground: 'hsl(0, 0%, 100%)', // #FFFFFF
|
|
77
|
+
cardForeground: 'hsl(0, 0%, 100%)', // #FFFFFF
|
|
78
|
+
popoverForeground: 'hsl(0, 0%, 100%)', // #FFFFFF
|
|
79
|
+
mutedForeground: 'hsla(0, 0%, 100%, 0.7)', // #FFFFFF at 70%
|
|
80
|
+
|
|
81
|
+
// === 3. PRIMARY (Main buttons, CTAs) ===
|
|
82
|
+
primary: 'hsl(210, 13%, 85%)', // #D0D5D9 - Light grey (softer than white)
|
|
83
|
+
primaryForeground: 'hsl(200, 13%, 11%)', // #161A1D - Dark text
|
|
84
|
+
|
|
85
|
+
// === 4. SECONDARY (Secondary buttons) ===
|
|
86
|
+
secondary: 'hsl(218, 14%, 53%)', // #64748B
|
|
87
|
+
secondaryForeground: 'hsl(0, 0%, 100%)', // #FFFFFF
|
|
88
|
+
|
|
89
|
+
// === 5. TERTIARY/ACCENT (Highlights, selections) ===
|
|
90
|
+
accent: 'hsl(356, 76%, 57%)', // #E43341 - Crimson
|
|
91
|
+
accentForeground: 'hsl(0, 0%, 100%)', // #FFFFFF
|
|
92
|
+
|
|
93
|
+
// === 6. BORDERS ===
|
|
94
|
+
border: 'hsl(215, 25%, 27%)', // #334155 - Balanced slate-700
|
|
95
|
+
input: 'hsl(215, 25%, 27%)', // #334155
|
|
96
|
+
ring: 'hsl(210, 13%, 85%)', // #D0D5D9 - Same as primary
|
|
97
|
+
|
|
98
|
+
// === 7. HIGHLIGHTS ===
|
|
99
|
+
destructive: 'hsl(356, 87%, 57%)', // #F2353C - Red
|
|
100
|
+
destructiveForeground: 'hsl(0, 0%, 100%)',
|
|
101
|
+
success: 'hsl(88, 37%, 52%)', // #88B053 - Green
|
|
102
|
+
info: 'hsl(189, 45%, 51%)', // #4BAABE - Blue
|
|
103
|
+
warning: 'hsl(28, 81%, 57%)', // #ED9035 - Orange
|
|
104
|
+
|
|
105
|
+
// === 8. BRAND COLORS (Custom - use manually) ===
|
|
106
|
+
brand1: 'hsl(244, 100%, 73%)', // #8075FF - Cool violet
|
|
107
|
+
brand2: 'hsl(356, 76%, 57%)', // #E43341 - Crimson
|
|
108
|
+
brand3: 'hsl(291, 46%, 61%)', // #C160D4 - Light magenta
|
|
109
|
+
|
|
110
|
+
// === CHART COLORS ===
|
|
111
|
+
chart1: 'hsl(88, 37%, 52%)', // #88B053 - Green
|
|
112
|
+
chart2: 'hsl(189, 45%, 51%)', // #4BAABE - Blue
|
|
113
|
+
chart3: 'hsl(28, 81%, 57%)', // #ED9035 - Orange
|
|
114
|
+
chart4: 'hsl(254, 46%, 42%)', // #573DAB - Purple
|
|
115
|
+
chart5: 'hsl(348, 78%, 60%)', // #EA4A6B - Pink
|
|
116
|
+
|
|
117
|
+
// === MISC ===
|
|
118
|
+
radius: '0.5rem',
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* React Navigation theme configuration
|
|
124
|
+
* Maps our custom theme to React Navigation's theme structure
|
|
125
|
+
*/
|
|
126
|
+
export const NAV_THEME: Record<'light' | 'dark', Theme> = {
|
|
127
|
+
light: {
|
|
128
|
+
...DefaultTheme,
|
|
129
|
+
colors: {
|
|
130
|
+
...DefaultTheme.colors,
|
|
131
|
+
background: THEME.light.background,
|
|
132
|
+
border: THEME.light.border,
|
|
133
|
+
card: THEME.light.card,
|
|
134
|
+
notification: THEME.light.destructive,
|
|
135
|
+
primary: THEME.light.primary,
|
|
136
|
+
text: THEME.light.foreground,
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
dark: {
|
|
140
|
+
...DarkTheme,
|
|
141
|
+
colors: {
|
|
142
|
+
...DarkTheme.colors,
|
|
143
|
+
background: THEME.dark.background,
|
|
144
|
+
border: THEME.dark.border,
|
|
145
|
+
card: THEME.dark.card,
|
|
146
|
+
notification: THEME.dark.destructive,
|
|
147
|
+
primary: THEME.dark.primary,
|
|
148
|
+
text: THEME.dark.foreground,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
};
|
package/src/lib/utils.ts
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { clsx, type ClassValue } from 'clsx';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Utility function to merge Tailwind CSS classes with proper precedence
|
|
6
|
+
*
|
|
7
|
+
* Combines clsx (for conditional classes) and tailwind-merge (for deduplication)
|
|
8
|
+
* to create a single, optimized class string. Later classes override earlier ones.
|
|
9
|
+
*
|
|
10
|
+
* @param {...ClassValue[]} inputs - Class values to merge (strings, objects, arrays)
|
|
11
|
+
* @returns {string} Merged and deduplicated class string
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* // Basic usage
|
|
16
|
+
* cn('px-2 py-1', 'px-4') // => 'py-1 px-4'
|
|
17
|
+
*
|
|
18
|
+
* // With conditionals
|
|
19
|
+
* cn('text-base', isDark && 'text-white', 'font-bold')
|
|
20
|
+
* // => 'text-base text-white font-bold' (if isDark is true)
|
|
21
|
+
*
|
|
22
|
+
* // With objects
|
|
23
|
+
* cn({
|
|
24
|
+
* 'bg-primary': isPrimary,
|
|
25
|
+
* 'bg-secondary': !isPrimary
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* // Common component pattern
|
|
29
|
+
* cn('base-classes', variant === 'large' && 'large-classes', className)
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function cn(...inputs: ClassValue[]) {
|
|
33
|
+
return twMerge(clsx(inputs));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Applies dark mode classes with optional runtime control
|
|
38
|
+
*
|
|
39
|
+
* Provides three modes of operation:
|
|
40
|
+
* 1. Static mode (darkMode undefined): Returns classes with `dark:` prefix for automatic switching
|
|
41
|
+
* 2. Dark mode (darkMode true): Strips `dark:` prefix and returns only dark classes
|
|
42
|
+
* 3. Light mode (darkMode false): Returns only base classes
|
|
43
|
+
*
|
|
44
|
+
* This function is useful when you need to programmatically control dark mode
|
|
45
|
+
* instead of relying on Tailwind's automatic dark mode detection.
|
|
46
|
+
*
|
|
47
|
+
* @param {string} baseClasses - Classes to apply in light mode
|
|
48
|
+
* @param {string} darkClasses - Classes to apply in dark mode (with or without `dark:` prefix)
|
|
49
|
+
* @param {boolean} [darkMode] - Optional dark mode override (true/false/undefined)
|
|
50
|
+
* @returns {string} Merged class string based on mode
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```tsx
|
|
54
|
+
* // Static mode - use Tailwind's automatic detection
|
|
55
|
+
* cnWithDark('bg-white', 'dark:bg-black')
|
|
56
|
+
* // => 'bg-white dark:bg-black'
|
|
57
|
+
*
|
|
58
|
+
* // Programmatic dark mode
|
|
59
|
+
* const { isDark } = useTheme();
|
|
60
|
+
* cnWithDark('bg-white', 'dark:bg-black', isDark)
|
|
61
|
+
* // => 'bg-black' (if isDark is true)
|
|
62
|
+
* // => 'bg-white' (if isDark is false)
|
|
63
|
+
*
|
|
64
|
+
* // With multiple classes
|
|
65
|
+
* cnWithDark(
|
|
66
|
+
* 'bg-white text-black border-gray-200',
|
|
67
|
+
* 'dark:bg-black dark:text-white dark:border-gray-800',
|
|
68
|
+
* isDark
|
|
69
|
+
* )
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* @see {@link cn} for basic class merging
|
|
73
|
+
* @see {@link useTheme} for accessing theme state
|
|
74
|
+
*/
|
|
75
|
+
export function cnWithDark(
|
|
76
|
+
baseClasses: string,
|
|
77
|
+
darkClasses: string,
|
|
78
|
+
darkMode?: boolean
|
|
79
|
+
): string {
|
|
80
|
+
if (darkMode === undefined) {
|
|
81
|
+
// No override provided, use standard dark: prefixed classes
|
|
82
|
+
return cn(baseClasses, darkClasses);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (darkMode) {
|
|
86
|
+
// Dark mode enabled - apply dark classes without the dark: prefix
|
|
87
|
+
const processedDarkClasses = darkClasses
|
|
88
|
+
.split(' ')
|
|
89
|
+
.map((cls) => cls.replace(/^dark:/, ''))
|
|
90
|
+
.join(' ');
|
|
91
|
+
return cn(processedDarkClasses);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Dark mode disabled - only use base classes
|
|
95
|
+
return cn(baseClasses);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get color value based on theme mode
|
|
100
|
+
*
|
|
101
|
+
* Simple utility to select between light and dark color values based on the
|
|
102
|
+
* current theme. Primarily used for native platforms where Tailwind CSS
|
|
103
|
+
* classes don't work with inline styles.
|
|
104
|
+
*
|
|
105
|
+
* @param {string} lightColor - Color value for light mode (CSS color, HSL, RGB, hex)
|
|
106
|
+
* @param {string} darkColor - Color value for dark mode (CSS color, HSL, RGB, hex)
|
|
107
|
+
* @param {boolean} [darkMode] - Whether dark mode is active (defaults to light if undefined)
|
|
108
|
+
* @returns {string} The appropriate color value for the current mode
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```tsx
|
|
112
|
+
* import { useTheme } from './ThemeProvider';
|
|
113
|
+
*
|
|
114
|
+
* function MyComponent() {
|
|
115
|
+
* const { isDark } = useTheme();
|
|
116
|
+
*
|
|
117
|
+
* // Get color for inline styles
|
|
118
|
+
* const textColor = getThemeColor('#000000', '#ffffff', isDark);
|
|
119
|
+
* const bgColor = getThemeColor('hsl(0, 0%, 100%)', 'hsl(0, 0%, 10%)', isDark);
|
|
120
|
+
*
|
|
121
|
+
* return (
|
|
122
|
+
* <View style={{ backgroundColor: bgColor }}>
|
|
123
|
+
* <NativeText style={{ color: textColor }}>
|
|
124
|
+
* Theme-aware text
|
|
125
|
+
* </NativeText>
|
|
126
|
+
* </View>
|
|
127
|
+
* );
|
|
128
|
+
* }
|
|
129
|
+
*
|
|
130
|
+
* // Without theme context (defaults to light)
|
|
131
|
+
* const color = getThemeColor('#000', '#fff'); // => '#000'
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
* @see {@link useTheme} for accessing theme state
|
|
135
|
+
* @see {@link getThemeColorValue} from theme-config for more advanced usage
|
|
136
|
+
*/
|
|
137
|
+
export function getThemeColor(
|
|
138
|
+
lightColor: string,
|
|
139
|
+
darkColor: string,
|
|
140
|
+
darkMode?: boolean
|
|
141
|
+
): string {
|
|
142
|
+
if (darkMode === undefined) {
|
|
143
|
+
return lightColor; // Default to light if no preference
|
|
144
|
+
}
|
|
145
|
+
return darkMode ? darkColor : lightColor;
|
|
146
|
+
}
|