rnnovaui 0.11.4 → 0.11.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rnnovaui",
3
- "version": "0.11.4",
3
+ "version": "0.11.6",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "react-native": "src/index.js",
@@ -1,4 +1,11 @@
1
- import React, { memo, useCallback, useMemo, useState } from "react";
1
+ import React, {
2
+ memo,
3
+ useCallback,
4
+ useEffect,
5
+ useMemo,
6
+ useRef,
7
+ useState,
8
+ } from "react";
2
9
 
3
10
  import {
4
11
  Dimensions,
@@ -22,9 +29,9 @@ import { useUITheme } from "../../theme";
22
29
 
23
30
  const { width: SCREEN_WIDTH } = Dimensions.get("window");
24
31
 
25
- /* ========================================================================== */
26
- /* DEFAULTS */
27
- /* ========================================================================== */
32
+ /* ==========================================================================
33
+ * DEFAULTS
34
+ * ========================================================================== */
28
35
 
29
36
  const DEFAULT_SPRING = {
30
37
  damping: 18,
@@ -72,9 +79,9 @@ const DEFAULT_RADIUS = {
72
79
  pill: 999,
73
80
  };
74
81
 
75
- /* ========================================================================== */
76
- /* THEME */
77
- /* ========================================================================== */
82
+ /* ==========================================================================
83
+ * THEME
84
+ * ========================================================================== */
78
85
 
79
86
  function resolveTheme(theme) {
80
87
  return {
@@ -103,9 +110,9 @@ function resolveTheme(theme) {
103
110
  };
104
111
  }
105
112
 
106
- /* ========================================================================== */
107
- /* IMAGE SOURCE */
108
- /* ========================================================================== */
113
+ /* ==========================================================================
114
+ * IMAGE SOURCE
115
+ * ========================================================================== */
109
116
 
110
117
  function normalizeImageSource(source) {
111
118
  if (!source) {
@@ -113,17 +120,20 @@ function normalizeImageSource(source) {
113
120
  }
114
121
 
115
122
  /*
116
- * require("./image.png")
123
+ * Local image:
117
124
  *
118
- * React Native:
119
- * number
125
+ * require("../../assets/image.jpg")
126
+ *
127
+ * React Native returns a number.
120
128
  */
121
129
  if (typeof source === "number") {
122
130
  return source;
123
131
  }
124
132
 
125
133
  /*
126
- * "https://..."
134
+ * Remote image:
135
+ *
136
+ * "https://example.com/image.jpg"
127
137
  */
128
138
  if (typeof source === "string") {
129
139
  return {
@@ -132,6 +142,8 @@ function normalizeImageSource(source) {
132
142
  }
133
143
 
134
144
  /*
145
+ * Remote:
146
+ *
135
147
  * { uri: "https://..." }
136
148
  */
137
149
  if (typeof source === "object" && source !== null) {
@@ -140,9 +152,11 @@ function normalizeImageSource(source) {
140
152
  }
141
153
 
142
154
  /*
143
- * Support:
155
+ * Also support:
144
156
  *
145
- * { source: require(...) }
157
+ * {
158
+ * source: require(...)
159
+ * }
146
160
  */
147
161
  if (source.source) {
148
162
  return normalizeImageSource(source.source);
@@ -154,44 +168,41 @@ function normalizeImageSource(source) {
154
168
  return null;
155
169
  }
156
170
 
157
- /* ========================================================================== */
158
- /* IMAGE ARRAY */
159
- /* ========================================================================== */
171
+ /* ==========================================================================
172
+ * RESOLVE RESTAURANT IMAGES
173
+ * ========================================================================== */
160
174
 
161
175
  function resolveRestaurantImages({ restaurant, image, images }) {
162
176
  let result = [];
163
177
 
164
178
  /*
165
- * 1. Explicit images prop
179
+ * Priority:
180
+ *
181
+ * images prop
182
+ * restaurant.images
183
+ * image prop
184
+ * restaurant.image
166
185
  */
186
+
167
187
  if (Array.isArray(images) && images.length > 0) {
168
188
  result = images;
169
189
  } else if (
170
- /*
171
- * 2. restaurant.images
172
- */
173
190
  Array.isArray(restaurant?.images) &&
174
191
  restaurant.images.length > 0
175
192
  ) {
176
193
  result = restaurant.images;
177
194
  } else if (image) {
178
- /*
179
- * 3. Explicit image prop
180
- */
181
195
  result = [image];
182
196
  } else if (restaurant?.image) {
183
- /*
184
- * 4. restaurant.image
185
- */
186
197
  result = [restaurant.image];
187
198
  }
188
199
 
189
200
  return result.map(normalizeImageSource).filter(Boolean);
190
201
  }
191
202
 
192
- /* ========================================================================== */
193
- /* ICON */
194
- /* ========================================================================== */
203
+ /* ==========================================================================
204
+ * ICON
205
+ * ========================================================================== */
195
206
 
196
207
  function RenderIcon({ icon, size = 20, color = "#000000", style }) {
197
208
  if (!icon) {
@@ -199,9 +210,9 @@ function RenderIcon({ icon, size = 20, color = "#000000", style }) {
199
210
  }
200
211
 
201
212
  /*
202
- * Already-rendered React element.
213
+ * Already rendered element:
203
214
  *
204
- * <Ionicons name="heart" />
215
+ * icon={<Ionicons name="heart" />}
205
216
  */
206
217
  if (React.isValidElement(icon)) {
207
218
  return React.cloneElement(icon, {
@@ -232,7 +243,7 @@ function RenderIcon({ icon, size = 20, color = "#000000", style }) {
232
243
  /*
233
244
  * Icon name:
234
245
  *
235
- * icon="star"
246
+ * icon="heart"
236
247
  */
237
248
  if (typeof icon === "string") {
238
249
  return <Ionicons name={icon} size={size} color={color} style={style} />;
@@ -241,13 +252,14 @@ function RenderIcon({ icon, size = 20, color = "#000000", style }) {
241
252
  return null;
242
253
  }
243
254
 
244
- /* ========================================================================== */
245
- /* RESTAURANT IMAGE CAROUSEL */
246
- /* ========================================================================== */
255
+ /* ==========================================================================
256
+ * RESTAURANT IMAGE CAROUSEL
257
+ * ========================================================================== */
247
258
 
248
259
  const RestaurantImageCarousel = memo(function RestaurantImageCarousel({
249
- images,
250
- height = 210,
260
+ images = [],
261
+
262
+ height = 220,
251
263
 
252
264
  resizeMode = "cover",
253
265
 
@@ -264,16 +276,32 @@ const RestaurantImageCarousel = memo(function RestaurantImageCarousel({
264
276
  inactiveDotStyle,
265
277
 
266
278
  onImageChange,
279
+
280
+ /*
281
+ * Autoplay
282
+ */
283
+ autoplay = true,
284
+
285
+ autoplayInterval = 3000,
286
+
287
+ loop = true,
288
+
289
+ pauseOnTouch = true,
267
290
  }) {
268
291
  const [containerWidth, setContainerWidth] = useState(0);
269
292
 
270
293
  const [activeIndex, setActiveIndex] = useState(0);
271
294
 
272
- const data = Array.isArray(images) ? images : [];
295
+ const [isTouching, setIsTouching] = useState(false);
296
+
297
+ const listRef = useRef(null);
298
+
299
+ const data = Array.isArray(images) ? images.filter(Boolean) : [];
300
+
301
+ /* ======================================================================
302
+ * LAYOUT
303
+ * ====================================================================== */
273
304
 
274
- /*
275
- * Get actual width.
276
- */
277
305
  const handleLayout = useCallback(
278
306
  (event) => {
279
307
  const measuredWidth = event.nativeEvent.layout.width;
@@ -285,39 +313,147 @@ const RestaurantImageCarousel = memo(function RestaurantImageCarousel({
285
313
  [containerWidth],
286
314
  );
287
315
 
288
- /*
289
- * Calculate current page.
290
- */
316
+ /* ======================================================================
317
+ * INDEX CHANGE
318
+ * ====================================================================== */
319
+
320
+ const updateIndex = useCallback(
321
+ (index) => {
322
+ setActiveIndex(index);
323
+
324
+ if (typeof onImageChange === "function") {
325
+ onImageChange(index);
326
+ }
327
+ },
328
+ [onImageChange],
329
+ );
330
+
331
+ /* ======================================================================
332
+ * SCROLL
333
+ * ========================================================================== */
334
+
291
335
  const handleScroll = useCallback(
292
336
  (event) => {
293
- const { contentOffset, layoutMeasurement } = event.nativeEvent;
337
+ const offsetX = event.nativeEvent.contentOffset.x;
338
+
339
+ const layoutWidth = event.nativeEvent.layoutMeasurement?.width;
294
340
 
295
- const pageWidth = layoutMeasurement?.width || containerWidth;
341
+ const pageWidth = layoutWidth || containerWidth;
296
342
 
297
343
  if (!pageWidth) {
298
344
  return;
299
345
  }
300
346
 
301
- const nextIndex = Math.round(contentOffset.x / pageWidth);
347
+ const index = Math.round(offsetX / pageWidth);
302
348
 
303
- if (nextIndex < 0 || nextIndex >= data.length) {
349
+ if (index < 0 || index >= data.length) {
304
350
  return;
305
351
  }
306
352
 
307
- if (nextIndex !== activeIndex) {
308
- setActiveIndex(nextIndex);
309
-
310
- if (typeof onImageChange === "function") {
311
- onImageChange(nextIndex);
312
- }
353
+ if (index !== activeIndex) {
354
+ updateIndex(index);
313
355
  }
314
356
  },
315
- [activeIndex, containerWidth, data.length, onImageChange],
357
+ [activeIndex, containerWidth, data.length, updateIndex],
316
358
  );
317
359
 
318
- /*
319
- * Empty image state.
320
- */
360
+ /* ======================================================================
361
+ * AUTOPLAY
362
+ * ========================================================================== */
363
+
364
+ useEffect(() => {
365
+ if (!autoplay) {
366
+ return undefined;
367
+ }
368
+
369
+ if (data.length <= 1) {
370
+ return undefined;
371
+ }
372
+
373
+ if (containerWidth <= 0) {
374
+ return undefined;
375
+ }
376
+
377
+ if (pauseOnTouch && isTouching) {
378
+ return undefined;
379
+ }
380
+
381
+ const timer = setInterval(
382
+ () => {
383
+ setActiveIndex((currentIndex) => {
384
+ let nextIndex = currentIndex + 1;
385
+
386
+ /*
387
+ * Last image.
388
+ */
389
+ if (nextIndex >= data.length) {
390
+ if (!loop) {
391
+ return currentIndex;
392
+ }
393
+
394
+ nextIndex = 0;
395
+ }
396
+
397
+ /*
398
+ * Scroll carousel.
399
+ */
400
+ requestAnimationFrame(() => {
401
+ if (listRef.current) {
402
+ listRef.current.scrollToOffset({
403
+ offset: nextIndex * containerWidth,
404
+
405
+ animated: true,
406
+ });
407
+ }
408
+ });
409
+
410
+ /*
411
+ * Notify parent.
412
+ */
413
+ if (typeof onImageChange === "function") {
414
+ onImageChange(nextIndex);
415
+ }
416
+
417
+ return nextIndex;
418
+ });
419
+ },
420
+ Math.max(500, autoplayInterval),
421
+ );
422
+
423
+ return () => {
424
+ clearInterval(timer);
425
+ };
426
+ }, [
427
+ autoplay,
428
+ autoplayInterval,
429
+ containerWidth,
430
+ data.length,
431
+ isTouching,
432
+ loop,
433
+ onImageChange,
434
+ pauseOnTouch,
435
+ ]);
436
+
437
+ /* ======================================================================
438
+ * TOUCH
439
+ * ========================================================================== */
440
+
441
+ const handleTouchStart = useCallback(() => {
442
+ if (pauseOnTouch) {
443
+ setIsTouching(true);
444
+ }
445
+ }, [pauseOnTouch]);
446
+
447
+ const handleTouchEnd = useCallback(() => {
448
+ if (pauseOnTouch) {
449
+ setIsTouching(false);
450
+ }
451
+ }, [pauseOnTouch]);
452
+
453
+ /* ======================================================================
454
+ * EMPTY
455
+ * ========================================================================== */
456
+
321
457
  if (data.length === 0) {
322
458
  return (
323
459
  <View
@@ -345,9 +481,10 @@ const RestaurantImageCarousel = memo(function RestaurantImageCarousel({
345
481
  );
346
482
  }
347
483
 
348
- /*
349
- * Single image.
350
- */
484
+ /* ======================================================================
485
+ * SINGLE IMAGE
486
+ * ========================================================================== */
487
+
351
488
  if (data.length === 1) {
352
489
  return (
353
490
  <View
@@ -373,9 +510,10 @@ const RestaurantImageCarousel = memo(function RestaurantImageCarousel({
373
510
  );
374
511
  }
375
512
 
376
- /*
377
- * Multiple images.
378
- */
513
+ /* ======================================================================
514
+ * MULTIPLE IMAGES
515
+ * ========================================================================== */
516
+
379
517
  return (
380
518
  <View
381
519
  onLayout={handleLayout}
@@ -387,14 +525,9 @@ const RestaurantImageCarousel = memo(function RestaurantImageCarousel({
387
525
  ]}
388
526
  >
389
527
  <FlatList
528
+ ref={listRef}
390
529
  data={data}
391
530
  horizontal
392
- /*
393
- * IMPORTANT
394
- *
395
- * This enables one full image
396
- * per swipe.
397
- */
398
531
  pagingEnabled
399
532
  showsHorizontalScrollIndicator={false}
400
533
  bounces={false}
@@ -404,6 +537,11 @@ const RestaurantImageCarousel = memo(function RestaurantImageCarousel({
404
537
  scrollEventThrottle={16}
405
538
  decelerationRate="fast"
406
539
  onScroll={handleScroll}
540
+ onScrollBeginDrag={handleTouchStart}
541
+ onScrollEndDrag={handleTouchEnd}
542
+ onMomentumScrollEnd={handleTouchEnd}
543
+ onTouchStart={handleTouchStart}
544
+ onTouchEnd={handleTouchEnd}
407
545
  keyExtractor={(_, index) => `restaurant-image-${index}`}
408
546
  renderItem={({ item }) => {
409
547
  const itemWidth = containerWidth || SCREEN_WIDTH;
@@ -414,6 +552,7 @@ const RestaurantImageCarousel = memo(function RestaurantImageCarousel({
414
552
  styles.carouselItem,
415
553
  {
416
554
  width: itemWidth,
555
+
417
556
  height,
418
557
  },
419
558
  ]}
@@ -425,6 +564,7 @@ const RestaurantImageCarousel = memo(function RestaurantImageCarousel({
425
564
  styles.restaurantImage,
426
565
  {
427
566
  width: itemWidth,
567
+
428
568
  height,
429
569
  },
430
570
  ]}
@@ -434,7 +574,9 @@ const RestaurantImageCarousel = memo(function RestaurantImageCarousel({
434
574
  }}
435
575
  />
436
576
 
437
- {/* PAGINATION */}
577
+ {/* ================================================================ */}
578
+ {/* PAGINATION */}
579
+ {/* ================================================================ */}
438
580
 
439
581
  {showPagination ? (
440
582
  <View pointerEvents="none" style={[styles.pagination, paginationStyle]}>
@@ -468,16 +610,16 @@ const RestaurantImageCarousel = memo(function RestaurantImageCarousel({
468
610
  );
469
611
  });
470
612
 
471
- /* ========================================================================== */
472
- /* TOP RATED BADGE */
473
- /* ========================================================================== */
613
+ /* ==========================================================================
614
+ * TOP RATED
615
+ * ========================================================================== */
474
616
 
475
617
  const TopRatedBadge = memo(function TopRatedBadge({
476
618
  text = "Top Rated",
477
619
 
478
620
  icon = "flame",
479
621
 
480
- backgroundColor,
622
+ backgroundColor = "#FF5A5F",
481
623
 
482
624
  color = "#FFFFFF",
483
625
 
@@ -520,9 +662,9 @@ const TopRatedBadge = memo(function TopRatedBadge({
520
662
  );
521
663
  });
522
664
 
523
- /* ========================================================================== */
524
- /* RATING */
525
- /* ========================================================================== */
665
+ /* ==========================================================================
666
+ * RATING
667
+ * ========================================================================== */
526
668
 
527
669
  const Rating = memo(function Rating({
528
670
  rating,
@@ -535,9 +677,9 @@ const Rating = memo(function Rating({
535
677
 
536
678
  iconColor = "#FFB020",
537
679
 
538
- textColor,
680
+ textColor = "#171A21",
539
681
 
540
- reviewColor,
682
+ reviewColor = "#737985",
541
683
 
542
684
  showReviewCount = true,
543
685
 
@@ -549,7 +691,7 @@ const Rating = memo(function Rating({
549
691
 
550
692
  let formattedReviews = "";
551
693
 
552
- if (reviewCount !== undefined && reviewCount !== null) {
694
+ if (reviewCount !== undefined && reviewCount !== null && reviewCount !== "") {
553
695
  if (typeof reviewCount === "number" && reviewCount >= 1000) {
554
696
  formattedReviews = `${(reviewCount / 1000).toFixed(
555
697
  reviewCount >= 10000 ? 0 : 1,
@@ -590,18 +732,18 @@ const Rating = memo(function Rating({
590
732
  );
591
733
  });
592
734
 
593
- /* ========================================================================== */
594
- /* CUISINE TAGS */
595
- /* ========================================================================== */
735
+ /* ==========================================================================
736
+ * CUISINE TAGS
737
+ * ========================================================================== */
596
738
 
597
739
  const CuisineTags = memo(function CuisineTags({
598
740
  cuisines = [],
599
741
 
600
742
  maxTags = 3,
601
743
 
602
- backgroundColor,
744
+ backgroundColor = "rgba(255,90,31,0.10)",
603
745
 
604
- textColor,
746
+ textColor = "#737985",
605
747
 
606
748
  borderRadius = 999,
607
749
 
@@ -671,24 +813,24 @@ const CuisineTags = memo(function CuisineTags({
671
813
  );
672
814
  });
673
815
 
674
- /* ========================================================================== */
675
- /* INFO ITEM */
676
- /* ========================================================================== */
816
+ /* ==========================================================================
817
+ * INFO ITEM
818
+ * ========================================================================== */
677
819
 
678
820
  const InfoItem = memo(function InfoItem({
679
821
  icon,
680
822
 
681
- iconSize = 23,
823
+ iconSize = 24,
682
824
 
683
- iconColor,
825
+ iconColor = "#737985",
684
826
 
685
827
  value,
686
828
 
687
829
  label,
688
830
 
689
- valueColor,
831
+ valueColor = "#171A21",
690
832
 
691
- labelColor,
833
+ labelColor = "#737985",
692
834
  }) {
693
835
  if (!value && !label) {
694
836
  return null;
@@ -731,15 +873,31 @@ const InfoItem = memo(function InfoItem({
731
873
  );
732
874
  });
733
875
 
734
- /* ========================================================================== */
735
- /* RESTAURANT CARD */
736
- /* ========================================================================== */
876
+ /* ==========================================================================
877
+ * RESTAURANT CARD
878
+ * ========================================================================== */
737
879
 
738
880
  export const UIRestaurantCard = memo(function UIRestaurantCard({
739
881
  restaurant = {},
740
882
 
741
883
  /* -------------------------------------------------------------------- */
742
- /* Interaction */
884
+ /* CARD */
885
+ /* -------------------------------------------------------------------- */
886
+
887
+ width = SCREEN_WIDTH - 24,
888
+
889
+ backgroundColor,
890
+
891
+ borderRadius,
892
+
893
+ shadow = true,
894
+
895
+ style,
896
+
897
+ contentStyle,
898
+
899
+ /* -------------------------------------------------------------------- */
900
+ /* PRESS */
743
901
  /* -------------------------------------------------------------------- */
744
902
 
745
903
  onPress,
@@ -749,7 +907,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
749
907
  disabled = false,
750
908
 
751
909
  /* -------------------------------------------------------------------- */
752
- /* Animation */
910
+ /* ANIMATION */
753
911
  /* -------------------------------------------------------------------- */
754
912
 
755
913
  reanimated = false,
@@ -759,32 +917,32 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
759
917
  pressedScale = 0.985,
760
918
 
761
919
  /* -------------------------------------------------------------------- */
762
- /* Card */
920
+ /* IMAGE */
763
921
  /* -------------------------------------------------------------------- */
764
922
 
765
- width = SCREEN_WIDTH - 24,
766
-
767
- backgroundColor,
768
-
769
- borderRadius,
923
+ image,
770
924
 
771
- shadow = true,
925
+ images,
772
926
 
773
- style,
927
+ imageHeight = 220,
774
928
 
775
- contentStyle,
929
+ imageResizeMode = "cover",
776
930
 
777
931
  /* -------------------------------------------------------------------- */
778
- /* Images */
932
+ /* AUTOPLAY */
779
933
  /* -------------------------------------------------------------------- */
780
934
 
781
- image,
935
+ autoplay = true,
782
936
 
783
- images,
937
+ autoplayInterval = 3000,
784
938
 
785
- imageHeight = 220,
939
+ loop = true,
786
940
 
787
- imageResizeMode = "cover",
941
+ pauseOnTouch = true,
942
+
943
+ /* -------------------------------------------------------------------- */
944
+ /* PAGINATION */
945
+ /* -------------------------------------------------------------------- */
788
946
 
789
947
  showPagination = true,
790
948
 
@@ -801,7 +959,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
801
959
  onImageChange,
802
960
 
803
961
  /* -------------------------------------------------------------------- */
804
- /* Top Rated */
962
+ /* TOP RATED */
805
963
  /* -------------------------------------------------------------------- */
806
964
 
807
965
  showTopRated = true,
@@ -823,7 +981,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
823
981
  topRatedTextStyle,
824
982
 
825
983
  /* -------------------------------------------------------------------- */
826
- /* Favorite */
984
+ /* FAVORITE */
827
985
  /* -------------------------------------------------------------------- */
828
986
 
829
987
  showFavorite = true,
@@ -851,7 +1009,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
851
1009
  favoriteStyle,
852
1010
 
853
1011
  /* -------------------------------------------------------------------- */
854
- /* Discount */
1012
+ /* DISCOUNT */
855
1013
  /* -------------------------------------------------------------------- */
856
1014
 
857
1015
  showDiscount = true,
@@ -867,7 +1025,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
867
1025
  discountTextStyle,
868
1026
 
869
1027
  /* -------------------------------------------------------------------- */
870
- /* Logo */
1028
+ /* LOGO */
871
1029
  /* -------------------------------------------------------------------- */
872
1030
 
873
1031
  showLogo = true,
@@ -881,7 +1039,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
881
1039
  logoStyle,
882
1040
 
883
1041
  /* -------------------------------------------------------------------- */
884
- /* Restaurant Info */
1042
+ /* NAME */
885
1043
  /* -------------------------------------------------------------------- */
886
1044
 
887
1045
  name,
@@ -897,7 +1055,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
897
1055
  subtitleStyle,
898
1056
 
899
1057
  /* -------------------------------------------------------------------- */
900
- /* Rating */
1058
+ /* RATING */
901
1059
  /* -------------------------------------------------------------------- */
902
1060
 
903
1061
  showRating = true,
@@ -921,7 +1079,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
921
1079
  ratingStyle,
922
1080
 
923
1081
  /* -------------------------------------------------------------------- */
924
- /* Cuisine */
1082
+ /* CUISINES */
925
1083
  /* -------------------------------------------------------------------- */
926
1084
 
927
1085
  cuisines,
@@ -939,7 +1097,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
939
1097
  tagTextStyle,
940
1098
 
941
1099
  /* -------------------------------------------------------------------- */
942
- /* Delivery */
1100
+ /* DELIVERY */
943
1101
  /* -------------------------------------------------------------------- */
944
1102
 
945
1103
  deliveryTime,
@@ -951,7 +1109,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
951
1109
  deliveryIconSize = 25,
952
1110
 
953
1111
  /* -------------------------------------------------------------------- */
954
- /* Distance */
1112
+ /* DISTANCE */
955
1113
  /* -------------------------------------------------------------------- */
956
1114
 
957
1115
  distance,
@@ -963,7 +1121,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
963
1121
  distanceIconSize = 25,
964
1122
 
965
1123
  /* -------------------------------------------------------------------- */
966
- /* Free Delivery */
1124
+ /* FREE DELIVERY */
967
1125
  /* -------------------------------------------------------------------- */
968
1126
 
969
1127
  freeDelivery = false,
@@ -981,7 +1139,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
981
1139
  freeDeliveryIconColor,
982
1140
 
983
1141
  /* -------------------------------------------------------------------- */
984
- /* Divider */
1142
+ /* DIVIDER */
985
1143
  /* -------------------------------------------------------------------- */
986
1144
 
987
1145
  showDivider = true,
@@ -989,7 +1147,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
989
1147
  dividerColor,
990
1148
 
991
1149
  /* -------------------------------------------------------------------- */
992
- /* Custom rendering */
1150
+ /* CUSTOM RENDERERS */
993
1151
  /* -------------------------------------------------------------------- */
994
1152
 
995
1153
  renderImage,
@@ -1019,7 +1177,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1019
1177
  children,
1020
1178
  }) {
1021
1179
  /* ==================================================================== */
1022
- /* THEME */
1180
+ /* THEME */
1023
1181
  /* ==================================================================== */
1024
1182
 
1025
1183
  const { theme } = useUITheme();
@@ -1036,7 +1194,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1036
1194
  );
1037
1195
 
1038
1196
  /* ==================================================================== */
1039
- /* DATA */
1197
+ /* RESTAURANT DATA */
1040
1198
  /* ==================================================================== */
1041
1199
 
1042
1200
  const resolvedName = name ?? restaurant?.name ?? "";
@@ -1079,7 +1237,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1079
1237
  freeDeliverySubtext ?? restaurant?.freeDeliverySubtext;
1080
1238
 
1081
1239
  /* ==================================================================== */
1082
- /* COLORS */
1240
+ /* COLORS */
1083
1241
  /* ==================================================================== */
1084
1242
 
1085
1243
  const cardColor =
@@ -1108,7 +1266,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1108
1266
  freeDeliveryIconColor ?? colors.primary ?? "#FF5A1F";
1109
1267
 
1110
1268
  /* ==================================================================== */
1111
- /* CARD PRESS ANIMATION */
1269
+ /* PRESS ANIMATION */
1112
1270
  /* ==================================================================== */
1113
1271
 
1114
1272
  const scale = useSharedValue(1);
@@ -1124,21 +1282,25 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1124
1282
  });
1125
1283
 
1126
1284
  const handlePressIn = useCallback(() => {
1127
- if (disabled || !reanimated) {
1285
+ if (!reanimated || disabled) {
1128
1286
  return;
1129
1287
  }
1130
1288
 
1131
1289
  scale.value = withSpring(pressedScale, resolvedSpring);
1132
- }, [disabled, reanimated, pressedScale, resolvedSpring, scale]);
1290
+ }, [disabled, pressedScale, reanimated, resolvedSpring, scale]);
1133
1291
 
1134
1292
  const handlePressOut = useCallback(() => {
1135
- if (disabled || !reanimated) {
1293
+ if (!reanimated || disabled) {
1136
1294
  return;
1137
1295
  }
1138
1296
 
1139
1297
  scale.value = withSpring(1, resolvedSpring);
1140
1298
  }, [disabled, reanimated, resolvedSpring, scale]);
1141
1299
 
1300
+ /* ==================================================================== */
1301
+ /* PRESS */
1302
+ /* ==================================================================== */
1303
+
1142
1304
  const handlePress = useCallback(() => {
1143
1305
  if (disabled) {
1144
1306
  return;
@@ -1175,6 +1337,10 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1175
1337
  images={resolvedImages}
1176
1338
  height={imageHeight}
1177
1339
  resizeMode={imageResizeMode}
1340
+ autoplay={autoplay}
1341
+ autoplayInterval={autoplayInterval}
1342
+ loop={loop}
1343
+ pauseOnTouch={pauseOnTouch}
1178
1344
  showPagination={showPagination}
1179
1345
  activeDotColor={activeDotColor}
1180
1346
  inactiveDotColor={inactiveDotColor}
@@ -1186,7 +1352,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1186
1352
  );
1187
1353
 
1188
1354
  /* ==================================================================== */
1189
- /* TOP RATED */
1355
+ /* TOP RATED */
1190
1356
  /* ==================================================================== */
1191
1357
 
1192
1358
  const topRatedContent =
@@ -1214,7 +1380,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1214
1380
  ) : null;
1215
1381
 
1216
1382
  /* ==================================================================== */
1217
- /* FAVORITE */
1383
+ /* FAVORITE */
1218
1384
  /* ==================================================================== */
1219
1385
 
1220
1386
  const favoriteContent = showFavorite ? (
@@ -1232,6 +1398,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1232
1398
  }}
1233
1399
  style={[
1234
1400
  styles.favoriteButton,
1401
+
1235
1402
  {
1236
1403
  width: favoriteButtonSize,
1237
1404
 
@@ -1241,6 +1408,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1241
1408
 
1242
1409
  backgroundColor: favoriteBackgroundColor,
1243
1410
  },
1411
+
1244
1412
  favoriteStyle,
1245
1413
  ]}
1246
1414
  accessibilityRole="button"
@@ -1261,7 +1429,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1261
1429
  ) : null;
1262
1430
 
1263
1431
  /* ==================================================================== */
1264
- /* DISCOUNT */
1432
+ /* DISCOUNT */
1265
1433
  /* ==================================================================== */
1266
1434
 
1267
1435
  const discountContent =
@@ -1275,18 +1443,22 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1275
1443
  <View
1276
1444
  style={[
1277
1445
  styles.discountBadge,
1446
+
1278
1447
  {
1279
1448
  backgroundColor: discountBackgroundColor,
1280
1449
  },
1450
+
1281
1451
  discountStyle,
1282
1452
  ]}
1283
1453
  >
1284
1454
  <Text
1285
1455
  style={[
1286
1456
  styles.discountText,
1457
+
1287
1458
  {
1288
1459
  color: discountColor,
1289
1460
  },
1461
+
1290
1462
  discountTextStyle,
1291
1463
  ]}
1292
1464
  >
@@ -1297,7 +1469,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1297
1469
  ) : null;
1298
1470
 
1299
1471
  /* ==================================================================== */
1300
- /* RATING */
1472
+ /* RATING */
1301
1473
  /* ==================================================================== */
1302
1474
 
1303
1475
  const ratingContent = showRating ? (
@@ -1323,7 +1495,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1323
1495
  ) : null;
1324
1496
 
1325
1497
  /* ==================================================================== */
1326
- /* TAGS */
1498
+ /* TAGS */
1327
1499
  /* ==================================================================== */
1328
1500
 
1329
1501
  const tagsContent =
@@ -1345,7 +1517,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1345
1517
  );
1346
1518
 
1347
1519
  /* ==================================================================== */
1348
- /* DELIVERY */
1520
+ /* DELIVERY */
1349
1521
  /* ==================================================================== */
1350
1522
 
1351
1523
  const deliveryContent =
@@ -1367,7 +1539,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1367
1539
  );
1368
1540
 
1369
1541
  /* ==================================================================== */
1370
- /* DISTANCE */
1542
+ /* DISTANCE */
1371
1543
  /* ==================================================================== */
1372
1544
 
1373
1545
  const distanceContent =
@@ -1389,7 +1561,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1389
1561
  );
1390
1562
 
1391
1563
  /* ==================================================================== */
1392
- /* FREE DELIVERY */
1564
+ /* FREE DELIVERY */
1393
1565
  /* ==================================================================== */
1394
1566
 
1395
1567
  const freeDeliveryContent = resolvedFreeDelivery ? (
@@ -1437,7 +1609,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1437
1609
  ) : null;
1438
1610
 
1439
1611
  /* ==================================================================== */
1440
- /* LOGO */
1612
+ /* LOGO */
1441
1613
  /* ==================================================================== */
1442
1614
 
1443
1615
  const logoContent =
@@ -1451,6 +1623,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1451
1623
  <View
1452
1624
  style={[
1453
1625
  styles.logoContainer,
1626
+
1454
1627
  {
1455
1628
  width: logoSize,
1456
1629
 
@@ -1458,6 +1631,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1458
1631
 
1459
1632
  borderRadius: logoBorderRadius,
1460
1633
  },
1634
+
1461
1635
  logoStyle,
1462
1636
  ]}
1463
1637
  >
@@ -1466,6 +1640,7 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1466
1640
  resizeMode="cover"
1467
1641
  style={{
1468
1642
  width: logoSize,
1643
+
1469
1644
  height: logoSize,
1470
1645
  }}
1471
1646
  />
@@ -1474,22 +1649,24 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1474
1649
  ) : null;
1475
1650
 
1476
1651
  /* ==================================================================== */
1477
- /* DEFAULT CONTENT */
1652
+ /* DEFAULT CONTENT */
1478
1653
  /* ==================================================================== */
1479
1654
 
1480
1655
  const defaultContent = (
1481
1656
  <View
1482
1657
  style={[
1483
1658
  styles.content,
1659
+
1484
1660
  {
1485
1661
  paddingHorizontal: spacing.lg ?? 16,
1486
1662
  },
1663
+
1487
1664
  contentStyle,
1488
1665
  ]}
1489
1666
  >
1490
- {/* --------------------------------------------------------------- */}
1491
- {/* NAME + RATING */}
1492
- {/* --------------------------------------------------------------- */}
1667
+ {/* ================================================================ */}
1668
+ {/* NAME + RATING */}
1669
+ {/* ================================================================ */}
1493
1670
 
1494
1671
  <View style={styles.titleRow}>
1495
1672
  <View style={styles.titleContainer}>
@@ -1497,9 +1674,11 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1497
1674
  numberOfLines={1}
1498
1675
  style={[
1499
1676
  styles.restaurantName,
1677
+
1500
1678
  {
1501
1679
  color: resolvedNameColor,
1502
1680
  },
1681
+
1503
1682
  nameStyle,
1504
1683
  ]}
1505
1684
  >
@@ -1511,9 +1690,11 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1511
1690
  numberOfLines={1}
1512
1691
  style={[
1513
1692
  styles.restaurantSubtitle,
1693
+
1514
1694
  {
1515
1695
  color: resolvedSubtitleColor,
1516
1696
  },
1697
+
1517
1698
  subtitleStyle,
1518
1699
  ]}
1519
1700
  >
@@ -1525,22 +1706,23 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1525
1706
  {ratingContent}
1526
1707
  </View>
1527
1708
 
1528
- {/* --------------------------------------------------------------- */}
1529
- {/* CUISINES */}
1530
- {/* --------------------------------------------------------------- */}
1709
+ {/* ================================================================ */}
1710
+ {/* CUISINES */}
1711
+ {/* ================================================================ */}
1531
1712
 
1532
1713
  {tagsContent ? (
1533
1714
  <View style={styles.tagsWrapper}>{tagsContent}</View>
1534
1715
  ) : null}
1535
1716
 
1536
- {/* --------------------------------------------------------------- */}
1537
- {/* DIVIDER */}
1538
- {/* --------------------------------------------------------------- */}
1717
+ {/* ================================================================ */}
1718
+ {/* DIVIDER */}
1719
+ {/* ================================================================ */}
1539
1720
 
1540
1721
  {showDivider ? (
1541
1722
  <View
1542
1723
  style={[
1543
1724
  styles.divider,
1725
+
1544
1726
  {
1545
1727
  backgroundColor: resolvedDividerColor,
1546
1728
  },
@@ -1548,9 +1730,9 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1548
1730
  />
1549
1731
  ) : null}
1550
1732
 
1551
- {/* --------------------------------------------------------------- */}
1552
- {/* DELIVERY INFO */}
1553
- {/* --------------------------------------------------------------- */}
1733
+ {/* ================================================================ */}
1734
+ {/* INFO */}
1735
+ {/* ================================================================ */}
1554
1736
 
1555
1737
  <View style={styles.infoRow}>
1556
1738
  {deliveryContent}
@@ -1560,9 +1742,9 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1560
1742
  {freeDeliveryContent}
1561
1743
  </View>
1562
1744
 
1563
- {/* --------------------------------------------------------------- */}
1564
- {/* CUSTOM FOOTER */}
1565
- {/* --------------------------------------------------------------- */}
1745
+ {/* ================================================================ */}
1746
+ {/* FOOTER */}
1747
+ {/* ================================================================ */}
1566
1748
 
1567
1749
  {typeof renderFooter === "function"
1568
1750
  ? renderFooter({
@@ -1578,16 +1760,21 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1578
1760
  typeof renderContent === "function"
1579
1761
  ? renderContent({
1580
1762
  restaurant,
1763
+
1581
1764
  rating: resolvedRating,
1765
+
1582
1766
  reviewCount: resolvedReviewCount,
1767
+
1583
1768
  cuisines: resolvedCuisines,
1769
+
1584
1770
  deliveryTime: resolvedDeliveryTime,
1771
+
1585
1772
  distance: resolvedDistance,
1586
1773
  })
1587
1774
  : defaultContent;
1588
1775
 
1589
1776
  /* ==================================================================== */
1590
- /* CARD */
1777
+ /* FINAL CARD */
1591
1778
  /* ==================================================================== */
1592
1779
 
1593
1780
  return (
@@ -1597,7 +1784,9 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1597
1784
 
1598
1785
  {
1599
1786
  width,
1787
+
1600
1788
  borderRadius: cardRadius,
1789
+
1601
1790
  backgroundColor: cardColor,
1602
1791
  },
1603
1792
 
@@ -1611,18 +1800,20 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1611
1800
  <View
1612
1801
  style={[
1613
1802
  styles.cardInner,
1803
+
1614
1804
  {
1615
1805
  borderRadius: cardRadius,
1616
1806
  },
1617
1807
  ]}
1618
1808
  >
1619
- {/* ============================================================= */}
1620
- {/* IMAGE SECTION */}
1621
- {/* ============================================================= */}
1809
+ {/* ============================================================ */}
1810
+ {/* IMAGE */}
1811
+ {/* ============================================================ */}
1622
1812
 
1623
1813
  <View
1624
1814
  style={[
1625
1815
  styles.imageSection,
1816
+
1626
1817
  {
1627
1818
  height: imageHeight,
1628
1819
 
@@ -1632,22 +1823,22 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1632
1823
  },
1633
1824
  ]}
1634
1825
  >
1635
- {/* IMAGE CAROUSEL */}
1636
-
1637
1826
  {imageContent}
1638
1827
 
1639
- {/* =========================================================== */}
1640
- {/* TOP OVERLAY */}
1641
- {/* =========================================================== */}
1828
+ {/* ========================================================== */}
1829
+ {/* TOP CONTROLS */}
1830
+ {/* ========================================================== */}
1642
1831
 
1643
- <View style={styles.topOverlay} pointerEvents="box-none">
1832
+ <View pointerEvents="box-none" style={styles.topOverlay}>
1644
1833
  {/* TOP RATED */}
1645
1834
 
1646
1835
  {topRatedContent ? (
1647
1836
  <View style={styles.topRatedPosition} pointerEvents="auto">
1648
1837
  {topRatedContent}
1649
1838
  </View>
1650
- ) : null}
1839
+ ) : (
1840
+ <View />
1841
+ )}
1651
1842
 
1652
1843
  {/* FAVORITE */}
1653
1844
 
@@ -1658,24 +1849,25 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1658
1849
  ) : null}
1659
1850
  </View>
1660
1851
 
1661
- {/* =========================================================== */}
1852
+ {/* ========================================================== */}
1662
1853
  {/* DISCOUNT */}
1663
- {/* =========================================================== */}
1854
+ {/* ========================================================== */}
1664
1855
 
1665
1856
  {discountContent ? (
1666
1857
  <View style={styles.discountPosition}>{discountContent}</View>
1667
1858
  ) : null}
1668
1859
  </View>
1669
1860
 
1670
- {/* ============================================================= */}
1671
- {/* LOGO */}
1672
- {/* ============================================================= */}
1861
+ {/* ============================================================ */}
1862
+ {/* LOGO */}
1863
+ {/* ============================================================ */}
1673
1864
 
1674
1865
  {logoContent ? (
1675
1866
  <View
1676
1867
  pointerEvents="none"
1677
1868
  style={[
1678
1869
  styles.logoPosition,
1870
+
1679
1871
  {
1680
1872
  left: spacing.lg ?? 16,
1681
1873
 
@@ -1687,9 +1879,9 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1687
1879
  </View>
1688
1880
  ) : null}
1689
1881
 
1690
- {/* ============================================================= */}
1691
- {/* CONTENT */}
1692
- {/* ============================================================= */}
1882
+ {/* ============================================================ */}
1883
+ {/* CONTENT */}
1884
+ {/* ============================================================ */}
1693
1885
 
1694
1886
  <Pressable
1695
1887
  disabled={disabled}
@@ -1697,13 +1889,6 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1697
1889
  onLongPress={handleLongPress}
1698
1890
  onPressIn={handlePressIn}
1699
1891
  onPressOut={handlePressOut}
1700
- style={({ pressed }) => [
1701
- pressed && !reanimated
1702
- ? {
1703
- opacity: 0.96,
1704
- }
1705
- : null,
1706
- ]}
1707
1892
  >
1708
1893
  {content}
1709
1894
  </Pressable>
@@ -1712,9 +1897,9 @@ export const UIRestaurantCard = memo(function UIRestaurantCard({
1712
1897
  );
1713
1898
  });
1714
1899
 
1715
- /* ========================================================================== */
1716
- /* STYLES */
1717
- /* ========================================================================== */
1900
+ /* ==========================================================================
1901
+ * STYLES
1902
+ * ========================================================================== */
1718
1903
 
1719
1904
  const styles = StyleSheet.create({
1720
1905
  /* ---------------------------------------------------------------------- */
@@ -1727,6 +1912,7 @@ const styles = StyleSheet.create({
1727
1912
 
1728
1913
  cardInner: {
1729
1914
  width: "100%",
1915
+
1730
1916
  overflow: "hidden",
1731
1917
  },
1732
1918
 
@@ -2192,3 +2378,15 @@ const styles = StyleSheet.create({
2192
2378
  });
2193
2379
 
2194
2380
  export default UIRestaurantCard;
2381
+
2382
+ /* ==========================================================================
2383
+ * NAMED EXPORTS
2384
+ * ========================================================================== */
2385
+
2386
+ export {
2387
+ RestaurantImageCarousel,
2388
+ TopRatedBadge,
2389
+ Rating,
2390
+ CuisineTags,
2391
+ InfoItem,
2392
+ };
@@ -1 +1,9 @@
1
- export { default, UIRestaurantCard } from "./UIRestaurantCard";
1
+ export {
2
+ default,
3
+ UIRestaurantCard,
4
+ RestaurantImageCarousel,
5
+ TopRatedBadge,
6
+ Rating,
7
+ CuisineTags,
8
+ InfoItem,
9
+ } from "./UIRestaurantCard";
@@ -157,4 +157,11 @@ export {
157
157
  UICategoryItem,
158
158
  UICategorySizeConfig,
159
159
  } from "./UICategory";
160
- export { default as UIRestaurantCard } from "./UIRestaurantCard";
160
+ export {
161
+ default as UIRestaurantCard,
162
+ RestaurantImageCarousel,
163
+ TopRatedBadge,
164
+ Rating,
165
+ CuisineTags,
166
+ InfoItem,
167
+ } from "./UIRestaurantCard";