@marianmeres/stuic 3.102.0 → 3.104.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.
|
@@ -418,11 +418,17 @@
|
|
|
418
418
|
let swipeStartTime = 0;
|
|
419
419
|
let isSwiping = false;
|
|
420
420
|
|
|
421
|
-
// ----
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
421
|
+
// ---- Tap vs drag discrimination for page/area activation ----
|
|
422
|
+
// Activation uses pointer events (pointerdown/pointerup) rather than a synthesized
|
|
423
|
+
// mouse `click`. Pointer events unify mouse + touch and fire reliably on a clean tap,
|
|
424
|
+
// even on the `touch-action: none` gesture surface where tap→click synthesis is
|
|
425
|
+
// unreliable (notably iOS Safari, worst of all on inner SVG shapes). A tap is a
|
|
426
|
+
// pointerup landing within TAP_SLOP_PX of its pointerdown; movement beyond that is a
|
|
427
|
+
// swipe/drag and does not activate.
|
|
428
|
+
|
|
429
|
+
const TAP_SLOP_PX = 10;
|
|
430
|
+
let _tapDownX = 0;
|
|
431
|
+
let _tapDownY = 0;
|
|
426
432
|
|
|
427
433
|
// ---- Zoom helpers ----
|
|
428
434
|
|
|
@@ -572,10 +578,6 @@
|
|
|
572
578
|
const clientX = "touches" in e ? e.touches[0].clientX : e.clientX;
|
|
573
579
|
const clientY = "touches" in e ? e.touches[0].clientY : e.clientY;
|
|
574
580
|
|
|
575
|
-
_wasDragged = false;
|
|
576
|
-
_dragStartClientX = clientX;
|
|
577
|
-
_dragStartClientY = clientY;
|
|
578
|
-
|
|
579
581
|
if (zoomLevel > 1) {
|
|
580
582
|
// Pan mode
|
|
581
583
|
e.preventDefault();
|
|
@@ -603,18 +605,6 @@
|
|
|
603
605
|
return;
|
|
604
606
|
}
|
|
605
607
|
|
|
606
|
-
// Track drag for page click detection
|
|
607
|
-
if (!_wasDragged) {
|
|
608
|
-
const cx = "touches" in e ? (e.touches[0]?.clientX ?? 0) : e.clientX;
|
|
609
|
-
const cy = "touches" in e ? (e.touches[0]?.clientY ?? 0) : e.clientY;
|
|
610
|
-
if (
|
|
611
|
-
Math.abs(cx - _dragStartClientX) > 5 ||
|
|
612
|
-
Math.abs(cy - _dragStartClientY) > 5
|
|
613
|
-
) {
|
|
614
|
-
_wasDragged = true;
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
608
|
// Pan
|
|
619
609
|
if (isPanning) {
|
|
620
610
|
e.preventDefault();
|
|
@@ -693,10 +683,21 @@
|
|
|
693
683
|
};
|
|
694
684
|
}
|
|
695
685
|
|
|
686
|
+
// ---- Tap (pointer) helpers for page/area activation ----
|
|
687
|
+
|
|
688
|
+
function handleTapDown(e: PointerEvent) {
|
|
689
|
+
_tapDownX = e.clientX;
|
|
690
|
+
_tapDownY = e.clientY;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
function isTap(e: PointerEvent): boolean {
|
|
694
|
+
return Math.hypot(e.clientX - _tapDownX, e.clientY - _tapDownY) <= TAP_SLOP_PX;
|
|
695
|
+
}
|
|
696
|
+
|
|
696
697
|
// ---- Page click ----
|
|
697
698
|
|
|
698
|
-
function handlePageClick(e:
|
|
699
|
-
if (!onPageClick || !page ||
|
|
699
|
+
function handlePageClick(e: PointerEvent, page: BookPage | undefined) {
|
|
700
|
+
if (!onPageClick || !page || !isTap(e)) return;
|
|
700
701
|
const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
|
|
701
702
|
const x = (e.clientX - rect.left) / rect.width;
|
|
702
703
|
const y = (e.clientY - rect.top) / rect.height;
|
|
@@ -769,7 +770,8 @@
|
|
|
769
770
|
<div
|
|
770
771
|
class={twMerge(!unstyled && "stuic-book-sheet-front", classPage)}
|
|
771
772
|
data-placeholder={!sheet.frontPage && sheet.backPage ? "" : undefined}
|
|
772
|
-
|
|
773
|
+
onpointerdown={handleTapDown}
|
|
774
|
+
onpointerup={(e) => handlePageClick(e, sheet.frontPage)}
|
|
773
775
|
>
|
|
774
776
|
{#if isNearby && sheet.frontPage}
|
|
775
777
|
{#if renderPage}
|
|
@@ -840,8 +842,9 @@
|
|
|
840
842
|
width={area.w}
|
|
841
843
|
height={area.h}
|
|
842
844
|
class={!unstyled ? "stuic-book-area" : undefined}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
+
onpointerdown={handleTapDown}
|
|
846
|
+
onpointerup={(e: PointerEvent) => {
|
|
847
|
+
if (!isTap(e)) return;
|
|
845
848
|
e.stopPropagation();
|
|
846
849
|
onAreaClick({ area, page: sheet.frontPage! });
|
|
847
850
|
}}
|
|
@@ -858,7 +861,8 @@
|
|
|
858
861
|
<div
|
|
859
862
|
class={twMerge(!unstyled && "stuic-book-sheet-back", classPage)}
|
|
860
863
|
data-placeholder={!sheet.backPage && sheet.frontPage ? "" : undefined}
|
|
861
|
-
|
|
864
|
+
onpointerdown={handleTapDown}
|
|
865
|
+
onpointerup={(e) => handlePageClick(e, sheet.backPage)}
|
|
862
866
|
>
|
|
863
867
|
{#if isNearby && sheet.backPage}
|
|
864
868
|
{#if renderPage}
|
|
@@ -925,8 +929,9 @@
|
|
|
925
929
|
width={area.w}
|
|
926
930
|
height={area.h}
|
|
927
931
|
class={!unstyled ? "stuic-book-area" : undefined}
|
|
928
|
-
|
|
929
|
-
|
|
932
|
+
onpointerdown={handleTapDown}
|
|
933
|
+
onpointerup={(e: PointerEvent) => {
|
|
934
|
+
if (!isTap(e)) return;
|
|
930
935
|
e.stopPropagation();
|
|
931
936
|
onAreaClick({ area, page: sheet.backPage! });
|
|
932
937
|
}}
|
|
@@ -389,30 +389,36 @@
|
|
|
389
389
|
============================================================================ */
|
|
390
390
|
.stuic-button[data-aspect1] {
|
|
391
391
|
aspect-ratio: 1;
|
|
392
|
-
justify-items: center;
|
|
393
392
|
}
|
|
394
393
|
|
|
394
|
+
/*
|
|
395
|
+
* Declare both dimensions instead of deriving the square from aspect-ratio +
|
|
396
|
+
* min-* on a shrink-to-fit inline-flex box. WebKit (iOS Safari) resolves the
|
|
397
|
+
* cross-axis from content width before enforcing min-width, which squeezed
|
|
398
|
+
* icon buttons into a vertical ellipse. Fixed width == height removes that
|
|
399
|
+
* derivation, so every engine renders a true square/circle.
|
|
400
|
+
*/
|
|
395
401
|
.stuic-button[data-aspect1][data-size="sm"] {
|
|
396
|
-
|
|
397
|
-
|
|
402
|
+
width: var(--stuic-button-min-height-sm);
|
|
403
|
+
height: var(--stuic-button-min-height-sm);
|
|
398
404
|
padding: var(--stuic-button-padding-y-sm);
|
|
399
405
|
}
|
|
400
406
|
|
|
401
407
|
.stuic-button[data-aspect1][data-size="md"] {
|
|
402
|
-
|
|
403
|
-
|
|
408
|
+
width: var(--stuic-button-min-height-md);
|
|
409
|
+
height: var(--stuic-button-min-height-md);
|
|
404
410
|
padding: var(--stuic-button-padding-y-md);
|
|
405
411
|
}
|
|
406
412
|
|
|
407
413
|
.stuic-button[data-aspect1][data-size="lg"] {
|
|
408
|
-
|
|
409
|
-
|
|
414
|
+
width: var(--stuic-button-min-height-lg);
|
|
415
|
+
height: var(--stuic-button-min-height-lg);
|
|
410
416
|
padding: var(--stuic-button-padding-y-lg);
|
|
411
417
|
}
|
|
412
418
|
|
|
413
419
|
.stuic-button[data-aspect1][data-size="xl"] {
|
|
414
|
-
|
|
415
|
-
|
|
420
|
+
width: var(--stuic-button-min-height-xl);
|
|
421
|
+
height: var(--stuic-button-min-height-xl);
|
|
416
422
|
padding: var(--stuic-button-padding-y-xl);
|
|
417
423
|
}
|
|
418
424
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marianmeres/stuic",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.104.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "vite dev",
|
|
6
6
|
"build": "vite build && pnpm run prepack",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"prettier": "^3.8.3",
|
|
70
70
|
"prettier-plugin-svelte": "^3.5.2",
|
|
71
71
|
"publint": "^0.3.21",
|
|
72
|
-
"svelte": "^5.
|
|
72
|
+
"svelte": "^5.56.0",
|
|
73
73
|
"svelte-check": "^4.4.8",
|
|
74
74
|
"tailwindcss": "^4.3.0",
|
|
75
75
|
"tsx": "^4.22.3",
|
|
@@ -81,14 +81,14 @@
|
|
|
81
81
|
"dependencies": {
|
|
82
82
|
"@marianmeres/clog": "^3.21.0",
|
|
83
83
|
"@marianmeres/cron": "^2.0.1",
|
|
84
|
-
"@marianmeres/design-tokens": "^1.
|
|
84
|
+
"@marianmeres/design-tokens": "^1.8.0",
|
|
85
85
|
"@marianmeres/icons-fns": "^5.0.0",
|
|
86
86
|
"@marianmeres/item-collection": "^1.4.2",
|
|
87
87
|
"@marianmeres/paging-store": "^2.1.1",
|
|
88
88
|
"@marianmeres/parse-boolean": "^2.1.0",
|
|
89
89
|
"@marianmeres/ticker": "^1.17.1",
|
|
90
90
|
"@marianmeres/tree": "^2.3.0",
|
|
91
|
-
"libphonenumber-js": "^1.13.
|
|
91
|
+
"libphonenumber-js": "^1.13.4",
|
|
92
92
|
"runed": "^0.23.4",
|
|
93
93
|
"tailwind-merge": "^3.6.0"
|
|
94
94
|
}
|