@dododog/ui 0.13.0 → 0.14.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/dist/index.d.mts CHANGED
@@ -143,7 +143,10 @@ interface ReviewItem {
143
143
  meta?: string;
144
144
  /** Avis vérifié */
145
145
  verified?: boolean;
146
- /** Langue d'origine si traduit, ex: "l'anglais" → "Traduit de l'anglais" */
146
+ /**
147
+ * Langue d'origine si traduit, préposition incluse pour une contraction FR
148
+ * correcte : "de l'anglais" → "Traduit de l'anglais", "du russe" → "Traduit du russe".
149
+ */
147
150
  translatedFrom?: string;
148
151
  }
149
152
  interface ReviewSummaryProps extends React.HTMLAttributes<HTMLElement> {
@@ -161,8 +164,14 @@ interface ReviewSummaryProps extends React.HTMLAttributes<HTMLElement> {
161
164
  sources?: string[];
162
165
  /** Sous-notes détaillées (/10) */
163
166
  subScores?: ReviewSubScore[];
164
- /** Avis mis en avant */
167
+ /** Avis mis en avant (liste COMPLÈTE : la pagination « Voir plus » est gérée en interne) */
165
168
  reviews?: ReviewItem[];
169
+ /** Nombre d'avis affichés initialement (défaut : 8). Le reste est déplié via « Voir plus d'avis ». */
170
+ initialVisibleReviews?: number;
171
+ /** Pas de déploiement à chaque clic sur « Voir plus d'avis » (défaut : 8). */
172
+ reviewsStep?: number;
173
+ /** Libellé du bouton de déploiement progressif (défaut : « Voir plus d'avis »). */
174
+ moreReviewsLabel?: string;
166
175
  /** Callback bouton "Afficher tous les avis" */
167
176
  onSeeAll?: () => void;
168
177
  /** Libellé du bouton (par défaut dérivé du count) */
@@ -174,7 +183,7 @@ interface ReviewSummaryProps extends React.HTMLAttributes<HTMLElement> {
174
183
  * Bloc avis consolidé de la fiche hébergement (échelle /10 unique).
175
184
  * Remplace les blocs avis redondants. N'affiche que des sources réelles.
176
185
  */
177
- declare function ReviewSummary({ score, scoreLabel, count, title, countLabel, sources, subScores, reviews, onSeeAll, seeAllLabel, emptyLabel, className, ...props }: ReviewSummaryProps): react_jsx_runtime.JSX.Element;
186
+ declare function ReviewSummary({ score, scoreLabel, count, title, countLabel, sources, subScores, reviews, initialVisibleReviews, reviewsStep, moreReviewsLabel, onSeeAll, seeAllLabel, emptyLabel, className, ...props }: ReviewSummaryProps): react_jsx_runtime.JSX.Element;
178
187
 
179
188
  interface MobileBookingBarProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onSelect"> {
180
189
  /** Prix total déjà formaté, ex: "248 €" */
package/dist/index.d.ts CHANGED
@@ -143,7 +143,10 @@ interface ReviewItem {
143
143
  meta?: string;
144
144
  /** Avis vérifié */
145
145
  verified?: boolean;
146
- /** Langue d'origine si traduit, ex: "l'anglais" → "Traduit de l'anglais" */
146
+ /**
147
+ * Langue d'origine si traduit, préposition incluse pour une contraction FR
148
+ * correcte : "de l'anglais" → "Traduit de l'anglais", "du russe" → "Traduit du russe".
149
+ */
147
150
  translatedFrom?: string;
148
151
  }
149
152
  interface ReviewSummaryProps extends React.HTMLAttributes<HTMLElement> {
@@ -161,8 +164,14 @@ interface ReviewSummaryProps extends React.HTMLAttributes<HTMLElement> {
161
164
  sources?: string[];
162
165
  /** Sous-notes détaillées (/10) */
163
166
  subScores?: ReviewSubScore[];
164
- /** Avis mis en avant */
167
+ /** Avis mis en avant (liste COMPLÈTE : la pagination « Voir plus » est gérée en interne) */
165
168
  reviews?: ReviewItem[];
169
+ /** Nombre d'avis affichés initialement (défaut : 8). Le reste est déplié via « Voir plus d'avis ». */
170
+ initialVisibleReviews?: number;
171
+ /** Pas de déploiement à chaque clic sur « Voir plus d'avis » (défaut : 8). */
172
+ reviewsStep?: number;
173
+ /** Libellé du bouton de déploiement progressif (défaut : « Voir plus d'avis »). */
174
+ moreReviewsLabel?: string;
166
175
  /** Callback bouton "Afficher tous les avis" */
167
176
  onSeeAll?: () => void;
168
177
  /** Libellé du bouton (par défaut dérivé du count) */
@@ -174,7 +183,7 @@ interface ReviewSummaryProps extends React.HTMLAttributes<HTMLElement> {
174
183
  * Bloc avis consolidé de la fiche hébergement (échelle /10 unique).
175
184
  * Remplace les blocs avis redondants. N'affiche que des sources réelles.
176
185
  */
177
- declare function ReviewSummary({ score, scoreLabel, count, title, countLabel, sources, subScores, reviews, onSeeAll, seeAllLabel, emptyLabel, className, ...props }: ReviewSummaryProps): react_jsx_runtime.JSX.Element;
186
+ declare function ReviewSummary({ score, scoreLabel, count, title, countLabel, sources, subScores, reviews, initialVisibleReviews, reviewsStep, moreReviewsLabel, onSeeAll, seeAllLabel, emptyLabel, className, ...props }: ReviewSummaryProps): react_jsx_runtime.JSX.Element;
178
187
 
179
188
  interface MobileBookingBarProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onSelect"> {
180
189
  /** Prix total déjà formaté, ex: "248 €" */
package/dist/index.js CHANGED
@@ -4,8 +4,8 @@ var chunk7IJOHVNJ_js = require('./chunk-7IJOHVNJ.js');
4
4
  var chunkL7OYR6U3_js = require('./chunk-L7OYR6U3.js');
5
5
  var chunkVTELEOT7_js = require('./chunk-VTELEOT7.js');
6
6
  var chunkDTIYZ3TQ_js = require('./chunk-DTIYZ3TQ.js');
7
- var chunkBXFU7V2X_js = require('./chunk-BXFU7V2X.js');
8
7
  var chunkE6ZNND75_js = require('./chunk-E6ZNND75.js');
8
+ var chunkBXFU7V2X_js = require('./chunk-BXFU7V2X.js');
9
9
  var chunkN3JU7JS7_js = require('./chunk-N3JU7JS7.js');
10
10
  var chunkXHRDPJTF_js = require('./chunk-XHRDPJTF.js');
11
11
  var chunkTT7L3ZU7_js = require('./chunk-TT7L3ZU7.js');
@@ -15,16 +15,16 @@ var chunkOTHB7MU7_js = require('./chunk-OTHB7MU7.js');
15
15
  var chunk3VU6TPAT_js = require('./chunk-3VU6TPAT.js');
16
16
  var chunkI4S3R6C6_js = require('./chunk-I4S3R6C6.js');
17
17
  var chunk762LQMWP_js = require('./chunk-762LQMWP.js');
18
- var chunkSEHALSKW_js = require('./chunk-SEHALSKW.js');
19
18
  var chunk6KW7ZSKR_js = require('./chunk-6KW7ZSKR.js');
19
+ var chunkSEHALSKW_js = require('./chunk-SEHALSKW.js');
20
20
  var chunkOGB5LIXN_js = require('./chunk-OGB5LIXN.js');
21
21
  var chunkQWDKSY6Y_js = require('./chunk-QWDKSY6Y.js');
22
22
  var chunk3R7PT3JG_js = require('./chunk-3R7PT3JG.js');
23
23
  var chunkDS4LM7OS_js = require('./chunk-DS4LM7OS.js');
24
24
  var chunkWXSBKARZ_js = require('./chunk-WXSBKARZ.js');
25
+ var chunkSCGN5H6D_js = require('./chunk-SCGN5H6D.js');
25
26
  var chunkB4LR4H6R_js = require('./chunk-B4LR4H6R.js');
26
27
  var chunkPG4I4NWO_js = require('./chunk-PG4I4NWO.js');
27
- var chunkW7DZZS6L_js = require('./chunk-W7DZZS6L.js');
28
28
  var chunkPRDIS2VR_js = require('./chunk-PRDIS2VR.js');
29
29
  var chunkGXKON34B_js = require('./chunk-GXKON34B.js');
30
30
  var chunkTZHT7NZU_js = require('./chunk-TZHT7NZU.js');
@@ -34,11 +34,11 @@ var chunkHS3MAW3G_js = require('./chunk-HS3MAW3G.js');
34
34
  var chunkDFC6XK57_js = require('./chunk-DFC6XK57.js');
35
35
  var chunk77WKG2D7_js = require('./chunk-77WKG2D7.js');
36
36
  var chunkU3XWNFHH_js = require('./chunk-U3XWNFHH.js');
37
+ var chunkW7DZZS6L_js = require('./chunk-W7DZZS6L.js');
37
38
  var chunkTE4WHZ4Q_js = require('./chunk-TE4WHZ4Q.js');
38
39
  var chunkHN6B4TAW_js = require('./chunk-HN6B4TAW.js');
39
40
  var chunkKZSGVMUG_js = require('./chunk-KZSGVMUG.js');
40
41
  var chunkNBDPT3XQ_js = require('./chunk-NBDPT3XQ.js');
41
- var chunkSCGN5H6D_js = require('./chunk-SCGN5H6D.js');
42
42
  var chunkZCQJN4IT_js = require('./chunk-ZCQJN4IT.js');
43
43
  var chunkC4RZBOKH_js = require('./chunk-C4RZBOKH.js');
44
44
  var chunkKOO5ZXLD_js = require('./chunk-KOO5ZXLD.js');
@@ -55,27 +55,27 @@ var chunkIEHX4DU6_js = require('./chunk-IEHX4DU6.js');
55
55
  var chunkS5TLUDNM_js = require('./chunk-S5TLUDNM.js');
56
56
  var chunk7W3TFPIF_js = require('./chunk-7W3TFPIF.js');
57
57
  var chunkTJDHGNMR_js = require('./chunk-TJDHGNMR.js');
58
+ var chunkP7GAKOCX_js = require('./chunk-P7GAKOCX.js');
58
59
  var chunkMY6BYO5F_js = require('./chunk-MY6BYO5F.js');
59
60
  var chunkT4AT3YCT_js = require('./chunk-T4AT3YCT.js');
60
- var chunkIJIUUBFT_js = require('./chunk-IJIUUBFT.js');
61
- var chunkP7GAKOCX_js = require('./chunk-P7GAKOCX.js');
62
61
  var chunkAIA3NHCK_js = require('./chunk-AIA3NHCK.js');
62
+ var chunkIJIUUBFT_js = require('./chunk-IJIUUBFT.js');
63
63
  var chunkE24VNM6S_js = require('./chunk-E24VNM6S.js');
64
- require('./chunk-VNURXHKK.js');
65
64
  var chunkXXC2YD3D_js = require('./chunk-XXC2YD3D.js');
66
- var chunk6EG6EAHW_js = require('./chunk-6EG6EAHW.js');
67
- var chunkWBRVUWGC_js = require('./chunk-WBRVUWGC.js');
65
+ require('./chunk-VNURXHKK.js');
68
66
  var chunkNHB2TI2B_js = require('./chunk-NHB2TI2B.js');
69
- var chunkPND5YKFN_js = require('./chunk-PND5YKFN.js');
67
+ var chunkEY4ZIR3P_js = require('./chunk-EY4ZIR3P.js');
70
68
  var chunkZ5S7LHMY_js = require('./chunk-Z5S7LHMY.js');
69
+ var chunk6EG6EAHW_js = require('./chunk-6EG6EAHW.js');
70
+ var chunkPND5YKFN_js = require('./chunk-PND5YKFN.js');
71
71
  var chunkH3JNRTAI_js = require('./chunk-H3JNRTAI.js');
72
72
  var chunkYZTVHCLK_js = require('./chunk-YZTVHCLK.js');
73
73
  var chunkZAUYE2EI_js = require('./chunk-ZAUYE2EI.js');
74
74
  var chunkMCF3EQTV_js = require('./chunk-MCF3EQTV.js');
75
75
  var chunkG3LZ32WA_js = require('./chunk-G3LZ32WA.js');
76
76
  var chunkHB2XJOBZ_js = require('./chunk-HB2XJOBZ.js');
77
+ var chunkWBRVUWGC_js = require('./chunk-WBRVUWGC.js');
77
78
  var chunkWXEZA6NE_js = require('./chunk-WXEZA6NE.js');
78
- var chunkEY4ZIR3P_js = require('./chunk-EY4ZIR3P.js');
79
79
  var chunkADIDI7AJ_js = require('./chunk-ADIDI7AJ.js');
80
80
  var React = require('react');
81
81
  var classVarianceAuthority = require('class-variance-authority');
@@ -342,6 +342,11 @@ function DogFriendlyPanel({
342
342
  function CheckIcon2({ className }) {
343
343
  return /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", className, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6 9 17l-5-5" }) });
344
344
  }
345
+ function ChevronDownIcon({ className }) {
346
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 9 6 6 6-6" }) });
347
+ }
348
+ var DEFAULT_INITIAL_VISIBLE = 8;
349
+ var DEFAULT_REVIEWS_STEP = 8;
345
350
  function formatScore(score) {
346
351
  return score.toFixed(1).replace(".", ",");
347
352
  }
@@ -357,14 +362,21 @@ function ReviewSummary({
357
362
  sources,
358
363
  subScores,
359
364
  reviews,
365
+ initialVisibleReviews = DEFAULT_INITIAL_VISIBLE,
366
+ reviewsStep = DEFAULT_REVIEWS_STEP,
367
+ moreReviewsLabel = "Voir plus d'avis",
360
368
  onSeeAll,
361
369
  seeAllLabel,
362
370
  emptyLabel = "Peu d'avis v\xE9rifi\xE9s pour le moment",
363
371
  className,
364
372
  ...props
365
373
  }) {
366
- const hasReviews = Boolean(reviews && reviews.length > 0);
374
+ const totalReviews = reviews?.length ?? 0;
375
+ const hasReviews = totalReviews > 0;
367
376
  const isEmpty = score == null && !hasReviews;
377
+ const [visibleCount, setVisibleCount] = React__namespace.useState(initialVisibleReviews);
378
+ const visibleReviews = reviews ? reviews.slice(0, visibleCount) : [];
379
+ const hasMoreReviews = visibleCount < totalReviews;
368
380
  return /* @__PURE__ */ jsxRuntime.jsxs(
369
381
  "section",
370
382
  {
@@ -401,7 +413,7 @@ function ReviewSummary({
401
413
  },
402
414
  sub.label
403
415
  )) }) : null,
404
- hasReviews ? /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "-mx-4 flex gap-3 overflow-x-auto px-4 pb-1 [scrollbar-width:none] md:mx-0 md:px-0 [&::-webkit-scrollbar]:hidden", children: reviews.map((review, index) => /* @__PURE__ */ jsxRuntime.jsxs(
416
+ hasReviews ? /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "-mx-4 flex gap-3 overflow-x-auto px-4 pb-1 [scrollbar-width:none] md:mx-0 md:px-0 [&::-webkit-scrollbar]:hidden", children: visibleReviews.map((review, index) => /* @__PURE__ */ jsxRuntime.jsxs(
405
417
  "li",
406
418
  {
407
419
  className: "flex w-[280px] shrink-0 flex-col rounded-2xl border border-sand-dark bg-white p-4",
@@ -429,7 +441,7 @@ function ReviewSummary({
429
441
  "Avis v\xE9rifi\xE9"
430
442
  ] }) : null,
431
443
  review.translatedFrom ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs italic text-text-muted", children: [
432
- "Traduit de ",
444
+ "Traduit ",
433
445
  review.translatedFrom
434
446
  ] }) : null
435
447
  ] })
@@ -438,6 +450,20 @@ function ReviewSummary({
438
450
  },
439
451
  `${review.author}-${index}`
440
452
  )) }) : null,
453
+ hasMoreReviews ? /* @__PURE__ */ jsxRuntime.jsxs(
454
+ "button",
455
+ {
456
+ type: "button",
457
+ onClick: () => setVisibleCount(
458
+ (current) => Math.min(current + reviewsStep, totalReviews)
459
+ ),
460
+ className: "mt-4 inline-flex w-full items-center justify-center gap-1.5 rounded-full border-[1.5px] border-primary bg-transparent px-4 py-3 text-sm font-semibold text-primary transition-colors hover:bg-primary hover:text-white",
461
+ children: [
462
+ moreReviewsLabel,
463
+ /* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon, { className: "h-4 w-4" })
464
+ ]
465
+ }
466
+ ) : null,
441
467
  onSeeAll ? /* @__PURE__ */ jsxRuntime.jsx(
442
468
  "button",
443
469
  {
@@ -524,14 +550,14 @@ Object.defineProperty(exports, "Toggle", {
524
550
  enumerable: true,
525
551
  get: function () { return chunkDTIYZ3TQ_js.Toggle; }
526
552
  });
527
- Object.defineProperty(exports, "TripHeroCard", {
528
- enumerable: true,
529
- get: function () { return chunkBXFU7V2X_js.TripHeroCard; }
530
- });
531
553
  Object.defineProperty(exports, "Tooltip", {
532
554
  enumerable: true,
533
555
  get: function () { return chunkE6ZNND75_js.Tooltip; }
534
556
  });
557
+ Object.defineProperty(exports, "TripHeroCard", {
558
+ enumerable: true,
559
+ get: function () { return chunkBXFU7V2X_js.TripHeroCard; }
560
+ });
535
561
  Object.defineProperty(exports, "VerticalMarquee", {
536
562
  enumerable: true,
537
563
  get: function () { return chunkN3JU7JS7_js.VerticalMarquee; }
@@ -584,14 +610,14 @@ Object.defineProperty(exports, "Tabs", {
584
610
  enumerable: true,
585
611
  get: function () { return chunk762LQMWP_js.Tabs; }
586
612
  });
587
- Object.defineProperty(exports, "SearchWidget", {
588
- enumerable: true,
589
- get: function () { return chunkSEHALSKW_js.SearchWidget; }
590
- });
591
613
  Object.defineProperty(exports, "SearchLoadingChecklist", {
592
614
  enumerable: true,
593
615
  get: function () { return chunk6KW7ZSKR_js.SearchLoadingChecklist; }
594
616
  });
617
+ Object.defineProperty(exports, "SearchWidget", {
618
+ enumerable: true,
619
+ get: function () { return chunkSEHALSKW_js.SearchWidget; }
620
+ });
595
621
  Object.defineProperty(exports, "SectionHeader", {
596
622
  enumerable: true,
597
623
  get: function () { return chunkOGB5LIXN_js.SectionHeader; }
@@ -620,6 +646,10 @@ Object.defineProperty(exports, "signInCalloutVariants", {
620
646
  enumerable: true,
621
647
  get: function () { return chunkWXSBKARZ_js.signInCalloutVariants; }
622
648
  });
649
+ Object.defineProperty(exports, "Pagination", {
650
+ enumerable: true,
651
+ get: function () { return chunkSCGN5H6D_js.Pagination; }
652
+ });
623
653
  Object.defineProperty(exports, "PriceDisplay", {
624
654
  enumerable: true,
625
655
  get: function () { return chunkB4LR4H6R_js.PriceDisplay; }
@@ -636,10 +666,6 @@ Object.defineProperty(exports, "progressFillVariants", {
636
666
  enumerable: true,
637
667
  get: function () { return chunkPG4I4NWO_js.progressFillVariants; }
638
668
  });
639
- Object.defineProperty(exports, "LinkCard", {
640
- enumerable: true,
641
- get: function () { return chunkW7DZZS6L_js.LinkCard; }
642
- });
643
669
  Object.defineProperty(exports, "PromoBanner", {
644
670
  enumerable: true,
645
671
  get: function () { return chunkPRDIS2VR_js.PromoBanner; }
@@ -700,6 +726,10 @@ Object.defineProperty(exports, "Lightbox", {
700
726
  enumerable: true,
701
727
  get: function () { return chunkU3XWNFHH_js.Lightbox; }
702
728
  });
729
+ Object.defineProperty(exports, "LinkCard", {
730
+ enumerable: true,
731
+ get: function () { return chunkW7DZZS6L_js.LinkCard; }
732
+ });
703
733
  Object.defineProperty(exports, "LoadingOverlay", {
704
734
  enumerable: true,
705
735
  get: function () { return chunkTE4WHZ4Q_js.LoadingOverlay; }
@@ -716,10 +746,6 @@ Object.defineProperty(exports, "Modal", {
716
746
  enumerable: true,
717
747
  get: function () { return chunkNBDPT3XQ_js.Modal; }
718
748
  });
719
- Object.defineProperty(exports, "Pagination", {
720
- enumerable: true,
721
- get: function () { return chunkSCGN5H6D_js.Pagination; }
722
- });
723
749
  Object.defineProperty(exports, "FloatingDock", {
724
750
  enumerable: true,
725
751
  get: function () { return chunkZCQJN4IT_js.FloatingDock; }
@@ -788,6 +814,10 @@ Object.defineProperty(exports, "FilterPill", {
788
814
  enumerable: true,
789
815
  get: function () { return chunkTJDHGNMR_js.FilterPill; }
790
816
  });
817
+ Object.defineProperty(exports, "Carousel", {
818
+ enumerable: true,
819
+ get: function () { return chunkP7GAKOCX_js.Carousel; }
820
+ });
791
821
  Object.defineProperty(exports, "CardList", {
792
822
  enumerable: true,
793
823
  get: function () { return chunkMY6BYO5F_js.CardList; }
@@ -796,14 +826,6 @@ Object.defineProperty(exports, "Counter", {
796
826
  enumerable: true,
797
827
  get: function () { return chunkT4AT3YCT_js.Counter; }
798
828
  });
799
- Object.defineProperty(exports, "Checkbox", {
800
- enumerable: true,
801
- get: function () { return chunkIJIUUBFT_js.Checkbox; }
802
- });
803
- Object.defineProperty(exports, "Carousel", {
804
- enumerable: true,
805
- get: function () { return chunkP7GAKOCX_js.Carousel; }
806
- });
807
829
  Object.defineProperty(exports, "DatePickerInput", {
808
830
  enumerable: true,
809
831
  get: function () { return chunkAIA3NHCK_js.DatePickerInput; }
@@ -812,6 +834,10 @@ Object.defineProperty(exports, "DateRangePicker", {
812
834
  enumerable: true,
813
835
  get: function () { return chunkAIA3NHCK_js.DateRangePicker; }
814
836
  });
837
+ Object.defineProperty(exports, "Checkbox", {
838
+ enumerable: true,
839
+ get: function () { return chunkIJIUUBFT_js.Checkbox; }
840
+ });
815
841
  Object.defineProperty(exports, "DetailList", {
816
842
  enumerable: true,
817
843
  get: function () { return chunkE24VNM6S_js.DetailList; }
@@ -820,18 +846,6 @@ Object.defineProperty(exports, "Divider", {
820
846
  enumerable: true,
821
847
  get: function () { return chunkXXC2YD3D_js.Divider; }
822
848
  });
823
- Object.defineProperty(exports, "Banner", {
824
- enumerable: true,
825
- get: function () { return chunk6EG6EAHW_js.Banner; }
826
- });
827
- Object.defineProperty(exports, "bannerVariants", {
828
- enumerable: true,
829
- get: function () { return chunk6EG6EAHW_js.bannerVariants; }
830
- });
831
- Object.defineProperty(exports, "Alert", {
832
- enumerable: true,
833
- get: function () { return chunkWBRVUWGC_js.Alert; }
834
- });
835
849
  Object.defineProperty(exports, "Autocomplete", {
836
850
  enumerable: true,
837
851
  get: function () { return chunkNHB2TI2B_js.Autocomplete; }
@@ -840,9 +854,9 @@ Object.defineProperty(exports, "autocompleteInputVariants", {
840
854
  enumerable: true,
841
855
  get: function () { return chunkNHB2TI2B_js.autocompleteInputVariants; }
842
856
  });
843
- Object.defineProperty(exports, "BottomNavBar", {
857
+ Object.defineProperty(exports, "Avatar", {
844
858
  enumerable: true,
845
- get: function () { return chunkPND5YKFN_js.BottomNavBar; }
859
+ get: function () { return chunkEY4ZIR3P_js.Avatar; }
846
860
  });
847
861
  Object.defineProperty(exports, "Badge", {
848
862
  enumerable: true,
@@ -852,6 +866,18 @@ Object.defineProperty(exports, "badgeVariants", {
852
866
  enumerable: true,
853
867
  get: function () { return chunkZ5S7LHMY_js.badgeVariants; }
854
868
  });
869
+ Object.defineProperty(exports, "Banner", {
870
+ enumerable: true,
871
+ get: function () { return chunk6EG6EAHW_js.Banner; }
872
+ });
873
+ Object.defineProperty(exports, "bannerVariants", {
874
+ enumerable: true,
875
+ get: function () { return chunk6EG6EAHW_js.bannerVariants; }
876
+ });
877
+ Object.defineProperty(exports, "BottomNavBar", {
878
+ enumerable: true,
879
+ get: function () { return chunkPND5YKFN_js.BottomNavBar; }
880
+ });
855
881
  Object.defineProperty(exports, "Breadcrumb", {
856
882
  enumerable: true,
857
883
  get: function () { return chunkH3JNRTAI_js.Breadcrumb; }
@@ -920,13 +946,13 @@ Object.defineProperty(exports, "dogAvatarColor", {
920
946
  enumerable: true,
921
947
  get: function () { return chunkHB2XJOBZ_js.dogAvatarColor; }
922
948
  });
923
- Object.defineProperty(exports, "AnchorTabs", {
949
+ Object.defineProperty(exports, "Alert", {
924
950
  enumerable: true,
925
- get: function () { return chunkWXEZA6NE_js.AnchorTabs; }
951
+ get: function () { return chunkWBRVUWGC_js.Alert; }
926
952
  });
927
- Object.defineProperty(exports, "Avatar", {
953
+ Object.defineProperty(exports, "AnchorTabs", {
928
954
  enumerable: true,
929
- get: function () { return chunkEY4ZIR3P_js.Avatar; }
955
+ get: function () { return chunkWXEZA6NE_js.AnchorTabs; }
930
956
  });
931
957
  Object.defineProperty(exports, "cn", {
932
958
  enumerable: true,
package/dist/index.mjs CHANGED
@@ -2,8 +2,8 @@ export { Tag, tagVariants } from './chunk-WOG6V7OW.mjs';
2
2
  export { Textarea, textareaVariants } from './chunk-ZZ4EWC53.mjs';
3
3
  export { Toast, toastVariants } from './chunk-YVTUUNAX.mjs';
4
4
  export { Toggle } from './chunk-2AB5ZHY5.mjs';
5
- export { TripHeroCard } from './chunk-LO2XNMZO.mjs';
6
5
  export { Tooltip } from './chunk-2MJTZ6RR.mjs';
6
+ export { TripHeroCard } from './chunk-LO2XNMZO.mjs';
7
7
  export { VerticalMarquee } from './chunk-JP5ZR2HI.mjs';
8
8
  export { Spinner, spinnerVariants } from './chunk-NCSFXSOZ.mjs';
9
9
  export { StatCard } from './chunk-O2W7NR33.mjs';
@@ -13,16 +13,16 @@ export { StayListRow } from './chunk-IVCQVBOT.mjs';
13
13
  export { Stepper } from './chunk-2ASKBL63.mjs';
14
14
  export { Switch, switchThumbVariants, switchTrackVariants } from './chunk-DMCMWOBJ.mjs';
15
15
  export { Tabs } from './chunk-VOZPGXQD.mjs';
16
- export { SearchWidget } from './chunk-DUT3ABEI.mjs';
17
16
  export { SearchLoadingChecklist } from './chunk-SRYZ4N7T.mjs';
17
+ export { SearchWidget } from './chunk-DUT3ABEI.mjs';
18
18
  export { SectionHeader } from './chunk-DM76AK4A.mjs';
19
19
  export { SegmentedControl } from './chunk-36Y7UU32.mjs';
20
20
  export { Select, selectVariants } from './chunk-333YD5QI.mjs';
21
21
  export { Sidebar } from './chunk-MPL35D5G.mjs';
22
22
  export { SignInCallout, signInCalloutVariants } from './chunk-Z3KRMKHP.mjs';
23
+ export { Pagination } from './chunk-XQVODPHL.mjs';
23
24
  export { PriceDisplay } from './chunk-REXLQTNE.mjs';
24
25
  export { ProgressBar, progressBarVariants, progressFillVariants } from './chunk-UGYMWWKT.mjs';
25
- export { LinkCard } from './chunk-UYDZKAGZ.mjs';
26
26
  export { PromoBanner, promoBannerVariants } from './chunk-FNDR3WOZ.mjs';
27
27
  export { RadioGroup } from './chunk-F2BUMJYW.mjs';
28
28
  export { Rating } from './chunk-SGDC4IVX.mjs';
@@ -32,11 +32,11 @@ export { SearchBar } from './chunk-KQK7LFWM.mjs';
32
32
  export { ImpactCard } from './chunk-IKQYFSBW.mjs';
33
33
  export { Input, inputVariants } from './chunk-GRG4USTC.mjs';
34
34
  export { Lightbox } from './chunk-GBWVIY3C.mjs';
35
+ export { LinkCard } from './chunk-UYDZKAGZ.mjs';
35
36
  export { LoadingOverlay } from './chunk-WVEJS2J2.mjs';
36
37
  export { MegaMenu } from './chunk-EUEM2D5M.mjs';
37
38
  export { MobileMenu } from './chunk-R4DC7XPP.mjs';
38
39
  export { Modal } from './chunk-74B2EGKT.mjs';
39
- export { Pagination } from './chunk-XQVODPHL.mjs';
40
40
  export { FloatingDock } from './chunk-P2SGBTKS.mjs';
41
41
  export { Footer } from './chunk-SZ3SV4SJ.mjs';
42
42
  export { GuestPicker } from './chunk-EJ7LDW7E.mjs';
@@ -53,27 +53,27 @@ export { EmptyState } from './chunk-OCUHCDAQ.mjs';
53
53
  export { ErrorBoundary } from './chunk-5257MWFI.mjs';
54
54
  export { FilterAccordion } from './chunk-VQVRKRSM.mjs';
55
55
  export { FilterPill } from './chunk-YKBASX5A.mjs';
56
+ export { Carousel } from './chunk-OOPP4ES2.mjs';
56
57
  export { CardList } from './chunk-RJWHPHHX.mjs';
57
58
  export { Counter } from './chunk-LRNSVRUN.mjs';
58
- export { Checkbox } from './chunk-EEIPCJQ2.mjs';
59
- export { Carousel } from './chunk-OOPP4ES2.mjs';
60
59
  export { DatePickerInput, DateRangePicker } from './chunk-FL3GD5FJ.mjs';
60
+ export { Checkbox } from './chunk-EEIPCJQ2.mjs';
61
61
  export { DetailList } from './chunk-N6THLJIG.mjs';
62
- import './chunk-OZULAGYL.mjs';
63
62
  export { Divider } from './chunk-E4B6LXK7.mjs';
64
- export { Banner, bannerVariants } from './chunk-LFIZX2S6.mjs';
65
- export { Alert } from './chunk-BQWVWK74.mjs';
63
+ import './chunk-OZULAGYL.mjs';
66
64
  export { Autocomplete, autocompleteInputVariants } from './chunk-B47HQHX3.mjs';
67
- export { BottomNavBar } from './chunk-UQRQZLMQ.mjs';
65
+ export { Avatar } from './chunk-2POGTS27.mjs';
68
66
  export { Badge, badgeVariants } from './chunk-XZU2SISM.mjs';
67
+ export { Banner, bannerVariants } from './chunk-LFIZX2S6.mjs';
68
+ export { BottomNavBar } from './chunk-UQRQZLMQ.mjs';
69
69
  export { Breadcrumb, breadcrumbVariants } from './chunk-UKCH6RYL.mjs';
70
70
  export { Button, buttonVariants } from './chunk-4U5MNA3B.mjs';
71
71
  export { Card, CardContent, CardDescription, CardImage, CardTitle, cardImageVariants, cardVariants } from './chunk-V5J2XLPD.mjs';
72
72
  export { Accordion } from './chunk-NZ7GF6RF.mjs';
73
73
  export { ActiveStayCard } from './chunk-CRQ4XOCC.mjs';
74
74
  export { DOG_AVATAR_COLORS, DogAvatar, DogAvatarStack, dogAvatarColor } from './chunk-AGNY5DBW.mjs';
75
+ export { Alert } from './chunk-BQWVWK74.mjs';
75
76
  export { AnchorTabs } from './chunk-M2H6QUAL.mjs';
76
- export { Avatar } from './chunk-2POGTS27.mjs';
77
77
  import { cn } from './chunk-IMKLN273.mjs';
78
78
  export { cn } from './chunk-IMKLN273.mjs';
79
79
  import * as React from 'react';
@@ -321,6 +321,11 @@ function DogFriendlyPanel({
321
321
  function CheckIcon2({ className }) {
322
322
  return /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", className, "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) });
323
323
  }
324
+ function ChevronDownIcon({ className }) {
325
+ return /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" }) });
326
+ }
327
+ var DEFAULT_INITIAL_VISIBLE = 8;
328
+ var DEFAULT_REVIEWS_STEP = 8;
324
329
  function formatScore(score) {
325
330
  return score.toFixed(1).replace(".", ",");
326
331
  }
@@ -336,14 +341,21 @@ function ReviewSummary({
336
341
  sources,
337
342
  subScores,
338
343
  reviews,
344
+ initialVisibleReviews = DEFAULT_INITIAL_VISIBLE,
345
+ reviewsStep = DEFAULT_REVIEWS_STEP,
346
+ moreReviewsLabel = "Voir plus d'avis",
339
347
  onSeeAll,
340
348
  seeAllLabel,
341
349
  emptyLabel = "Peu d'avis v\xE9rifi\xE9s pour le moment",
342
350
  className,
343
351
  ...props
344
352
  }) {
345
- const hasReviews = Boolean(reviews && reviews.length > 0);
353
+ const totalReviews = reviews?.length ?? 0;
354
+ const hasReviews = totalReviews > 0;
346
355
  const isEmpty = score == null && !hasReviews;
356
+ const [visibleCount, setVisibleCount] = React.useState(initialVisibleReviews);
357
+ const visibleReviews = reviews ? reviews.slice(0, visibleCount) : [];
358
+ const hasMoreReviews = visibleCount < totalReviews;
347
359
  return /* @__PURE__ */ jsxs(
348
360
  "section",
349
361
  {
@@ -380,7 +392,7 @@ function ReviewSummary({
380
392
  },
381
393
  sub.label
382
394
  )) }) : null,
383
- hasReviews ? /* @__PURE__ */ jsx("ul", { className: "-mx-4 flex gap-3 overflow-x-auto px-4 pb-1 [scrollbar-width:none] md:mx-0 md:px-0 [&::-webkit-scrollbar]:hidden", children: reviews.map((review, index) => /* @__PURE__ */ jsxs(
395
+ hasReviews ? /* @__PURE__ */ jsx("ul", { className: "-mx-4 flex gap-3 overflow-x-auto px-4 pb-1 [scrollbar-width:none] md:mx-0 md:px-0 [&::-webkit-scrollbar]:hidden", children: visibleReviews.map((review, index) => /* @__PURE__ */ jsxs(
384
396
  "li",
385
397
  {
386
398
  className: "flex w-[280px] shrink-0 flex-col rounded-2xl border border-sand-dark bg-white p-4",
@@ -408,7 +420,7 @@ function ReviewSummary({
408
420
  "Avis v\xE9rifi\xE9"
409
421
  ] }) : null,
410
422
  review.translatedFrom ? /* @__PURE__ */ jsxs("span", { className: "text-xs italic text-text-muted", children: [
411
- "Traduit de ",
423
+ "Traduit ",
412
424
  review.translatedFrom
413
425
  ] }) : null
414
426
  ] })
@@ -417,6 +429,20 @@ function ReviewSummary({
417
429
  },
418
430
  `${review.author}-${index}`
419
431
  )) }) : null,
432
+ hasMoreReviews ? /* @__PURE__ */ jsxs(
433
+ "button",
434
+ {
435
+ type: "button",
436
+ onClick: () => setVisibleCount(
437
+ (current) => Math.min(current + reviewsStep, totalReviews)
438
+ ),
439
+ className: "mt-4 inline-flex w-full items-center justify-center gap-1.5 rounded-full border-[1.5px] border-primary bg-transparent px-4 py-3 text-sm font-semibold text-primary transition-colors hover:bg-primary hover:text-white",
440
+ children: [
441
+ moreReviewsLabel,
442
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4" })
443
+ ]
444
+ }
445
+ ) : null,
420
446
  onSeeAll ? /* @__PURE__ */ jsx(
421
447
  "button",
422
448
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dododog/ui",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "React UI component library for DodoDog — pet-friendly travel platform",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",