@xiping/react-components 1.0.36 → 1.0.40

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.
@@ -1,98 +1,94 @@
1
1
  "use client";
2
- import { jsx as e, jsxs as i } from "react/jsx-runtime";
3
- import { Modal as S, ModalContent as D, cn as c, Spinner as O } from "@heroui/react";
2
+ import { jsx as e, jsxs as c } from "react/jsx-runtime";
3
+ import { Modal as D, ModalContent as O, Spinner as S } from "@heroui/react";
4
4
  import U from "../pinch-content/PinchContent.js";
5
5
  import A from "./ImageThumbnails.js";
6
- import { useState as u, useEffect as B } from "react";
7
- import P from "clsx";
8
- import { Download as T, X as H } from "lucide-react";
9
- import { AnimatePresence as V, motion as W } from "motion/react";
10
- const p = (o) => {
11
- o.target.closest(".image-viewer-main-content") && o.preventDefault();
12
- }, Z = (o) => {
6
+ import { useState as h, useEffect as P } from "react";
7
+ import T from "clsx";
8
+ import { Download as B, X as V } from "lucide-react";
9
+ import { AnimatePresence as W, motion as X } from "motion/react";
10
+ import { cn as l } from "../../utils/utils.js";
11
+ /* empty css */
12
+ const u = (a) => {
13
+ a.target.closest(".xiping-main-content") && a.preventDefault();
14
+ }, $ = (a) => {
13
15
  const {
14
- isOpen: t,
15
- onClose: g,
16
- imgSrc: l,
17
- thumbnailImages: w,
18
- canDownload: b = !1,
16
+ isOpen: n,
17
+ onClose: f,
18
+ imgSrc: s,
19
+ thumbnailImages: x,
20
+ canDownload: w = !1,
19
21
  wrapperClassName: v,
20
- closeClassName: y,
21
- downloadClassName: x,
22
- toolWrapperClassName: C,
23
- initialIndex: I = 0
24
- } = o, a = Array.isArray(l) ? l : [l], N = w || a, L = Math.max(0, Math.min(I, a.length - 1)), [s, E] = u(L), [j, r] = u(!0), m = () => {
25
- r(!0), g();
26
- }, k = async () => {
27
- const d = a[s];
22
+ closeClassName: C,
23
+ downloadClassName: N,
24
+ toolWrapperClassName: I,
25
+ initialIndex: b = 0
26
+ } = a, t = Array.isArray(s) ? s : [s], y = x || t, L = Math.max(
27
+ 0,
28
+ Math.min(b, t.length - 1)
29
+ ), [i, E] = h(L), [M, r] = h(!0), m = () => {
30
+ r(!0), f();
31
+ }, R = async () => {
32
+ const d = t[i];
28
33
  try {
29
- const R = await (await fetch(d)).blob(), h = window.URL.createObjectURL(R), n = document.createElement("a");
30
- n.href = h, n.download = d.split("/").pop() || "image", document.body.appendChild(n), n.click(), window.URL.revokeObjectURL(h), document.body.removeChild(n);
31
- } catch (f) {
32
- console.error("Error downloading image:", f);
34
+ const z = await (await fetch(d)).blob(), g = window.URL.createObjectURL(z), o = document.createElement("a");
35
+ o.href = g, o.download = d.split("/").pop() || "image", document.body.appendChild(o), o.click(), window.URL.revokeObjectURL(g), document.body.removeChild(o);
36
+ } catch (p) {
37
+ console.error("Error downloading image:", p);
33
38
  }
34
- }, z = () => {
39
+ }, j = () => {
35
40
  r(!1);
36
- }, M = () => {
41
+ }, k = () => {
37
42
  r(!1);
38
43
  };
39
- return B(() => {
40
- if (t)
41
- return document.addEventListener("touchmove", p, {
44
+ return P(() => {
45
+ if (n)
46
+ return document.addEventListener("touchmove", u, {
42
47
  passive: !1
43
48
  }), () => {
44
- document.removeEventListener("touchmove", p);
49
+ document.removeEventListener("touchmove", u);
45
50
  };
46
- }, [t]), /* @__PURE__ */ e(
47
- S,
51
+ }, [n]), /* @__PURE__ */ e(
52
+ D,
48
53
  {
49
- isOpen: t,
54
+ isOpen: n,
50
55
  size: "full",
51
56
  onClose: m,
52
57
  classNames: {
53
- wrapper: P("", v)
58
+ wrapper: T(v)
54
59
  },
55
- className: "bg-black/70",
60
+ className: "xiping-modal-overlay",
56
61
  hideCloseButton: !0,
57
62
  portalContainer: document.body,
58
- children: /* @__PURE__ */ e(D, { className: "overflow-hidden", children: /* @__PURE__ */ i("div", { className: "w-screen h-screen relative flex flex-col pt-safe-offset-0", children: [
59
- /* @__PURE__ */ i(
60
- "div",
61
- {
62
- className: c(
63
- "absolute top-4 right-4 flex gap-4 z-10",
64
- C
65
- ),
66
- children: [
67
- b && /* @__PURE__ */ e(
68
- T,
69
- {
70
- size: 24,
71
- className: c("text-white cursor-pointer", x),
72
- onClick: k
73
- }
74
- ),
75
- /* @__PURE__ */ e(
76
- H,
77
- {
78
- size: 24,
79
- className: c("text-white cursor-pointer", y),
80
- onClick: m
81
- }
82
- )
83
- ]
84
- }
85
- ),
86
- /* @__PURE__ */ i("div", { className: "flex-1 min-h-0 relative flex items-center justify-center image-viewer-main-content", children: [
87
- /* @__PURE__ */ e(U, { canRotate: !1, className: "w-full h-full", children: /* @__PURE__ */ e(V, { mode: "wait", children: /* @__PURE__ */ e(
88
- W.img,
63
+ children: /* @__PURE__ */ e(O, { className: "xiping-modal-content", children: /* @__PURE__ */ c("div", { className: "xiping-wrapper", children: [
64
+ /* @__PURE__ */ c("div", { className: l("xiping-tool-wrapper", I), children: [
65
+ w && /* @__PURE__ */ e(
66
+ B,
67
+ {
68
+ size: 24,
69
+ className: l("xiping-download-icon", N),
70
+ onClick: R
71
+ }
72
+ ),
73
+ /* @__PURE__ */ e(
74
+ V,
75
+ {
76
+ size: 24,
77
+ className: l("xiping-close-icon", C),
78
+ onClick: m
79
+ }
80
+ )
81
+ ] }),
82
+ /* @__PURE__ */ c("div", { className: "xiping-main-content", children: [
83
+ /* @__PURE__ */ e(U, { canRotate: !1, className: "xiping-pinch-content", children: /* @__PURE__ */ e(W, { mode: "wait", children: /* @__PURE__ */ e(
84
+ X.img,
89
85
  {
90
86
  draggable: "false",
91
- src: a[s],
87
+ src: t[i],
92
88
  alt: "",
93
- className: "w-screen h-full object-contain pointer-events-none",
94
- onLoad: z,
95
- onError: M,
89
+ className: "xiping-image",
90
+ onLoad: j,
91
+ onError: k,
96
92
  initial: { opacity: 0, scale: 0.95 },
97
93
  animate: { opacity: 1, scale: 1 },
98
94
  exit: { opacity: 0, scale: 1.05 },
@@ -101,37 +97,22 @@ const p = (o) => {
101
97
  ease: "easeInOut"
102
98
  }
103
99
  },
104
- s
100
+ i
105
101
  ) }) }),
106
- j && /* @__PURE__ */ e("div", { className: "absolute inset-0 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ e(O, { color: "white", size: "lg" }) })
102
+ M && /* @__PURE__ */ e("div", { className: "xiping-loading", children: /* @__PURE__ */ e(S, { color: "white", size: "lg" }) })
107
103
  ] }),
108
104
  /* @__PURE__ */ e(
109
105
  A,
110
106
  {
111
- images: N,
112
- currentIndex: s,
107
+ images: y,
108
+ currentIndex: i,
113
109
  onImageSelect: E
114
110
  }
115
111
  )
116
112
  ] }) })
117
113
  }
118
114
  );
119
- }, X = `
120
- .scrollbar-hide {
121
- -ms-overflow-style: none;
122
- scrollbar-width: none;
123
- }
124
- .scrollbar-hide::-webkit-scrollbar {
125
- display: none;
126
- }
127
- `;
128
- if (typeof document < "u") {
129
- const o = "image-viewer-scrollbar-hide";
130
- if (!document.getElementById(o)) {
131
- const t = document.createElement("style");
132
- t.id = o, t.textContent = X, document.head.appendChild(t);
133
- }
134
- }
115
+ };
135
116
  export {
136
- Z as default
117
+ $ as default
137
118
  };
@@ -13,6 +13,22 @@ export interface PinchContentProps {
13
13
  wheelZoomFactor?: number;
14
14
  rubberband?: boolean;
15
15
  style?: CSSProperties;
16
+ /** 外部控制的缩放值(受控模式) */
17
+ scale?: number;
18
+ /** 缩放值变化时的回调 */
19
+ onScaleChange?: (scale: number) => void;
16
20
  }
17
- declare const PinchContent: (props: PinchContentProps) => import("react/jsx-runtime").JSX.Element;
21
+ export interface PinchContentRef {
22
+ /** 放大 */
23
+ zoomIn: (factor?: number) => void;
24
+ /** 缩小 */
25
+ zoomOut: (factor?: number) => void;
26
+ /** 设置缩放值 */
27
+ setScale: (scale: number) => void;
28
+ /** 重置到初始状态 */
29
+ reset: () => void;
30
+ /** 获取当前缩放值 */
31
+ getScale: () => number;
32
+ }
33
+ declare const PinchContent: import('react').ForwardRefExoticComponent<PinchContentProps & import('react').RefAttributes<PinchContentRef>>;
18
34
  export default PinchContent;
@@ -1,86 +1,127 @@
1
- import { jsx as B } from "react/jsx-runtime";
2
- import { useSpring as C, animated as G } from "@react-spring/web";
3
- import { createUseGesture as N, dragAction as U, pinchAction as W, wheelAction as j } from "@use-gesture/react";
4
- import { useRef as F } from "react";
5
- import { useMount as k, useUnmount as q } from "ahooks";
6
- import z from "clsx";
7
- const H = N([U, W, j]), a = (c) => c.preventDefault(), V = (c) => {
8
- const {
9
- className: f,
10
- children: h,
11
- pinchWithoutMove: m = !1,
12
- canPinch: d = !0,
13
- canDrag: x = !0,
14
- canRotate: v = !0,
15
- scaleBounds: l = { min: 0.3, max: 10 },
16
- wheelZoomFactor: p = 1e-3,
17
- rubberband: y = !0
18
- } = c, e = F(null);
19
- k(() => {
20
- e.current?.addEventListener("gesturestart", a), e.current?.addEventListener("gesturechange", a), e.current?.addEventListener("gestureend", a);
21
- }), q(() => {
22
- e.current?.removeEventListener("gesturestart", a), e.current?.removeEventListener("gesturechange", a), e.current?.removeEventListener("gestureend", a);
23
- });
24
- const [t, g] = C(() => ({
25
- x: 0,
26
- y: 0,
27
- scale: 1,
28
- rotateZ: 0
29
- }));
30
- return H(
31
- {
32
- onWheel: ({ event: o, delta: [, r] }) => {
33
- if (!d) return;
34
- const n = t.scale.get() * (1 - r * p), i = Math.min(
35
- Math.max(n, l.min),
36
- l.max
1
+ import { jsx as U } from "react/jsx-runtime";
2
+ import { useSpring as W, animated as j } from "@react-spring/web";
3
+ import { createUseGesture as F, dragAction as H, pinchAction as O, wheelAction as k } from "@use-gesture/react";
4
+ import { forwardRef as q, useRef as J, useEffect as K, useImperativeHandle as Q } from "react";
5
+ import { useMount as T, useUnmount as V } from "ahooks";
6
+ import X from "clsx";
7
+ const Y = F([H, O, k]), i = (u) => u.preventDefault(), _ = q(
8
+ (u, x) => {
9
+ const {
10
+ className: p,
11
+ children: S,
12
+ pinchWithoutMove: v = !1,
13
+ canPinch: h = !0,
14
+ canDrag: y = !0,
15
+ canRotate: M = !0,
16
+ scaleBounds: r = { min: 0.3, max: 10 },
17
+ wheelZoomFactor: E = 1e-3,
18
+ rubberband: w = !0,
19
+ scale: m,
20
+ onScaleChange: d
21
+ } = u, a = J(null);
22
+ T(() => {
23
+ a.current?.addEventListener("gesturestart", i), a.current?.addEventListener("gesturechange", i), a.current?.addEventListener("gestureend", i);
24
+ }), V(() => {
25
+ a.current?.removeEventListener("gesturestart", i), a.current?.removeEventListener("gesturechange", i), a.current?.removeEventListener("gestureend", i);
26
+ });
27
+ const L = m ?? 1, [t, c] = W(() => ({
28
+ x: 0,
29
+ y: 0,
30
+ scale: L,
31
+ rotateZ: 0
32
+ }));
33
+ K(() => {
34
+ if (m !== void 0) {
35
+ const e = Math.min(
36
+ Math.max(m, r.min),
37
+ r.max
37
38
  );
38
- g.start({ scale: i });
39
+ c.start({ scale: e });
40
+ }
41
+ }, [m, r.min, r.max, c]);
42
+ const g = (e) => {
43
+ const n = Math.min(
44
+ Math.max(e, r.min),
45
+ r.max
46
+ );
47
+ c.start({ scale: n }), d?.(n);
48
+ };
49
+ return Q(x, () => ({
50
+ zoomIn: (e = 1.2) => {
51
+ const n = t.scale.get();
52
+ g(n * e);
53
+ },
54
+ zoomOut: (e = 1.2) => {
55
+ const n = t.scale.get();
56
+ g(n / e);
39
57
  },
40
- onDrag: ({ pinching: o, cancel: r, offset: [u, n], ...i }) => {
41
- if (!x || o) return r();
42
- g.start({ x: u, y: n });
58
+ setScale: (e) => {
59
+ g(e);
43
60
  },
44
- onPinch: ({
45
- origin: [o, r],
46
- first: u,
47
- movement: [n],
48
- offset: [i, E],
49
- memo: s,
50
- cancel: L
51
- }) => {
52
- if (!d) return L();
53
- if (u) {
54
- const { width: M, height: Z, x: A, y: D } = e.current.getBoundingClientRect(), P = o - (A + M / 2), R = r - (D + Z / 2);
55
- s = [t.x.get(), t.y.get(), P, R];
61
+ reset: () => {
62
+ c.start({ x: 0, y: 0, scale: 1, rotateZ: 0 }), d?.(1);
63
+ },
64
+ getScale: () => t.scale.get()
65
+ })), Y(
66
+ {
67
+ onWheel: ({ delta: [, e] }) => {
68
+ if (!h) return;
69
+ const l = t.scale.get() * (1 - e * E), s = Math.min(
70
+ Math.max(l, r.min),
71
+ r.max
72
+ );
73
+ c.start({ scale: s }), d?.(s);
74
+ },
75
+ onDrag: ({ pinching: e, cancel: n, offset: [l, s] }) => {
76
+ if (!y || e) return n();
77
+ c.start({ x: l, y: s });
78
+ },
79
+ onPinch: ({
80
+ origin: [e, n],
81
+ first: l,
82
+ movement: [s],
83
+ offset: [R, Z],
84
+ memo: o,
85
+ cancel: b
86
+ }) => {
87
+ if (!h) return b();
88
+ if (l) {
89
+ const { width: D, height: N, x: z, y: B } = a.current.getBoundingClientRect(), G = e - (z + D / 2), I = n - (B + N / 2);
90
+ o = [t.x.get(), t.y.get(), G, I];
91
+ }
92
+ const f = Math.min(
93
+ Math.max(R, r.min),
94
+ r.max
95
+ ), C = o[0] - (s - 1) * o[2], P = o[1] - (s - 1) * o[3], A = {
96
+ scale: f,
97
+ rotateZ: M ? Z : t.rotateZ.get(),
98
+ ...v ? { x: t.x.get(), y: t.y.get() } : { x: C, y: P }
99
+ };
100
+ return c.start(A), d?.(f), o;
56
101
  }
57
- const w = s[0] - (n - 1) * s[2], S = s[1] - (n - 1) * s[3], b = {
58
- scale: i,
59
- rotateZ: v ? E : t.rotateZ.get(),
60
- ...m ? { x: t.x.get(), y: t.y.get() } : { x: w, y: S }
61
- };
62
- return g.start(b), s;
63
- }
64
- },
65
- {
66
- target: e,
67
- drag: { from: () => [t.x.get(), t.y.get()] },
68
- pinch: { scaleBounds: l, rubberband: y },
69
- wheel: { enabled: !0 }
70
- }
71
- ), /* @__PURE__ */ B(
72
- G.div,
73
- {
74
- className: z("select-none", f),
75
- ref: e,
76
- style: {
77
- ...c.style,
78
- ...t
79
102
  },
80
- children: h
81
- }
82
- );
83
- };
103
+ {
104
+ target: a,
105
+ drag: { from: () => [t.x.get(), t.y.get()] },
106
+ pinch: { scaleBounds: r, rubberband: w },
107
+ wheel: { enabled: !0 }
108
+ }
109
+ ), /* @__PURE__ */ U(
110
+ j.div,
111
+ {
112
+ className: X(p),
113
+ ref: a,
114
+ style: {
115
+ userSelect: "none",
116
+ ...u.style,
117
+ ...t
118
+ },
119
+ children: S
120
+ }
121
+ );
122
+ }
123
+ );
124
+ _.displayName = "PinchContent";
84
125
  export {
85
- V as default
126
+ _ as default
86
127
  };
@@ -0,0 +1,26 @@
1
+ import { ElementType } from 'react';
2
+ interface TextTypeProps {
3
+ className?: string;
4
+ showCursor?: boolean;
5
+ hideCursorWhileTyping?: boolean;
6
+ cursorCharacter?: string | React.ReactNode;
7
+ cursorBlinkDuration?: number;
8
+ cursorClassName?: string;
9
+ text: string | string[];
10
+ as?: ElementType;
11
+ typingSpeed?: number;
12
+ initialDelay?: number;
13
+ pauseDuration?: number;
14
+ deletingSpeed?: number;
15
+ loop?: boolean;
16
+ textColors?: string[];
17
+ variableSpeed?: {
18
+ min: number;
19
+ max: number;
20
+ };
21
+ onSentenceComplete?: (sentence: string, index: number) => void;
22
+ startOnVisible?: boolean;
23
+ reverseMode?: boolean;
24
+ }
25
+ declare const TextType: ({ text, as: Component, typingSpeed, initialDelay, pauseDuration, deletingSpeed, loop, className, showCursor, hideCursorWhileTyping, cursorCharacter, cursorClassName, cursorBlinkDuration, textColors, variableSpeed, onSentenceComplete, startOnVisible, reverseMode, ...props }: TextTypeProps & React.HTMLAttributes<HTMLElement>) => import('react').ReactElement<any, string | import('react').JSXElementConstructor<any>>;
26
+ export default TextType;
@@ -0,0 +1,116 @@
1
+ "use client";
2
+ import { jsx as b } from "react/jsx-runtime";
3
+ import { useState as u, useRef as k, useMemo as U, useCallback as V, useEffect as p, createElement as W } from "react";
4
+ import { gsap as q } from "gsap";
5
+ /* empty css */
6
+ const D = ({
7
+ text: i,
8
+ as: v = "div",
9
+ typingSpeed: f = 50,
10
+ initialDelay: _ = 0,
11
+ pauseDuration: x = 2e3,
12
+ deletingSpeed: A = 30,
13
+ loop: R = !0,
14
+ className: w = "",
15
+ showCursor: T = !0,
16
+ hideCursorWhileTyping: z = !1,
17
+ cursorCharacter: F = "|",
18
+ cursorClassName: G = "",
19
+ cursorBlinkDuration: E = 0.5,
20
+ textColors: d = [],
21
+ variableSpeed: c,
22
+ onSentenceComplete: y,
23
+ startOnVisible: g = !1,
24
+ reverseMode: N = !1,
25
+ ...J
26
+ }) => {
27
+ const [l, $] = u(""), [o, j] = u(0), [a, C] = u(!1), [t, K] = u(0), [H, L] = u(!g), m = k(null), I = k(null), r = U(() => Array.isArray(i) ? i : [i], [i]), O = V(() => {
28
+ if (!c) return f;
29
+ const { min: e, max: n } = c;
30
+ return Math.random() * (n - e) + e;
31
+ }, [c, f]), P = () => {
32
+ if (d.length !== 0)
33
+ return d[t % d.length];
34
+ };
35
+ p(() => {
36
+ if (!g || !I.current) return;
37
+ const e = new IntersectionObserver(
38
+ (n) => {
39
+ n.forEach((h) => {
40
+ h.isIntersecting && L(!0);
41
+ });
42
+ },
43
+ { threshold: 0.1 }
44
+ );
45
+ return e.observe(I.current), () => e.disconnect();
46
+ }, [g]), p(() => {
47
+ T && m.current && (q.set(m.current, { opacity: 1 }), q.to(m.current, {
48
+ opacity: 0,
49
+ duration: E,
50
+ repeat: -1,
51
+ yoyo: !0,
52
+ ease: "power2.inOut"
53
+ }));
54
+ }, [T, E]), p(() => {
55
+ if (!H) return;
56
+ let e;
57
+ const n = r[t], h = N ? n.split("").reverse().join("") : n, M = () => {
58
+ if (a)
59
+ if (l === "") {
60
+ if (C(!1), t === r.length - 1 && !R)
61
+ return;
62
+ y && y(r[t], t), K((s) => (s + 1) % r.length), j(0), e = setTimeout(() => {
63
+ }, x);
64
+ } else
65
+ e = setTimeout(() => {
66
+ $((s) => s.slice(0, -1));
67
+ }, A);
68
+ else
69
+ o < h.length ? e = setTimeout(
70
+ () => {
71
+ $((s) => s + h[o]), j((s) => s + 1);
72
+ },
73
+ c ? O() : f
74
+ ) : r.length > 1 && (e = setTimeout(() => {
75
+ C(!0);
76
+ }, x));
77
+ };
78
+ return o === 0 && !a && l === "" ? e = setTimeout(M, _) : M(), () => clearTimeout(e);
79
+ }, [
80
+ o,
81
+ l,
82
+ a,
83
+ f,
84
+ A,
85
+ x,
86
+ r,
87
+ t,
88
+ R,
89
+ _,
90
+ H,
91
+ N,
92
+ c,
93
+ y
94
+ ]);
95
+ const Q = z && (o < r[t].length || a);
96
+ return W(
97
+ v,
98
+ {
99
+ ref: I,
100
+ className: `text-type ${w}`,
101
+ ...J
102
+ },
103
+ /* @__PURE__ */ b("span", { className: "text-type__content", style: { color: P() || "inherit" }, children: l }),
104
+ T && /* @__PURE__ */ b(
105
+ "span",
106
+ {
107
+ ref: m,
108
+ className: `text-type__cursor ${G} ${Q ? "text-type__cursor--hidden" : ""}`,
109
+ children: F
110
+ }
111
+ )
112
+ );
113
+ };
114
+ export {
115
+ D as default
116
+ };
@@ -0,0 +1,3 @@
1
+ import { default as TextType } from './TextType.tsx';
2
+ export { TextType };
3
+ export default TextType;
@@ -23,4 +23,6 @@ export * from './components/animated-list';
23
23
  export * from './components/shiny-button';
24
24
  export * from './components/scratch-to-reveal';
25
25
  export * from './components/split-text';
26
+ export * from './components/dome-gallery';
27
+ export * from './components/text-type';
26
28
  export * from './hooks/useStayTimeReport';