@planetaexo/design-system 0.93.1 → 0.94.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.cjs +98 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +98 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -5429,10 +5429,13 @@ interface ReviewsSpotlightProps {
|
|
|
5429
5429
|
className?: string;
|
|
5430
5430
|
}
|
|
5431
5431
|
/**
|
|
5432
|
-
* ReviewsSpotlight — a
|
|
5433
|
-
*
|
|
5434
|
-
*
|
|
5435
|
-
*
|
|
5432
|
+
* ReviewsSpotlight — a swipeable row of testimonials. Each review is a
|
|
5433
|
+
* full-width slide on a native horizontal scroll-snap track, so on touch it
|
|
5434
|
+
* can be flicked one review at a time; on desktop the dots advance it. One
|
|
5435
|
+
* large serif quote with Trustpilot stars, auto-advancing through `items` with
|
|
5436
|
+
* the pagination dots synced to scroll position. Autoplay pauses on
|
|
5437
|
+
* hover / focus / active swipe and is skipped entirely under
|
|
5438
|
+
* `prefers-reduced-motion`. The dark band matches the rest of {@link NewHome}.
|
|
5436
5439
|
*/
|
|
5437
5440
|
declare function ReviewsSpotlight({ eyebrow, title, link, items, intervalMs, className, }: ReviewsSpotlightProps): react_jsx_runtime.JSX.Element | null;
|
|
5438
5441
|
|
package/dist/index.d.ts
CHANGED
|
@@ -5429,10 +5429,13 @@ interface ReviewsSpotlightProps {
|
|
|
5429
5429
|
className?: string;
|
|
5430
5430
|
}
|
|
5431
5431
|
/**
|
|
5432
|
-
* ReviewsSpotlight — a
|
|
5433
|
-
*
|
|
5434
|
-
*
|
|
5435
|
-
*
|
|
5432
|
+
* ReviewsSpotlight — a swipeable row of testimonials. Each review is a
|
|
5433
|
+
* full-width slide on a native horizontal scroll-snap track, so on touch it
|
|
5434
|
+
* can be flicked one review at a time; on desktop the dots advance it. One
|
|
5435
|
+
* large serif quote with Trustpilot stars, auto-advancing through `items` with
|
|
5436
|
+
* the pagination dots synced to scroll position. Autoplay pauses on
|
|
5437
|
+
* hover / focus / active swipe and is skipped entirely under
|
|
5438
|
+
* `prefers-reduced-motion`. The dark band matches the rest of {@link NewHome}.
|
|
5436
5439
|
*/
|
|
5437
5440
|
declare function ReviewsSpotlight({ eyebrow, title, link, items, intervalMs, className, }: ReviewsSpotlightProps): react_jsx_runtime.JSX.Element | null;
|
|
5438
5441
|
|
package/dist/index.js
CHANGED
|
@@ -20210,10 +20210,18 @@ function ReviewsSpotlight({
|
|
|
20210
20210
|
intervalMs = 7e3,
|
|
20211
20211
|
className
|
|
20212
20212
|
}) {
|
|
20213
|
+
const trackRef = React20.useRef(null);
|
|
20213
20214
|
const [index, setIndex] = React20.useState(0);
|
|
20214
|
-
const [visible, setVisible] = React20.useState(true);
|
|
20215
20215
|
const reduced = React20.useRef(false);
|
|
20216
|
-
const
|
|
20216
|
+
const hoverRef = React20.useRef(false);
|
|
20217
|
+
const focusRef = React20.useRef(false);
|
|
20218
|
+
const interactRef = React20.useRef(false);
|
|
20219
|
+
const programmaticRef = React20.useRef(false);
|
|
20220
|
+
const rafRef = React20.useRef(null);
|
|
20221
|
+
const interactTimer = React20.useRef(null);
|
|
20222
|
+
const programmaticTimer = React20.useRef(
|
|
20223
|
+
null
|
|
20224
|
+
);
|
|
20217
20225
|
React20.useEffect(() => {
|
|
20218
20226
|
var _a;
|
|
20219
20227
|
const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
@@ -20227,56 +20235,107 @@ function ReviewsSpotlight({
|
|
|
20227
20235
|
return (_a2 = mq.removeEventListener) == null ? void 0 : _a2.call(mq, "change", onChange);
|
|
20228
20236
|
};
|
|
20229
20237
|
}, []);
|
|
20230
|
-
const
|
|
20231
|
-
|
|
20232
|
-
|
|
20233
|
-
|
|
20238
|
+
const scrollToIndex = React20.useCallback((i) => {
|
|
20239
|
+
const el = trackRef.current;
|
|
20240
|
+
if (!el) return;
|
|
20241
|
+
const smooth = !reduced.current;
|
|
20242
|
+
programmaticRef.current = true;
|
|
20243
|
+
el.scrollTo({ left: i * el.clientWidth, behavior: smooth ? "smooth" : "auto" });
|
|
20244
|
+
if (programmaticTimer.current) clearTimeout(programmaticTimer.current);
|
|
20245
|
+
programmaticTimer.current = setTimeout(
|
|
20246
|
+
() => {
|
|
20247
|
+
programmaticRef.current = false;
|
|
20248
|
+
},
|
|
20249
|
+
smooth ? 600 : 50
|
|
20250
|
+
);
|
|
20251
|
+
}, []);
|
|
20252
|
+
const onScroll = React20.useCallback(() => {
|
|
20253
|
+
const el = trackRef.current;
|
|
20254
|
+
if (!el) return;
|
|
20255
|
+
if (rafRef.current) cancelAnimationFrame(rafRef.current);
|
|
20256
|
+
rafRef.current = requestAnimationFrame(() => {
|
|
20257
|
+
const i = Math.round(el.scrollLeft / Math.max(1, el.clientWidth));
|
|
20258
|
+
setIndex((prev) => prev === i ? prev : i);
|
|
20259
|
+
});
|
|
20260
|
+
if (!programmaticRef.current) {
|
|
20261
|
+
interactRef.current = true;
|
|
20262
|
+
if (interactTimer.current) clearTimeout(interactTimer.current);
|
|
20263
|
+
interactTimer.current = setTimeout(() => {
|
|
20264
|
+
interactRef.current = false;
|
|
20265
|
+
}, 1500);
|
|
20234
20266
|
}
|
|
20235
|
-
setVisible(false);
|
|
20236
|
-
swapRef.current = setTimeout(() => {
|
|
20237
|
-
setIndex((i) => resolve(i));
|
|
20238
|
-
setVisible(true);
|
|
20239
|
-
}, 260);
|
|
20240
20267
|
}, []);
|
|
20241
20268
|
React20.useEffect(() => {
|
|
20242
20269
|
if (items.length <= 1 || intervalMs <= 0) return;
|
|
20243
20270
|
const id = setInterval(() => {
|
|
20244
|
-
if (
|
|
20271
|
+
if (reduced.current) return;
|
|
20272
|
+
if (hoverRef.current || focusRef.current || interactRef.current) return;
|
|
20273
|
+
const el = trackRef.current;
|
|
20274
|
+
if (!el) return;
|
|
20275
|
+
const cur = Math.round(el.scrollLeft / Math.max(1, el.clientWidth));
|
|
20276
|
+
scrollToIndex((cur + 1) % items.length);
|
|
20245
20277
|
}, intervalMs);
|
|
20246
|
-
return () =>
|
|
20247
|
-
|
|
20248
|
-
|
|
20249
|
-
|
|
20250
|
-
|
|
20278
|
+
return () => clearInterval(id);
|
|
20279
|
+
}, [items.length, intervalMs, scrollToIndex]);
|
|
20280
|
+
React20.useEffect(
|
|
20281
|
+
() => () => {
|
|
20282
|
+
if (rafRef.current) cancelAnimationFrame(rafRef.current);
|
|
20283
|
+
if (interactTimer.current) clearTimeout(interactTimer.current);
|
|
20284
|
+
if (programmaticTimer.current) clearTimeout(programmaticTimer.current);
|
|
20285
|
+
},
|
|
20286
|
+
[]
|
|
20287
|
+
);
|
|
20251
20288
|
if (!items.length) return null;
|
|
20252
|
-
const
|
|
20253
|
-
const review = items[safe];
|
|
20289
|
+
const active = Math.min(index, items.length - 1);
|
|
20254
20290
|
return /* @__PURE__ */ jsx(
|
|
20255
20291
|
"section",
|
|
20256
20292
|
{
|
|
20257
20293
|
className: cn(SURFACE_PRIMARY_9002, "py-24 text-white sm:py-32", className),
|
|
20294
|
+
onMouseEnter: () => {
|
|
20295
|
+
hoverRef.current = true;
|
|
20296
|
+
},
|
|
20297
|
+
onMouseLeave: () => {
|
|
20298
|
+
hoverRef.current = false;
|
|
20299
|
+
},
|
|
20300
|
+
onFocus: () => {
|
|
20301
|
+
focusRef.current = true;
|
|
20302
|
+
},
|
|
20303
|
+
onBlur: () => {
|
|
20304
|
+
focusRef.current = false;
|
|
20305
|
+
},
|
|
20258
20306
|
children: /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-3xl px-6 text-center sm:px-8", children: [
|
|
20259
20307
|
eyebrow && /* @__PURE__ */ jsx("p", { className: "font-ui text-xs font-bold uppercase tracking-[0.22em] text-primary", children: eyebrow }),
|
|
20260
20308
|
/* @__PURE__ */ jsx("h2", { className: "sr-only", children: title }),
|
|
20261
|
-
/* @__PURE__ */
|
|
20309
|
+
/* @__PURE__ */ jsx(
|
|
20262
20310
|
"div",
|
|
20263
20311
|
{
|
|
20264
|
-
|
|
20265
|
-
|
|
20266
|
-
|
|
20267
|
-
|
|
20268
|
-
|
|
20269
|
-
|
|
20270
|
-
|
|
20271
|
-
|
|
20272
|
-
|
|
20273
|
-
"
|
|
20274
|
-
|
|
20275
|
-
|
|
20276
|
-
|
|
20277
|
-
|
|
20278
|
-
|
|
20279
|
-
|
|
20312
|
+
ref: trackRef,
|
|
20313
|
+
onScroll,
|
|
20314
|
+
"aria-roledescription": "carousel",
|
|
20315
|
+
"aria-label": title,
|
|
20316
|
+
className: "flex snap-x snap-mandatory overflow-x-auto scrollbar-none",
|
|
20317
|
+
children: items.map((review, i) => /* @__PURE__ */ jsxs(
|
|
20318
|
+
"div",
|
|
20319
|
+
{
|
|
20320
|
+
role: "group",
|
|
20321
|
+
"aria-roledescription": "slide",
|
|
20322
|
+
"aria-label": `Review ${i + 1} of ${items.length}`,
|
|
20323
|
+
className: "w-full shrink-0 snap-start",
|
|
20324
|
+
children: [
|
|
20325
|
+
/* @__PURE__ */ jsx("div", { className: "mt-8 flex justify-center", children: /* @__PURE__ */ jsx(TrustpilotStars, { stars: review.stars, className: "h-7 w-7" }) }),
|
|
20326
|
+
/* @__PURE__ */ jsxs("blockquote", { className: "mx-auto mt-8 flex min-h-[15rem] max-w-[20ch] items-center justify-center font-sans text-3xl font-normal italic leading-[1.3] text-white sm:min-h-[18rem] sm:text-4xl", children: [
|
|
20327
|
+
"\u201C",
|
|
20328
|
+
review.quote,
|
|
20329
|
+
"\u201D"
|
|
20330
|
+
] }),
|
|
20331
|
+
(review.author || review.location) && /* @__PURE__ */ jsxs("div", { className: "mt-6", children: [
|
|
20332
|
+
review.author && /* @__PURE__ */ jsx("p", { className: "font-ui text-base font-bold tracking-wide text-white", children: review.author }),
|
|
20333
|
+
review.location && /* @__PURE__ */ jsx("p", { className: "mt-1 font-sans text-sm text-white/55", children: review.location })
|
|
20334
|
+
] })
|
|
20335
|
+
]
|
|
20336
|
+
},
|
|
20337
|
+
i
|
|
20338
|
+
))
|
|
20280
20339
|
}
|
|
20281
20340
|
),
|
|
20282
20341
|
items.length > 1 && /* @__PURE__ */ jsx("div", { className: "mt-10 flex justify-center gap-2.5", children: items.map((_, i) => /* @__PURE__ */ jsx(
|
|
@@ -20284,11 +20343,11 @@ function ReviewsSpotlight({
|
|
|
20284
20343
|
{
|
|
20285
20344
|
type: "button",
|
|
20286
20345
|
"aria-label": `Show review ${i + 1} of ${items.length}`,
|
|
20287
|
-
"aria-current": i ===
|
|
20288
|
-
onClick: () =>
|
|
20346
|
+
"aria-current": i === active,
|
|
20347
|
+
onClick: () => scrollToIndex(i),
|
|
20289
20348
|
className: cn(
|
|
20290
20349
|
"h-2 w-2 rounded-full transition-colors",
|
|
20291
|
-
i ===
|
|
20350
|
+
i === active ? "bg-primary" : "bg-white/25 hover:bg-white/45"
|
|
20292
20351
|
)
|
|
20293
20352
|
},
|
|
20294
20353
|
i
|