@flamingo-stack/openframe-frontend-core 0.0.396-snapshot.20260709212121 → 0.0.396
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/{chunk-IVXOR2IA.js → chunk-2PTEK3D6.js} +2 -2
- package/dist/{chunk-DB6CUWTL.cjs → chunk-6DGQPKVA.cjs} +26 -26
- package/dist/{chunk-DB6CUWTL.cjs.map → chunk-6DGQPKVA.cjs.map} +1 -1
- package/dist/{chunk-OAENYOKC.cjs → chunk-AODSKL5I.cjs} +9 -9
- package/dist/{chunk-OAENYOKC.cjs.map → chunk-AODSKL5I.cjs.map} +1 -1
- package/dist/{chunk-M6NPDNVB.cjs → chunk-CCV6Z3CL.cjs} +26 -26
- package/dist/{chunk-M6NPDNVB.cjs.map → chunk-CCV6Z3CL.cjs.map} +1 -1
- package/dist/{chunk-JNU3YPLP.js → chunk-EKYE2VJU.js} +4 -4
- package/dist/{chunk-J6TAK6HE.js → chunk-FAUC7EA3.js} +4 -4
- package/dist/{chunk-2OOZASQE.js → chunk-GA3R77TB.js} +2 -2
- package/dist/{chunk-VTR4QDL2.js → chunk-H4WIS6RJ.js} +2 -2
- package/dist/{chunk-HPQKX5IW.cjs → chunk-HEH47UTC.cjs} +15 -15
- package/dist/{chunk-HPQKX5IW.cjs.map → chunk-HEH47UTC.cjs.map} +1 -1
- package/dist/{chunk-XNAYZHPK.cjs → chunk-HNXZFKDQ.cjs} +62 -62
- package/dist/{chunk-XNAYZHPK.cjs.map → chunk-HNXZFKDQ.cjs.map} +1 -1
- package/dist/{chunk-T5F54MN4.cjs → chunk-HWJUWOXK.cjs} +12 -12
- package/dist/{chunk-T5F54MN4.cjs.map → chunk-HWJUWOXK.cjs.map} +1 -1
- package/dist/{chunk-K5FRWPWF.js → chunk-J2UHW4UM.js} +2 -2
- package/dist/{chunk-55SNCMFS.cjs → chunk-KRMGVMIO.cjs} +31 -31
- package/dist/{chunk-55SNCMFS.cjs.map → chunk-KRMGVMIO.cjs.map} +1 -1
- package/dist/{chunk-Z6PAD2UN.cjs → chunk-NAFW3LKI.cjs} +7 -7
- package/dist/{chunk-Z6PAD2UN.cjs.map → chunk-NAFW3LKI.cjs.map} +1 -1
- package/dist/{chunk-TTHTO5H5.js → chunk-NFRHBR7W.js} +4 -4
- package/dist/{chunk-3E4BDAHJ.js → chunk-OP3H7VB2.js} +2 -2
- package/dist/{chunk-ZFK4HHRX.js → chunk-PQXUY6SB.js} +2 -2
- package/dist/{chunk-43C5ECNT.cjs → chunk-RUYZ5QMK.cjs} +37 -37
- package/dist/{chunk-43C5ECNT.cjs.map → chunk-RUYZ5QMK.cjs.map} +1 -1
- package/dist/{chunk-D4F7ZLJG.js → chunk-STEM5CPV.js} +4 -4
- package/dist/{chunk-CK5UZLIN.js → chunk-SV7IJPIH.js} +5000 -5313
- package/dist/chunk-SV7IJPIH.js.map +1 -0
- package/dist/{chunk-WCDM226S.js → chunk-TIC3UE6L.js} +2 -2
- package/dist/{chunk-BB7TZ6KS.cjs → chunk-VSPNWVIE.cjs} +59 -59
- package/dist/{chunk-BB7TZ6KS.cjs.map → chunk-VSPNWVIE.cjs.map} +1 -1
- package/dist/{chunk-SBWTMJPQ.cjs → chunk-XQILJ7FF.cjs} +5 -5
- package/dist/{chunk-SBWTMJPQ.cjs.map → chunk-XQILJ7FF.cjs.map} +1 -1
- package/dist/{chunk-ZUKBC2ZX.cjs → chunk-Y36KVLBX.cjs} +798 -1111
- package/dist/chunk-Y36KVLBX.cjs.map +1 -0
- package/dist/components/case-studies/index.cjs +8 -8
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/chat/entity-cards/blog-card.d.ts +3 -6
- package/dist/components/chat/entity-cards/blog-card.d.ts.map +1 -1
- package/dist/components/chat/entity-cards/case-study-card.d.ts +3 -7
- package/dist/components/chat/entity-cards/case-study-card.d.ts.map +1 -1
- package/dist/components/chat/entity-cards/customer-interview-card.d.ts +3 -6
- package/dist/components/chat/entity-cards/customer-interview-card.d.ts.map +1 -1
- package/dist/components/chat/entity-cards/index.d.ts +0 -3
- package/dist/components/chat/entity-cards/index.d.ts.map +1 -1
- package/dist/components/chat/entity-cards/investor-update-card.d.ts +3 -6
- package/dist/components/chat/entity-cards/investor-update-card.d.ts.map +1 -1
- package/dist/components/chat/entity-cards/onboarding-guide-card.d.ts +2 -4
- package/dist/components/chat/entity-cards/onboarding-guide-card.d.ts.map +1 -1
- package/dist/components/chat/entity-cards/program-card.d.ts +5 -17
- package/dist/components/chat/entity-cards/program-card.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +2 -10
- package/dist/components/chat/index.cjs.map +1 -1
- package/dist/components/chat/index.js +1 -9
- package/dist/components/chat/types/entities/program-types.d.ts +0 -23
- package/dist/components/chat/types/entities/program-types.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/docs/index.cjs +5 -5
- package/dist/components/docs/index.js +4 -4
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/embeds/index.js +2 -2
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/faq/index.js +2 -2
- package/dist/components/features/cards-strip.d.ts.map +1 -1
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/features/video-bites-strip.d.ts.map +1 -1
- package/dist/components/help-center-pages/index.cjs +20 -20
- package/dist/components/help-center-pages/index.js +11 -11
- package/dist/components/index.cjs +120 -128
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +9 -17
- package/dist/components/index.js.map +1 -1
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/tickets/index.cjs +5 -5
- package/dist/components/tickets/index.js +4 -4
- package/dist/components/ui/index.cjs +2 -10
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.js +1 -9
- package/dist/index.cjs +2 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -9
- package/package.json +1 -1
- package/src/components/chat/entity-cards/blog-card.tsx +7 -40
- package/src/components/chat/entity-cards/case-study-card.tsx +6 -32
- package/src/components/chat/entity-cards/customer-interview-card.tsx +6 -31
- package/src/components/chat/entity-cards/index.ts +0 -18
- package/src/components/chat/entity-cards/investor-update-card.tsx +2 -28
- package/src/components/chat/entity-cards/onboarding-guide-card.tsx +1 -30
- package/src/components/chat/entity-cards/program-card.tsx +17 -69
- package/src/components/chat/types/entities/program-types.ts +0 -34
- package/src/components/features/cards-strip.tsx +8 -122
- package/src/components/features/video-bites-strip.tsx +0 -4
- package/dist/chunk-CK5UZLIN.js.map +0 -1
- package/dist/chunk-ZUKBC2ZX.cjs.map +0 -1
- package/dist/components/chat/entity-cards/entity-portrait-card.d.ts +0 -59
- package/dist/components/chat/entity-cards/entity-portrait-card.d.ts.map +0 -1
- package/dist/components/chat/entity-cards/use-cover-image-fallback.d.ts +0 -26
- package/dist/components/chat/entity-cards/use-cover-image-fallback.d.ts.map +0 -1
- package/src/components/chat/entity-cards/entity-portrait-card.tsx +0 -201
- package/src/components/chat/entity-cards/use-cover-image-fallback.ts +0 -50
- /package/dist/{chunk-IVXOR2IA.js.map → chunk-2PTEK3D6.js.map} +0 -0
- /package/dist/{chunk-JNU3YPLP.js.map → chunk-EKYE2VJU.js.map} +0 -0
- /package/dist/{chunk-J6TAK6HE.js.map → chunk-FAUC7EA3.js.map} +0 -0
- /package/dist/{chunk-2OOZASQE.js.map → chunk-GA3R77TB.js.map} +0 -0
- /package/dist/{chunk-VTR4QDL2.js.map → chunk-H4WIS6RJ.js.map} +0 -0
- /package/dist/{chunk-K5FRWPWF.js.map → chunk-J2UHW4UM.js.map} +0 -0
- /package/dist/{chunk-TTHTO5H5.js.map → chunk-NFRHBR7W.js.map} +0 -0
- /package/dist/{chunk-3E4BDAHJ.js.map → chunk-OP3H7VB2.js.map} +0 -0
- /package/dist/{chunk-ZFK4HHRX.js.map → chunk-PQXUY6SB.js.map} +0 -0
- /package/dist/{chunk-D4F7ZLJG.js.map → chunk-STEM5CPV.js.map} +0 -0
- /package/dist/{chunk-WCDM226S.js.map → chunk-TIC3UE6L.js.map} +0 -0
|
@@ -284,11 +284,6 @@ export function CardsStrip<T = unknown>(props: CardsStripProps<T>): React.ReactE
|
|
|
284
284
|
// modulo the copy width each frame, so warps are invisible to it.
|
|
285
285
|
const marqueePosRef = useRef(0);
|
|
286
286
|
const glideRemainingRef = useRef(0);
|
|
287
|
-
// Velocity envelope (px/s): the marquee EASES between 0 and autoScrollSpeed
|
|
288
|
-
// (~250ms time constant) instead of binary stop/start — pause decelerates,
|
|
289
|
-
// resume accelerates from the current position (GSAP-marquee behavior;
|
|
290
|
-
// hard cuts read as jank).
|
|
291
|
-
const speedEnvRef = useRef(0);
|
|
292
287
|
useEffect(() => {
|
|
293
288
|
if (!marqueeActive) return;
|
|
294
289
|
const scroller = scrollerRef.current;
|
|
@@ -306,21 +301,11 @@ export function CardsStrip<T = unknown>(props: CardsStripProps<T>): React.ReactE
|
|
|
306
301
|
const tick = (now: number) => {
|
|
307
302
|
const dt = Math.min(now - last, 100) / 1000; // clamp tab-wake jumps
|
|
308
303
|
last = now;
|
|
309
|
-
// Container-level pause (industry-standard marquee behavior): the
|
|
310
|
-
// marquee freezes whenever a hover-capable pointer is ANYWHERE over the
|
|
311
|
-
// cards row — content must never move under a pointing cursor. Per-card
|
|
312
|
-
// activeKey still pauses for keyboard focus (no pointer involved).
|
|
313
304
|
const paused =
|
|
314
|
-
(pauseOnHover &&
|
|
305
|
+
(pauseOnHover && activeKeyRef.current !== null) ||
|
|
315
306
|
!nearViewportRef.current ||
|
|
316
307
|
document.visibilityState === 'hidden' ||
|
|
317
308
|
now < Math.max(chevronSuppressUntilRef.current, userScrollSuppressUntilRef.current);
|
|
318
|
-
// Ease the marquee velocity toward its target (0 when paused) — smooth
|
|
319
|
-
// decel on hover, smooth accel on leave, always from the CURRENT position.
|
|
320
|
-
const targetSpeed = paused ? 0 : autoScrollSpeed;
|
|
321
|
-
speedEnvRef.current += (targetSpeed - speedEnvRef.current) * Math.min(1, dt / 0.25);
|
|
322
|
-
if (targetSpeed === 0 && speedEnvRef.current < 0.5) speedEnvRef.current = 0;
|
|
323
|
-
|
|
324
309
|
const glide = glideRemainingRef.current;
|
|
325
310
|
if (glide !== 0) {
|
|
326
311
|
// Ease-out toward the chevron target; runs even while "paused"
|
|
@@ -333,26 +318,20 @@ export function CardsStrip<T = unknown>(props: CardsStripProps<T>): React.ReactE
|
|
|
333
318
|
glideRemainingRef.current = Math.abs(glide - step) < 0.5 ? 0 : glide - step;
|
|
334
319
|
marqueePosRef.current = wrap(marqueePosRef.current + step);
|
|
335
320
|
scroller.scrollLeft = marqueePosRef.current;
|
|
336
|
-
} else if (
|
|
321
|
+
} else if (!paused) {
|
|
337
322
|
// Resync after external movement (user scroll, seam warp).
|
|
338
323
|
if (Math.abs(scroller.scrollLeft - marqueePosRef.current) > 1.5) {
|
|
339
324
|
marqueePosRef.current = scroller.scrollLeft;
|
|
340
325
|
}
|
|
341
|
-
marqueePosRef.current = wrap(marqueePosRef.current +
|
|
326
|
+
marqueePosRef.current = wrap(marqueePosRef.current + autoScrollSpeed * dt);
|
|
342
327
|
scroller.scrollLeft = marqueePosRef.current;
|
|
343
328
|
} else {
|
|
344
329
|
marqueePosRef.current = scroller.scrollLeft;
|
|
345
330
|
}
|
|
346
|
-
// Track moved under a possibly-stationary pointer → re-resolve which
|
|
347
|
-
// card is hovered (declared below; stable useCallback identity, called
|
|
348
|
-
// lazily per frame so source order is irrelevant — deliberately NOT a
|
|
349
|
-
// dep, same as the activeKeyRef read above).
|
|
350
|
-
syncHoverIfScrolled();
|
|
351
331
|
raf = requestAnimationFrame(tick);
|
|
352
332
|
};
|
|
353
333
|
raf = requestAnimationFrame(tick);
|
|
354
334
|
return () => cancelAnimationFrame(raf);
|
|
355
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps -- syncHoverIfScrolled is identity-stable
|
|
356
335
|
}, [marqueeActive, autoScrollSpeed, pauseOnHover]);
|
|
357
336
|
|
|
358
337
|
// ---- hover / overlay state -----------------------------------------------------
|
|
@@ -378,72 +357,6 @@ export function CardsStrip<T = unknown>(props: CardsStripProps<T>): React.ReactE
|
|
|
378
357
|
setActiveKey(current => (current === key ? null : current));
|
|
379
358
|
}, []);
|
|
380
359
|
|
|
381
|
-
// ---- container-level hover pause + pointer-tracked activation sync ---------
|
|
382
|
-
// TWO separate concerns, deliberately decoupled (matches how production
|
|
383
|
-
// marquees — react-fast-marquee, GSAP — behave):
|
|
384
|
-
//
|
|
385
|
-
// 1. MARQUEE PAUSE is container-level: `hoverPointerRef.inside` is true
|
|
386
|
-
// whenever a hover-capable pointer is over the SCROLLER (the cards row).
|
|
387
|
-
// The rAF freezes on it, so content NEVER auto-moves under a pointing
|
|
388
|
-
// cursor — which is what made per-card boundary pausing feel flaky
|
|
389
|
-
// (cards sliding under/away from a stationary pointer don't emit
|
|
390
|
-
// pointerenter/leave, gaps caused stutter-steps, seam warps swapped the
|
|
391
|
-
// hovered card's identity mid-playback).
|
|
392
|
-
//
|
|
393
|
-
// 2. CARD ACTIVATION (overlay + video playback) stays per-card: the card/
|
|
394
|
-
// cell pointer handlers are the zero-latency path, and the
|
|
395
|
-
// elementFromPoint sync below re-resolves the card under the pointer
|
|
396
|
-
// whenever the track moves WHILE the pointer is inside (user wheel
|
|
397
|
-
// scroll, chevron glide, seam warp) — scoped to THIS strip's scroller so
|
|
398
|
-
// stacked strips can never activate/pause each other.
|
|
399
|
-
const hoverPointerRef = useRef<{ x: number; y: number; inside: boolean }>({ x: 0, y: 0, inside: false });
|
|
400
|
-
const lastHoverSyncScrollRef = useRef(-1);
|
|
401
|
-
const syncHoverToPointer = useCallback(() => {
|
|
402
|
-
const p = hoverPointerRef.current;
|
|
403
|
-
if (!p.inside) return;
|
|
404
|
-
const el = typeof document !== 'undefined' ? document.elementFromPoint(p.x, p.y) : null;
|
|
405
|
-
const cardEl = el?.closest?.('[data-strip-card-key]') as HTMLElement | null;
|
|
406
|
-
// Strip-scoped: a card from ANOTHER CardsStrip under the tracked point
|
|
407
|
-
// must read as "no card here" (stacked strips share the viewport).
|
|
408
|
-
const scoped = cardEl && scrollerRef.current?.contains(cardEl) ? cardEl : null;
|
|
409
|
-
const key = scoped?.getAttribute('data-strip-card-key') ?? null;
|
|
410
|
-
const current = activeKeyRef.current;
|
|
411
|
-
if (key === current) return;
|
|
412
|
-
if (current !== null) deactivate(current);
|
|
413
|
-
if (key !== null) activate(key);
|
|
414
|
-
}, [activate, deactivate]);
|
|
415
|
-
// Hover-capable pointers only (mouse/pen) — touch drags must not fake hover.
|
|
416
|
-
const onHoverPointerEnter = useCallback((e: React.PointerEvent) => {
|
|
417
|
-
if (e.pointerType === 'touch') return;
|
|
418
|
-
hoverPointerRef.current = { x: e.clientX, y: e.clientY, inside: true };
|
|
419
|
-
}, []);
|
|
420
|
-
const onHoverPointerMove = useCallback((e: React.PointerEvent) => {
|
|
421
|
-
if (e.pointerType === 'touch') return;
|
|
422
|
-
hoverPointerRef.current = { x: e.clientX, y: e.clientY, inside: true };
|
|
423
|
-
}, []);
|
|
424
|
-
const onHoverPointerLeave = useCallback((e: React.PointerEvent) => {
|
|
425
|
-
if (e.pointerType === 'touch') return;
|
|
426
|
-
hoverPointerRef.current.inside = false;
|
|
427
|
-
// The pointer left the whole scroller — no card can be hovered anymore
|
|
428
|
-
// (covers leave events swallowed by DOM churn under the cursor).
|
|
429
|
-
const current = activeKeyRef.current;
|
|
430
|
-
if (current !== null) deactivate(current);
|
|
431
|
-
}, [deactivate]);
|
|
432
|
-
/** Re-sync hover only when the track actually moved under the pointer.
|
|
433
|
-
* KNOWN HOT-PATH COST (intentional): while the marquee runs with the
|
|
434
|
-
* pointer parked over strip whitespace (no card → not paused), scrollLeft
|
|
435
|
-
* changes every frame, so this invokes `document.elementFromPoint` ~60×/s
|
|
436
|
-
* — a synchronous hit-test. It's inherent to detecting a card sliding
|
|
437
|
-
* under a stationary cursor; any throttle trades hover latency for it.
|
|
438
|
-
* Revisit only if profiling flags it on pages with many stacked strips. */
|
|
439
|
-
const syncHoverIfScrolled = useCallback(() => {
|
|
440
|
-
const scroller = scrollerRef.current;
|
|
441
|
-
if (!scroller) return;
|
|
442
|
-
if (scroller.scrollLeft === lastHoverSyncScrollRef.current) return;
|
|
443
|
-
lastHoverSyncScrollRef.current = scroller.scrollLeft;
|
|
444
|
-
syncHoverToPointer();
|
|
445
|
-
}, [syncHoverToPointer]);
|
|
446
|
-
|
|
447
360
|
// ---- shared card-mount gate (by ITEM index, across both copies) -------------
|
|
448
361
|
// A card and its clone show identical content half a copy-width apart. If
|
|
449
362
|
// each card gated its own expensive content (e.g. video players), a seam warp
|
|
@@ -520,15 +433,6 @@ export function CardsStrip<T = unknown>(props: CardsStripProps<T>): React.ReactE
|
|
|
520
433
|
const onUserScrollIntent = useCallback(() => {
|
|
521
434
|
userScrollSuppressUntilRef.current = performance.now() + USER_SCROLL_SUPPRESS_MS;
|
|
522
435
|
}, []);
|
|
523
|
-
// Suppress ONLY on genuine horizontal-scroll intent. Vertical page-scroll
|
|
524
|
-
// wheel events over the strip and plain clicks (pointerdown) used to arm the
|
|
525
|
-
// 3s suppression — the "marquee resumes only after a delay" bug.
|
|
526
|
-
const onWheelIntent = useCallback((e: React.WheelEvent) => {
|
|
527
|
-
if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) onUserScrollIntent();
|
|
528
|
-
}, [onUserScrollIntent]);
|
|
529
|
-
const onPointerDownIntent = useCallback((e: React.PointerEvent) => {
|
|
530
|
-
if (e.pointerType === 'touch') onUserScrollIntent();
|
|
531
|
-
}, [onUserScrollIntent]);
|
|
532
436
|
|
|
533
437
|
// Never-ending strip: warp across the clone seam on EVERY scroll (manual
|
|
534
438
|
// wheel/drag/chevron included — the rAF only wraps while the marquee runs,
|
|
@@ -541,12 +445,7 @@ export function CardsStrip<T = unknown>(props: CardsStripProps<T>): React.ReactE
|
|
|
541
445
|
marqueeActiveRef.current = marqueeActive;
|
|
542
446
|
const onSeamWarp = useCallback(() => {
|
|
543
447
|
const scroller = scrollerRef.current;
|
|
544
|
-
if (!scroller) return;
|
|
545
|
-
// Every scroll (native wheel/drag, smooth chevron scroll, marquee) moves
|
|
546
|
-
// cards under a possibly-stationary pointer — re-resolve hover regardless
|
|
547
|
-
// of marquee state (pointerenter/leave never fire for track motion).
|
|
548
|
-
syncHoverIfScrolled();
|
|
549
|
-
if (!marqueeActiveRef.current) return;
|
|
448
|
+
if (!scroller || !marqueeActiveRef.current) return;
|
|
550
449
|
const half = singleCopyWidthRef.current;
|
|
551
450
|
if (half <= 0) return;
|
|
552
451
|
let sl = scroller.scrollLeft;
|
|
@@ -560,7 +459,7 @@ export function CardsStrip<T = unknown>(props: CardsStripProps<T>): React.ReactE
|
|
|
560
459
|
marqueePosRef.current = sl;
|
|
561
460
|
}
|
|
562
461
|
lastScrollLeftRef.current = sl;
|
|
563
|
-
}, [
|
|
462
|
+
}, []);
|
|
564
463
|
|
|
565
464
|
// ---- render ----------------------------------------------------------------
|
|
566
465
|
|
|
@@ -569,15 +468,6 @@ export function CardsStrip<T = unknown>(props: CardsStripProps<T>): React.ReactE
|
|
|
569
468
|
// Seam assertion (see normalization comment above).
|
|
570
469
|
return (props.renderCard as (item: unknown, ctx: CardStripRenderCtx) => React.ReactNode)(item, ctx);
|
|
571
470
|
}
|
|
572
|
-
// Per-child DESKTOP cell-width hint: heterogeneous card designs need
|
|
573
|
-
// heterogeneous cells (wide horizontal cards vs 400px vertical cards —
|
|
574
|
-
// variable widths are native to the engine, exactly like bite ratios).
|
|
575
|
-
// Read from the child ELEMENT's `data-strip-cell-width` prop; mobile keeps
|
|
576
|
-
// the strip-level width (wide cards stack vertically below md anyway).
|
|
577
|
-
const hintedWidth = React.isValidElement(item)
|
|
578
|
-
? (item.props as Record<string, unknown>)['data-strip-cell-width']
|
|
579
|
-
: undefined;
|
|
580
|
-
const desktopWidth = typeof hintedWidth === 'number' ? hintedWidth : cardWidthDesktop;
|
|
581
471
|
// Managed cell — the ONLY place cell width / activation / clone a11y are
|
|
582
472
|
// encoded for children mode.
|
|
583
473
|
return (
|
|
@@ -586,8 +476,7 @@ export function CardsStrip<T = unknown>(props: CardsStripProps<T>): React.ReactE
|
|
|
586
476
|
// clones).
|
|
587
477
|
<div
|
|
588
478
|
className="shrink-0 self-stretch"
|
|
589
|
-
style={{ width: ctx.isMobile ? cardWidthMobile :
|
|
590
|
-
data-strip-card-key={ctx.cardKey}
|
|
479
|
+
style={{ width: ctx.isMobile ? cardWidthMobile : cardWidthDesktop, maxWidth: STRIP_CELL_MAX_WIDTH }}
|
|
591
480
|
onPointerEnter={ctx.isTouch ? undefined : () => ctx.onActivate(ctx.cardKey)}
|
|
592
481
|
onPointerLeave={ctx.isTouch ? undefined : () => ctx.onDeactivate(ctx.cardKey)}
|
|
593
482
|
// Keyboard pause parity (focus bubbles from the card's anchor; WCAG 2.2.2).
|
|
@@ -631,12 +520,9 @@ export function CardsStrip<T = unknown>(props: CardsStripProps<T>): React.ReactE
|
|
|
631
520
|
<div
|
|
632
521
|
ref={scrollerRef}
|
|
633
522
|
className="overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
|
|
634
|
-
onWheel={
|
|
523
|
+
onWheel={onUserScrollIntent}
|
|
635
524
|
onTouchStart={onUserScrollIntent}
|
|
636
|
-
onPointerDown={
|
|
637
|
-
onPointerEnter={onHoverPointerEnter}
|
|
638
|
-
onPointerMove={onHoverPointerMove}
|
|
639
|
-
onPointerLeave={onHoverPointerLeave}
|
|
525
|
+
onPointerDown={onUserScrollIntent}
|
|
640
526
|
onScroll={onSeamWarp}
|
|
641
527
|
>
|
|
642
528
|
<div ref={trackRef} data-copies={copies} className="flex w-max items-stretch gap-4">
|
|
@@ -391,10 +391,6 @@ export function VideoBiteCard({
|
|
|
391
391
|
return rootRef?.(node);
|
|
392
392
|
}}
|
|
393
393
|
aria-hidden={isClone || undefined}
|
|
394
|
-
// Hit-test marker for the strip engine's pointer-tracked hover re-sync
|
|
395
|
-
// (cards move under a stationary pointer — see cards-strip.tsx). The
|
|
396
|
-
// hover area is exactly this card root: media + overlay + toolbar.
|
|
397
|
-
data-strip-card-key={key}
|
|
398
394
|
className={cn(
|
|
399
395
|
'relative rounded-md border border-ods-border bg-ods-card overflow-hidden group/card',
|
|
400
396
|
height !== undefined ? 'shrink-0' : 'w-full',
|