@campxdev/react-native-blueprint 0.1.15 → 0.1.16

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 (58) hide show
  1. package/global.css +672 -0
  2. package/lib/module/assets/Success-Tick.json +1 -0
  3. package/lib/module/assets/lotties/index.js +2 -1
  4. package/lib/module/assets/lotties/index.js.map +1 -1
  5. package/lib/module/components/DataDisplay/Banner/Banner.figma.js +25 -0
  6. package/lib/module/components/DataDisplay/Banner/Banner.figma.js.map +1 -0
  7. package/lib/module/components/DataDisplay/Banner/Banner.js +101 -0
  8. package/lib/module/components/DataDisplay/Banner/Banner.js.map +1 -0
  9. package/lib/module/components/DataDisplay/Greeting/Greeting.figma.js +15 -0
  10. package/lib/module/components/DataDisplay/Greeting/Greeting.figma.js.map +1 -0
  11. package/lib/module/components/DataDisplay/Greeting/Greeting.js +121 -0
  12. package/lib/module/components/DataDisplay/Greeting/Greeting.js.map +1 -0
  13. package/lib/module/components/DataDisplay/MonthCalendar/MonthCalendar.figma.js +5 -7
  14. package/lib/module/components/DataDisplay/MonthCalendar/MonthCalendar.figma.js.map +1 -1
  15. package/lib/module/components/Input/TextField/Textfield.js +77 -21
  16. package/lib/module/components/Input/TextField/Textfield.js.map +1 -1
  17. package/lib/module/components/ui/index.js +2 -1
  18. package/lib/module/components/ui/index.js.map +1 -1
  19. package/lib/module/index.js +3 -0
  20. package/lib/module/index.js.map +1 -1
  21. package/lib/module/patterns/pattern-components/BottomSheetPattern/index.js +4 -0
  22. package/lib/module/patterns/pattern-components/BottomSheetPattern/index.js.map +1 -0
  23. package/lib/module/patterns/pattern-components/CalendarPattern/index.js +4 -0
  24. package/lib/module/patterns/pattern-components/CalendarPattern/index.js.map +1 -0
  25. package/lib/module/patterns/pattern-components/DashboardPattern/index.js +4 -0
  26. package/lib/module/patterns/pattern-components/DashboardPattern/index.js.map +1 -0
  27. package/lib/module/patterns/pattern-components/EntityPatternGuided/index.js +4 -0
  28. package/lib/module/patterns/pattern-components/EntityPatternGuided/index.js.map +1 -0
  29. package/lib/module/patterns/pattern-components/SuccessPattern/SuccessPattern.figma.js +38 -0
  30. package/lib/module/patterns/pattern-components/SuccessPattern/SuccessPattern.figma.js.map +1 -0
  31. package/lib/module/patterns/pattern-components/SuccessPattern/SuccessPattern.js +91 -0
  32. package/lib/module/patterns/pattern-components/SuccessPattern/SuccessPattern.js.map +1 -0
  33. package/lib/module/patterns/pattern-components/SuccessPattern/index.js +4 -0
  34. package/lib/module/patterns/pattern-components/SuccessPattern/index.js.map +1 -0
  35. package/lib/module/patterns/pattern-components/index.js +4 -3
  36. package/lib/module/patterns/pattern-components/index.js.map +1 -1
  37. package/package.json +3 -2
  38. package/src/assets/Success-Tick.json +1 -0
  39. package/src/assets/lotties/index.ts +1 -0
  40. package/src/components/DataDisplay/Banner/Banner.figma.tsx +26 -0
  41. package/src/components/DataDisplay/Banner/Banner.tsx +108 -0
  42. package/src/components/DataDisplay/Greeting/Greeting.figma.tsx +12 -0
  43. package/src/components/DataDisplay/Greeting/Greeting.tsx +154 -0
  44. package/src/components/DataDisplay/MonthCalendar/MonthCalendar.figma.tsx +7 -11
  45. package/src/components/Input/TextField/Textfield.tsx +118 -33
  46. package/src/components/ui/index.ts +3 -1
  47. package/src/index.tsx +3 -0
  48. package/src/patterns/pattern-components/BottomSheetPattern/index.ts +1 -0
  49. package/src/patterns/pattern-components/CalendarPattern/index.ts +1 -0
  50. package/src/patterns/pattern-components/DashboardPattern/index.ts +1 -0
  51. package/src/patterns/pattern-components/EntityPatternGuided/index.ts +1 -0
  52. package/src/patterns/pattern-components/SuccessPattern/SuccessPattern.figma.tsx +38 -0
  53. package/src/patterns/pattern-components/SuccessPattern/SuccessPattern.tsx +119 -0
  54. package/src/patterns/pattern-components/SuccessPattern/index.ts +2 -0
  55. package/src/patterns/pattern-components/index.ts +2 -1
  56. package/lib/module/components/ui/Greeting-Card.js +0 -393
  57. package/lib/module/components/ui/Greeting-Card.js.map +0 -1
  58. package/src/components/ui/Greeting-Card.tsx +0 -472
@@ -1,472 +0,0 @@
1
- // @ts-nocheck
2
- import * as React from 'react';
3
- import {
4
- Image,
5
- Pressable,
6
- StyleSheet,
7
- View,
8
- useColorScheme,
9
- } from 'react-native';
10
- import { cssInterop } from 'nativewind';
11
- import { cn } from '../../lib/utils';
12
- import { CustomCard } from './Custom-Card';
13
- import { Text } from '../Input/Text/Text';
14
-
15
- cssInterop(View, { className: 'style' });
16
- cssInterop(Pressable, { className: 'style' });
17
-
18
- /**
19
- * Weather data structure for the greeting card
20
- */
21
- export interface Weather {
22
- /** Temperature in Celsius */
23
- temperature: number;
24
- /** Human-readable weather description (e.g., "Clear Sky", "Rainy") */
25
- weatherDescription: string;
26
- /** Path to the weather icon image */
27
- weatherImage: any;
28
- /** Weather code from Open-Meteo API */
29
- weatherCode: number;
30
- /** Timestamp of last weather update */
31
- lastUpdated: Date;
32
- }
33
-
34
- /**
35
- * Weather icon mappings for different weather conditions
36
- */
37
- const WEATHER_ICONS = {
38
- sunny: require('../../assets/icons/weather_icons/sunny_weather.png'),
39
- partlyCloudy: require('../../assets/icons/weather_icons/partly_cloudy.png'),
40
- foggy: require('../../assets/icons/weather_icons/foggy.png'),
41
- drizzle: require('../../assets/icons/weather_icons/drizzle.png'),
42
- rainy: require('../../assets/icons/weather_icons/rainy.png'),
43
- freezingRain: require('../../assets/icons/weather_icons/freezing_rain.png'),
44
- showers: require('../../assets/icons/weather_icons/showers.png'),
45
- thunderstorm: require('../../assets/icons/weather_icons/thunderstorm.png'),
46
- thunderstormHail: require('../../assets/icons/weather_icons/thunderstorm_hail.png'),
47
- };
48
-
49
- /**
50
- * Converts a weather code from Open-Meteo API to a description and icon
51
- *
52
- * @param {number} code - Weather code from Open-Meteo API (0-99)
53
- * @returns {Object} Object containing description and icon path
54
- *
55
- * @example
56
- * ```tsx
57
- * const weatherInfo = getWeatherDescription(0);
58
- * // Returns: { description: 'Clear Sky (Sunny)', weatherImage: ... }
59
- * ```
60
- */
61
- export function getWeatherDescription(code: number): {
62
- description: string;
63
- weatherImage: any;
64
- } {
65
- const weatherMap: {
66
- [key: string]: { description: string; icon: keyof typeof WEATHER_ICONS };
67
- } = {
68
- '0': { description: 'Clear Sky (Sunny)', icon: 'sunny' },
69
- '1,2,3': { description: 'Partly Cloudy', icon: 'partlyCloudy' },
70
- '45,48': { description: 'Foggy', icon: 'foggy' },
71
- '51,53,55': { description: 'Drizzle', icon: 'drizzle' },
72
- '56,57': { description: 'Freezing Drizzle', icon: 'drizzle' },
73
- '61,63,65': { description: 'Rainy', icon: 'rainy' },
74
- '66,67': { description: 'Freezing Rain', icon: 'freezingRain' },
75
- '80,81,82': { description: 'Showers', icon: 'showers' },
76
- '95': { description: 'Thunderstorm', icon: 'thunderstorm' },
77
- '96,99': {
78
- description: 'Thunderstorm with Hail',
79
- icon: 'thunderstormHail',
80
- },
81
- };
82
-
83
- for (const [codes, info] of Object.entries(weatherMap)) {
84
- if (codes.split(',').map(Number).includes(code)) {
85
- return {
86
- description: info.description,
87
- weatherImage: WEATHER_ICONS[info.icon],
88
- };
89
- }
90
- }
91
-
92
- return {
93
- description: 'Unknown Weather',
94
- weatherImage: WEATHER_ICONS.sunny,
95
- };
96
- }
97
-
98
- /**
99
- * Returns a greeting based on the current time of day
100
- *
101
- * @returns {string} Time-appropriate greeting
102
- *
103
- * @example
104
- * ```tsx
105
- * const greeting = getTimeBasedGreeting();
106
- * // Returns: "Good Morning" (if it's morning)
107
- * ```
108
- */
109
- export function getTimeBasedGreeting(): string {
110
- const hour = new Date().getHours();
111
-
112
- if (hour >= 5 && hour < 12) {
113
- return 'Good Morning';
114
- } else if (hour >= 12 && hour < 17) {
115
- return 'Good Afternoon';
116
- } else if (hour >= 17 && hour < 21) {
117
- return 'Good Evening';
118
- } else {
119
- return 'Good Night';
120
- }
121
- }
122
-
123
- /**
124
- * Formats a date to a readable string format
125
- *
126
- * @param {Date} date - Date to format
127
- * @returns {string} Formatted date string (e.g., "Monday, 16 October")
128
- */
129
- export function formatDate(date: Date): string {
130
- const days = [
131
- 'Sunday',
132
- 'Monday',
133
- 'Tuesday',
134
- 'Wednesday',
135
- 'Thursday',
136
- 'Friday',
137
- 'Saturday',
138
- ];
139
- const months = [
140
- 'January',
141
- 'February',
142
- 'March',
143
- 'April',
144
- 'May',
145
- 'June',
146
- 'July',
147
- 'August',
148
- 'September',
149
- 'October',
150
- 'November',
151
- 'December',
152
- ];
153
-
154
- const dayName = days[date.getDay()];
155
- const day = date.getDate();
156
- const monthName = months[date.getMonth()];
157
-
158
- return `${dayName}, ${day} ${monthName}`;
159
- }
160
-
161
- /**
162
- * Fetches weather data from Open-Meteo API
163
- *
164
- * @param {number} latitude - Latitude coordinate
165
- * @param {number} longitude - Longitude coordinate
166
- * @returns {Promise<Weather | null>} Weather data or null if fetch fails
167
- *
168
- * @example
169
- * ```tsx
170
- * const weather = await fetchWeather(37.7749, -122.4194);
171
- * ```
172
- */
173
- export async function fetchWeather(
174
- latitude: number,
175
- longitude: number
176
- ): Promise<Weather | null> {
177
- const url = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&current=temperature_2m,weathercode`;
178
-
179
- try {
180
- const response = await fetch(url);
181
-
182
- if (response.ok) {
183
- const data = await response.json();
184
-
185
- const temperature: number = data.current?.temperature_2m ?? 0;
186
- const weatherCode: number = data.current?.weathercode ?? 0;
187
-
188
- const weatherInfo = getWeatherDescription(weatherCode);
189
-
190
- return {
191
- temperature,
192
- weatherDescription: weatherInfo.description,
193
- weatherImage: weatherInfo.weatherImage,
194
- weatherCode,
195
- lastUpdated: new Date(),
196
- };
197
- }
198
-
199
- return null;
200
- } catch (error) {
201
- console.error('Failed to fetch weather:', error);
202
- return null;
203
- }
204
- }
205
-
206
- /**
207
- * Props for the GreetingCard component
208
- */
209
- export interface GreetingCardProps {
210
- /** User's full name to display in the greeting (required) */
211
- userName: string;
212
- /** Latitude coordinate for weather fetching (optional - weather shown only when both lat and lng provided) */
213
- lat?: number;
214
- /** Longitude coordinate for weather fetching (optional - weather shown only when both lat and lng provided) */
215
- lng?: number;
216
- /** Custom greeting message (overrides time-based greeting) */
217
- customGreeting?: string;
218
- /** Custom date to display (defaults to current date) */
219
- date?: Date;
220
- /** Action button text (e.g., "View Schedule") */
221
- actionText?: string;
222
- /** Callback when the card or action button is pressed */
223
- onPress?: () => void;
224
- /** Additional CSS classes for the card container */
225
- className?: string;
226
- /** Whether to show the action button section */
227
- showAction?: boolean;
228
- /** Cache duration in milliseconds (default: 15 minutes) */
229
- cacheDuration?: number;
230
- }
231
-
232
- /**
233
- * GreetingCard - A personalized greeting card with weather information
234
- *
235
- * Displays a personalized greeting with the user's name, current date, and optional
236
- * weather information fetched from Open-Meteo API. Includes an optional action button
237
- * (e.g., "View Schedule"). Weather data is automatically cached for 15 minutes.
238
- *
239
- * @component
240
- * @example
241
- * ```tsx
242
- * // Basic usage without weather
243
- * <GreetingCard
244
- * userName="John Doe"
245
- * actionText="View Schedule"
246
- * onPress={() => navigation.navigate('Schedule')}
247
- * />
248
- *
249
- * // With automatic weather fetching (provide both lat and lng)
250
- * <GreetingCard
251
- * userName="Jane Smith"
252
- * lat={37.7749}
253
- * lng={-122.4194}
254
- * actionText="View Dashboard"
255
- * onPress={() => console.log('Card pressed')}
256
- * />
257
- *
258
- * // Custom greeting without action
259
- * <GreetingCard
260
- * userName="Alice"
261
- * customGreeting="Welcome back"
262
- * showAction={false}
263
- * />
264
- * ```
265
- *
266
- * @property {string} userName - User's full name to display in greeting (required)
267
- * @property {number} [lat] - Latitude coordinate for weather fetching (optional)
268
- * @property {number} [lng] - Longitude coordinate for weather fetching (optional)
269
- * @property {string} [customGreeting] - Override the time-based greeting
270
- * @property {Date} [date] - Custom date to display (defaults to current date)
271
- * @property {string} [actionText="View Details"] - Text for the action button
272
- * @property {Function} [onPress] - Handler called when card or action is pressed
273
- * @property {string} [className] - Additional Tailwind classes for styling
274
- * @property {boolean} [showAction=true] - Whether to show the action button section
275
- * @property {number} [cacheDuration=900000] - Cache duration in ms (default: 15 min)
276
- */
277
- export function GreetingCard({
278
- userName,
279
- lat,
280
- lng,
281
- customGreeting,
282
- date = new Date(),
283
- actionText = 'View Details',
284
- onPress,
285
- className,
286
- showAction = true,
287
- cacheDuration = 15 * 60 * 1000, // 15 minutes
288
- }: GreetingCardProps) {
289
- const colorScheme = useColorScheme();
290
- const isDark = colorScheme === 'dark';
291
- const [weather, setWeather] = React.useState<Weather | null>(null);
292
- const [isLoading, setIsLoading] = React.useState(false);
293
- const cacheRef = React.useRef<{
294
- data: Weather | null;
295
- timestamp: number;
296
- } | null>(null);
297
-
298
- // Dynamic styles based on theme
299
- const dynamicStyles = React.useMemo(
300
- () => ({
301
- separator: {
302
- ...styles.separator,
303
- backgroundColor: isDark
304
- ? 'rgba(255, 255, 255, 0.15)'
305
- : 'rgba(0, 0, 0, 0.1)',
306
- },
307
- }),
308
- [isDark]
309
- );
310
-
311
- React.useEffect(() => {
312
- const loadWeather = async () => {
313
- if (lat === undefined || lng === undefined) {
314
- return;
315
- }
316
-
317
- const now = Date.now();
318
-
319
- // Check cache
320
- if (
321
- cacheRef.current &&
322
- now - cacheRef.current.timestamp < cacheDuration
323
- ) {
324
- setWeather(cacheRef.current.data);
325
- return;
326
- }
327
-
328
- setIsLoading(true);
329
-
330
- try {
331
- const weatherData = await fetchWeather(lat, lng);
332
- setWeather(weatherData);
333
- cacheRef.current = {
334
- data: weatherData,
335
- timestamp: now,
336
- };
337
- } catch (error) {
338
- console.error('Error loading weather:', error);
339
- } finally {
340
- setIsLoading(false);
341
- }
342
- };
343
-
344
- loadWeather();
345
- }, [lat, lng, cacheDuration]);
346
-
347
- const greeting = customGreeting || getTimeBasedGreeting();
348
- const formattedDate = formatDate(date);
349
-
350
- const CardWrapper = onPress ? Pressable : View;
351
- const wrapperProps = onPress
352
- ? {
353
- onPress,
354
- android_ripple: { color: 'rgba(0, 0, 0, 0.1)' },
355
- }
356
- : {};
357
-
358
- return (
359
- <CardWrapper {...wrapperProps}>
360
- <CustomCard
361
- cornerRadius={20}
362
- cornerSmoothing={1}
363
- className={cn('border-primary/20 dark:border-primary/30', className)}
364
- >
365
- {/* Wrapper with negative margin to counteract CustomCard's default padding */}
366
- <View style={styles.contentWrapper}>
367
- {/* Header Section with Greeting and Weather */}
368
- <View style={styles.headerSection}>
369
- {/* Greeting Text */}
370
- <View style={styles.greetingText}>
371
- <Text className="text-sm font-semibold text-card-foreground dark:text-card-foreground">
372
- Hi {userName},
373
- </Text>
374
- <Text className="mt-1.5 text-xs tracking-wider text-muted-foreground dark:text-muted-foreground">
375
- {greeting}, {formattedDate}
376
- </Text>
377
- </View>
378
-
379
- {/* Weather Display */}
380
- {(weather || isLoading) && (
381
- <View style={styles.weatherContainer}>
382
- {isLoading ? (
383
- <Text className="text-xs text-muted-foreground dark:text-muted-foreground">
384
- Loading...
385
- </Text>
386
- ) : (
387
- weather && (
388
- <>
389
- <View style={styles.weatherRow}>
390
- <Image
391
- source={weather.weatherImage}
392
- style={styles.weatherIcon}
393
- resizeMode="contain"
394
- />
395
- <Text className="ml-1 text-xs text-card-foreground dark:text-card-foreground">
396
- {Math.round(weather.temperature)}° C
397
- </Text>
398
- </View>
399
- <Text className="mt-0.5 text-xs text-muted-foreground/70 dark:text-muted-foreground/70">
400
- {weather.weatherDescription}
401
- </Text>
402
- </>
403
- )
404
- )}
405
- </View>
406
- )}
407
- </View>
408
-
409
- {/* Action Section */}
410
- {showAction && (
411
- <>
412
- <View style={dynamicStyles.separator} />
413
- <View style={styles.actionSection}>
414
- <Text className="text-sm font-semibold text-card-foreground dark:text-card-foreground">
415
- {actionText}
416
- </Text>
417
- <Text className="text-2xl text-primary dark:text-primary">
418
-
419
- </Text>
420
- </View>
421
- </>
422
- )}
423
- </View>
424
- </CustomCard>
425
- </CardWrapper>
426
- );
427
- }
428
-
429
- GreetingCard.displayName = 'GreetingCard';
430
-
431
- const styles = StyleSheet.create({
432
- weatherIcon: {
433
- width: 40,
434
- height: 35,
435
- },
436
- contentWrapper: {
437
- margin: -24, // Counteract CustomCard's default padding of 24
438
- },
439
- headerSection: {
440
- flexDirection: 'row',
441
- alignItems: 'flex-start',
442
- justifyContent: 'space-between',
443
- paddingHorizontal: 20,
444
- paddingTop: 20,
445
- paddingBottom: 16,
446
- },
447
- greetingText: {
448
- flex: 1,
449
- },
450
- weatherContainer: {
451
- marginLeft: 12,
452
- alignItems: 'flex-end',
453
- },
454
- weatherRow: {
455
- flexDirection: 'row',
456
- alignItems: 'center',
457
- },
458
- separator: {
459
- height: 1,
460
- marginVertical: 8,
461
- },
462
- actionSection: {
463
- flexDirection: 'row',
464
- alignItems: 'center',
465
- justifyContent: 'space-between',
466
- paddingHorizontal: 20,
467
- paddingBottom: 12,
468
- paddingTop: 4,
469
- },
470
- });
471
-
472
- export { WEATHER_ICONS };