@xhub-short/ui 1.0.0-beta.24 → 1.0.0-beta.26
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-26KDWJRI.js → chunk-3OB3OVYR.js} +1 -1
- package/dist/{chunk-4WTGO44D.js → chunk-7WXAQHJI.js} +1 -1
- package/dist/{chunk-K3YQHGDX.js → chunk-BNI7CYRI.js} +1 -1
- package/dist/{chunk-OM4L7RE5.js → chunk-JM76QJ4H.js} +4 -1
- package/dist/{chunk-AKLFOFWW.js → chunk-MFJS65C5.js} +1 -144
- package/dist/{chunk-C27FC7E2.js → chunk-NJXIYSDZ.js} +0 -1
- package/dist/{chunk-7QQREYXV.js → chunk-VJ744W5N.js} +6 -110
- package/dist/components/ActionBar/index.d.ts +1 -1
- package/dist/components/ActionBar/index.js +1 -1
- package/dist/components/ArticleSlot/index.js +1 -1
- package/dist/components/AuthorInfo/index.d.ts +1 -1
- package/dist/components/AuthorInfo/index.js +1 -1
- package/dist/components/VideoInfo/index.d.ts +1 -1
- package/dist/components/VideoInfo/index.js +1 -1
- package/dist/components/VideoPlayer/index.js +1 -1
- package/dist/components/VideoSlot/index.d.ts +2 -14
- package/dist/components/VideoSlot/index.js +2 -2
- package/dist/index.d.ts +1 -88
- package/dist/index.js +7 -9
- package/package.json +4 -4
- package/dist/chunk-TJCPW4AO.js +0 -105
- package/dist/chunk-UTLVQ3FL.js +0 -244
- package/dist/components/ZoomableContainer/index.d.ts +0 -39
- package/dist/components/ZoomableContainer/index.js +0 -1
package/dist/chunk-UTLVQ3FL.js
DELETED
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
import { useState, useRef, useCallback } from 'react';
|
|
2
|
-
|
|
3
|
-
// src/hooks/usePinchZoom.ts
|
|
4
|
-
var DEFAULT_MIN_SCALE = 1;
|
|
5
|
-
var DEFAULT_MAX_SCALE = 3;
|
|
6
|
-
var PINCH_THRESHOLD = 5;
|
|
7
|
-
var ZOOM_THRESHOLD = 1.05;
|
|
8
|
-
var RESET_ANIMATION_MS = 200;
|
|
9
|
-
function getTouchDistance(t1, t2) {
|
|
10
|
-
const dx = t1.clientX - t2.clientX;
|
|
11
|
-
const dy = t1.clientY - t2.clientY;
|
|
12
|
-
return Math.sqrt(dx * dx + dy * dy);
|
|
13
|
-
}
|
|
14
|
-
function getTouchMidpoint(t1, t2) {
|
|
15
|
-
return {
|
|
16
|
-
x: (t1.clientX + t2.clientX) / 2,
|
|
17
|
-
y: (t1.clientY + t2.clientY) / 2
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
function clamp(value, min, max) {
|
|
21
|
-
return Math.min(max, Math.max(min, value));
|
|
22
|
-
}
|
|
23
|
-
function usePinchZoom({
|
|
24
|
-
containerRef,
|
|
25
|
-
minScale = DEFAULT_MIN_SCALE,
|
|
26
|
-
maxScale = DEFAULT_MAX_SCALE,
|
|
27
|
-
disabled = false,
|
|
28
|
-
onZoomStart,
|
|
29
|
-
onZoomEnd,
|
|
30
|
-
onZoomReset
|
|
31
|
-
}) {
|
|
32
|
-
const [scale, setScale] = useState(1);
|
|
33
|
-
const [translateX, setTranslateX] = useState(0);
|
|
34
|
-
const [translateY, setTranslateY] = useState(0);
|
|
35
|
-
const [isPinching, setIsPinching] = useState(false);
|
|
36
|
-
const isAnimatingRef = useRef(false);
|
|
37
|
-
const scaleRef = useRef(1);
|
|
38
|
-
const txRef = useRef(0);
|
|
39
|
-
const tyRef = useRef(0);
|
|
40
|
-
const initialDistanceRef = useRef(0);
|
|
41
|
-
const baseScaleRef = useRef(1);
|
|
42
|
-
const pinchActivatedRef = useRef(false);
|
|
43
|
-
const lastPanRef = useRef(null);
|
|
44
|
-
const isPanningRef = useRef(false);
|
|
45
|
-
const contentElementRef = useRef(null);
|
|
46
|
-
const rafRef = useRef(null);
|
|
47
|
-
const applyTransform = useCallback(
|
|
48
|
-
(s, tx, ty) => {
|
|
49
|
-
if (rafRef.current) {
|
|
50
|
-
cancelAnimationFrame(rafRef.current);
|
|
51
|
-
}
|
|
52
|
-
rafRef.current = requestAnimationFrame(() => {
|
|
53
|
-
const el = contentElementRef.current ?? containerRef.current?.firstElementChild;
|
|
54
|
-
if (el instanceof HTMLElement) {
|
|
55
|
-
contentElementRef.current = el;
|
|
56
|
-
el.style.transform = `scale(${s}) translate(${tx}px, ${ty}px)`;
|
|
57
|
-
}
|
|
58
|
-
rafRef.current = null;
|
|
59
|
-
});
|
|
60
|
-
},
|
|
61
|
-
[containerRef]
|
|
62
|
-
);
|
|
63
|
-
const clampTranslation = useCallback(
|
|
64
|
-
(tx, ty, currentScale) => {
|
|
65
|
-
if (currentScale <= 1) return { x: 0, y: 0 };
|
|
66
|
-
const container = containerRef.current;
|
|
67
|
-
if (!container) return { x: tx, y: ty };
|
|
68
|
-
const rect = container.getBoundingClientRect();
|
|
69
|
-
const maxTx = (currentScale - 1) * rect.width / (2 * currentScale);
|
|
70
|
-
const maxTy = (currentScale - 1) * rect.height / (2 * currentScale);
|
|
71
|
-
return {
|
|
72
|
-
x: clamp(tx, -maxTx, maxTx),
|
|
73
|
-
y: clamp(ty, -maxTy, maxTy)
|
|
74
|
-
};
|
|
75
|
-
},
|
|
76
|
-
[containerRef]
|
|
77
|
-
);
|
|
78
|
-
const handleTouchStart = useCallback(
|
|
79
|
-
(e) => {
|
|
80
|
-
if (disabled) return;
|
|
81
|
-
const touches = e.touches;
|
|
82
|
-
if (touches.length === 2) {
|
|
83
|
-
const t0 = touches[0];
|
|
84
|
-
const t1 = touches[1];
|
|
85
|
-
if (!t0 || !t1) return;
|
|
86
|
-
e.preventDefault();
|
|
87
|
-
const distance = getTouchDistance(t0, t1);
|
|
88
|
-
initialDistanceRef.current = distance;
|
|
89
|
-
baseScaleRef.current = scaleRef.current;
|
|
90
|
-
pinchActivatedRef.current = false;
|
|
91
|
-
isPanningRef.current = false;
|
|
92
|
-
lastPanRef.current = null;
|
|
93
|
-
setIsPinching(true);
|
|
94
|
-
onZoomStart?.();
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
if (touches.length === 1 && scaleRef.current > ZOOM_THRESHOLD) {
|
|
98
|
-
const t0 = touches[0];
|
|
99
|
-
if (!t0) return;
|
|
100
|
-
e.preventDefault();
|
|
101
|
-
isPanningRef.current = true;
|
|
102
|
-
lastPanRef.current = {
|
|
103
|
-
x: t0.clientX,
|
|
104
|
-
y: t0.clientY
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
|
-
[disabled, onZoomStart]
|
|
109
|
-
);
|
|
110
|
-
const handleTouchMove = useCallback(
|
|
111
|
-
(e) => {
|
|
112
|
-
if (disabled) return;
|
|
113
|
-
const touches = e.touches;
|
|
114
|
-
if (touches.length === 2) {
|
|
115
|
-
const t0 = touches[0];
|
|
116
|
-
const t1 = touches[1];
|
|
117
|
-
if (!t0 || !t1) return;
|
|
118
|
-
e.preventDefault();
|
|
119
|
-
const distance = getTouchDistance(t0, t1);
|
|
120
|
-
if (!pinchActivatedRef.current && Math.abs(distance - initialDistanceRef.current) < PINCH_THRESHOLD) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
pinchActivatedRef.current = true;
|
|
124
|
-
const ratio = distance / initialDistanceRef.current;
|
|
125
|
-
const newScale = clamp(baseScaleRef.current * ratio, minScale, maxScale);
|
|
126
|
-
const container = containerRef.current;
|
|
127
|
-
if (container) {
|
|
128
|
-
const rect = container.getBoundingClientRect();
|
|
129
|
-
const midpoint = getTouchMidpoint(t0, t1);
|
|
130
|
-
const centerX = rect.left + rect.width / 2;
|
|
131
|
-
const centerY = rect.top + rect.height / 2;
|
|
132
|
-
const offsetX = (midpoint.x - centerX) / newScale;
|
|
133
|
-
const offsetY = (midpoint.y - centerY) / newScale;
|
|
134
|
-
const scaleDelta = newScale - scaleRef.current;
|
|
135
|
-
const newTx = txRef.current - offsetX * scaleDelta / newScale;
|
|
136
|
-
const newTy = tyRef.current - offsetY * scaleDelta / newScale;
|
|
137
|
-
const clamped = clampTranslation(newTx, newTy, newScale);
|
|
138
|
-
txRef.current = clamped.x;
|
|
139
|
-
tyRef.current = clamped.y;
|
|
140
|
-
}
|
|
141
|
-
scaleRef.current = newScale;
|
|
142
|
-
applyTransform(newScale, txRef.current, tyRef.current);
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
if (touches.length === 1 && isPanningRef.current && lastPanRef.current) {
|
|
146
|
-
const t0 = touches[0];
|
|
147
|
-
if (!t0) return;
|
|
148
|
-
e.preventDefault();
|
|
149
|
-
const dx = (t0.clientX - lastPanRef.current.x) / scaleRef.current;
|
|
150
|
-
const dy = (t0.clientY - lastPanRef.current.y) / scaleRef.current;
|
|
151
|
-
lastPanRef.current = {
|
|
152
|
-
x: t0.clientX,
|
|
153
|
-
y: t0.clientY
|
|
154
|
-
};
|
|
155
|
-
const newTx = txRef.current + dx;
|
|
156
|
-
const newTy = tyRef.current + dy;
|
|
157
|
-
const clamped = clampTranslation(newTx, newTy, scaleRef.current);
|
|
158
|
-
txRef.current = clamped.x;
|
|
159
|
-
tyRef.current = clamped.y;
|
|
160
|
-
applyTransform(scaleRef.current, clamped.x, clamped.y);
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
[disabled, minScale, maxScale, containerRef, applyTransform, clampTranslation]
|
|
164
|
-
);
|
|
165
|
-
const handleTouchEnd = useCallback(
|
|
166
|
-
(e) => {
|
|
167
|
-
if (disabled) return;
|
|
168
|
-
const touches = e.touches;
|
|
169
|
-
if (touches.length === 0) {
|
|
170
|
-
isPanningRef.current = false;
|
|
171
|
-
lastPanRef.current = null;
|
|
172
|
-
if (scaleRef.current < ZOOM_THRESHOLD) {
|
|
173
|
-
scaleRef.current = 1;
|
|
174
|
-
txRef.current = 0;
|
|
175
|
-
tyRef.current = 0;
|
|
176
|
-
applyTransform(1, 0, 0);
|
|
177
|
-
}
|
|
178
|
-
setScale(scaleRef.current);
|
|
179
|
-
setTranslateX(txRef.current);
|
|
180
|
-
setTranslateY(tyRef.current);
|
|
181
|
-
setIsPinching(false);
|
|
182
|
-
onZoomEnd?.(scaleRef.current);
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
if (touches.length === 1 && scaleRef.current > ZOOM_THRESHOLD) {
|
|
186
|
-
const t0 = touches[0];
|
|
187
|
-
if (!t0) return;
|
|
188
|
-
isPanningRef.current = true;
|
|
189
|
-
lastPanRef.current = {
|
|
190
|
-
x: t0.clientX,
|
|
191
|
-
y: t0.clientY
|
|
192
|
-
};
|
|
193
|
-
setIsPinching(false);
|
|
194
|
-
}
|
|
195
|
-
},
|
|
196
|
-
[disabled, applyTransform, onZoomEnd]
|
|
197
|
-
);
|
|
198
|
-
const resetZoom = useCallback(() => {
|
|
199
|
-
if (scaleRef.current <= 1 && txRef.current === 0 && tyRef.current === 0) {
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
isAnimatingRef.current = true;
|
|
203
|
-
scaleRef.current = 1;
|
|
204
|
-
txRef.current = 0;
|
|
205
|
-
tyRef.current = 0;
|
|
206
|
-
setScale(1);
|
|
207
|
-
setTranslateX(0);
|
|
208
|
-
setTranslateY(0);
|
|
209
|
-
const el = contentElementRef.current ?? containerRef.current?.firstElementChild;
|
|
210
|
-
if (el instanceof HTMLElement) {
|
|
211
|
-
el.style.transition = `transform ${RESET_ANIMATION_MS}ms ease-out`;
|
|
212
|
-
el.style.transform = "scale(1) translate(0px, 0px)";
|
|
213
|
-
setTimeout(() => {
|
|
214
|
-
el.style.transition = "";
|
|
215
|
-
isAnimatingRef.current = false;
|
|
216
|
-
}, RESET_ANIMATION_MS);
|
|
217
|
-
} else {
|
|
218
|
-
isAnimatingRef.current = false;
|
|
219
|
-
}
|
|
220
|
-
onZoomReset?.();
|
|
221
|
-
}, [containerRef, onZoomReset]);
|
|
222
|
-
const isZoomed = scale > ZOOM_THRESHOLD;
|
|
223
|
-
const contentStyle = {
|
|
224
|
-
transform: scale !== 1 || translateX !== 0 || translateY !== 0 ? `scale(${scale}) translate(${translateX}px, ${translateY}px)` : void 0,
|
|
225
|
-
transformOrigin: "center center",
|
|
226
|
-
willChange: isZoomed || isPinching ? "transform" : void 0,
|
|
227
|
-
touchAction: isZoomed ? "none" : void 0
|
|
228
|
-
};
|
|
229
|
-
const handlers = {
|
|
230
|
-
onTouchStart: handleTouchStart,
|
|
231
|
-
onTouchMove: handleTouchMove,
|
|
232
|
-
onTouchEnd: handleTouchEnd
|
|
233
|
-
};
|
|
234
|
-
return {
|
|
235
|
-
handlers,
|
|
236
|
-
contentStyle,
|
|
237
|
-
isZoomed,
|
|
238
|
-
isPinching,
|
|
239
|
-
resetZoom,
|
|
240
|
-
scale
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
export { usePinchZoom };
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import * as react from 'react';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
3
|
-
|
|
4
|
-
interface ZoomableContainerProps {
|
|
5
|
-
/** Content to make zoomable */
|
|
6
|
-
children: ReactNode;
|
|
7
|
-
/** When this value changes, zoom resets to 1x (e.g., video index) */
|
|
8
|
-
resetOnChange?: unknown;
|
|
9
|
-
/** Minimum scale (default: 1) */
|
|
10
|
-
minScale?: number;
|
|
11
|
-
/** Maximum scale (default: 3) */
|
|
12
|
-
maxScale?: number;
|
|
13
|
-
/** Whether zoom is disabled (default: false) */
|
|
14
|
-
disabled?: boolean;
|
|
15
|
-
/** Called when zoom gesture starts */
|
|
16
|
-
onZoomStart?: () => void;
|
|
17
|
-
/** Called when zoom gesture ends */
|
|
18
|
-
onZoomEnd?: (scale: number) => void;
|
|
19
|
-
/** Called when zoom resets */
|
|
20
|
-
onZoomReset?: () => void;
|
|
21
|
-
/** Called when zoomed state changes (for parent to disable tap/swipe) */
|
|
22
|
-
onZoomedChange?: (isZoomed: boolean) => void;
|
|
23
|
-
/** Additional class name */
|
|
24
|
-
className?: string;
|
|
25
|
-
/** Test ID */
|
|
26
|
-
testId?: string;
|
|
27
|
-
}
|
|
28
|
-
declare function ZoomableContainerBase({ children, resetOnChange, minScale, maxScale, disabled, onZoomStart, onZoomEnd, onZoomReset, onZoomedChange, className, testId, }: ZoomableContainerProps): React.ReactElement;
|
|
29
|
-
declare const ZoomableContainer: react.MemoExoticComponent<typeof ZoomableContainerBase>;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* ZoomableContainer CSS
|
|
33
|
-
*
|
|
34
|
-
* Styles for the pinch-to-zoom container.
|
|
35
|
-
* Uses CSS-in-TS pattern consistent with other components.
|
|
36
|
-
*/
|
|
37
|
-
declare const ZOOMABLE_CONTAINER_CSS = "\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * ZoomableContainer\n * Wraps content to enable pinch-to-zoom gesture\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-zoomable-container {\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n /* Prevent browser's default pinch-zoom on the container */\n touch-action: pan-y;\n}\n\n/* When zoomed, take full touch control */\n.sv-zoomable-container--zoomed {\n touch-action: none;\n}\n\n/* Content wrapper that receives the transform */\n.sv-zoomable-container__content {\n width: 100%;\n height: 100%;\n transform-origin: center center;\n}\n\n/* GPU acceleration during gesture */\n.sv-zoomable-container--active .sv-zoomable-container__content {\n will-change: transform;\n}\n";
|
|
38
|
-
|
|
39
|
-
export { ZOOMABLE_CONTAINER_CSS, ZoomableContainer, type ZoomableContainerProps };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { ZOOMABLE_CONTAINER_CSS, ZoomableContainer } from '../../chunk-TJCPW4AO.js';
|