@rxdrag/website-lib-core 0.0.102 → 0.0.104

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.
Files changed (43) hide show
  1. package/package.json +7 -7
  2. package/src/component-logic/index.ts +1 -8
  3. package/src/global.d.ts +7 -0
  4. package/src/index.ts +1 -3
  5. package/src/react/components/BackgroundHlsVideoPlayer.tsx +30 -1
  6. package/src/react/components/ContactForm/ContactForm.tsx +3 -2
  7. package/src/react/components/ContactForm/types.ts +1 -0
  8. package/src/react/components/Scroller.tsx +32 -4
  9. package/src/react/components/Share/socials.tsx +1 -2
  10. package/src/react/components/all.ts +39 -0
  11. package/src/react/components/index.ts +1 -2
  12. package/src/react/index.ts +1 -2
  13. package/src/component-logic/collapse.ts +0 -61
  14. package/src/component-logic/gsap.d.ts +0 -4
  15. package/src/component-logic/modal.ts +0 -45
  16. package/src/component-logic/motion.ts +0 -272
  17. package/src/component-logic/number.ts +0 -45
  18. package/src/component-logic/popover.ts +0 -51
  19. package/src/component-logic/tabs.ts +0 -10
  20. package/src/controller/AnimateController.ts +0 -138
  21. package/src/controller/AosController.ts +0 -240
  22. package/src/controller/CollapseController.ts +0 -130
  23. package/src/controller/FlipController.ts +0 -339
  24. package/src/controller/ModalController.ts +0 -127
  25. package/src/controller/NumberController.ts +0 -161
  26. package/src/controller/OpenableController.ts +0 -367
  27. package/src/controller/PageLoader.ts +0 -154
  28. package/src/controller/PopoverController.ts +0 -116
  29. package/src/controller/TabsController.ts +0 -271
  30. package/src/controller/applyAnimation.ts +0 -86
  31. package/src/controller/applyInitialState.ts +0 -79
  32. package/src/controller/consts.ts +0 -33
  33. package/src/controller/index.ts +0 -10
  34. package/src/controller/utils.ts +0 -48
  35. package/src/motion/consts.ts +0 -428
  36. package/src/motion/convertToGsapVars.ts +0 -102
  37. package/src/motion/index.ts +0 -6
  38. package/src/motion/normalizeAnimation.ts +0 -28
  39. package/src/motion/normalizeAosAnimation.ts +0 -22
  40. package/src/motion/normalizePopupAnimation.ts +0 -24
  41. package/src/motion/types.ts +0 -133
  42. package/src/react/hooks/index.ts +0 -1
  43. package/src/react/hooks/useScroll.ts +0 -30
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rxdrag/website-lib-core",
3
- "version": "0.0.102",
3
+ "version": "0.0.104",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.ts"
@@ -25,8 +25,8 @@
25
25
  "eslint": "^7.32.0",
26
26
  "typescript": "^5",
27
27
  "@rxdrag/slate-preview": "1.2.63",
28
- "@rxdrag/eslint-config-custom": "0.2.12",
29
- "@rxdrag/tsconfig": "0.2.0"
28
+ "@rxdrag/tsconfig": "0.2.0",
29
+ "@rxdrag/eslint-config-custom": "0.2.12"
30
30
  },
31
31
  "dependencies": {
32
32
  "@iconify/utils": "^3.0.2",
@@ -34,13 +34,13 @@
34
34
  "gsap": "^3.12.7",
35
35
  "hls.js": "^1.6.13",
36
36
  "lodash-es": "^4.17.21",
37
- "react": "^19.1.0",
38
- "react-dom": "^19.1.0",
39
37
  "@rxdrag/entify-lib": "0.0.23",
40
- "@rxdrag/rxcms-models": "0.3.95"
38
+ "@rxdrag/rxcms-models": "0.3.96"
41
39
  },
42
40
  "peerDependencies": {
43
- "astro": "^4.0.0 || ^5.0.0"
41
+ "astro": "^4.0.0 || ^5.0.0",
42
+ "react": "^18.0.0 || ^19.0.0",
43
+ "react-dom": "^18.0.0 || ^19.0.0"
44
44
  },
45
45
  "scripts": {
46
46
  "lint": "eslint . --ext .ts,tsx",
@@ -1,9 +1,2 @@
1
- export * from "./collapse";
2
- export * from "./motion";
3
- export * from "../controller/FlipController";
4
1
  export * from "./link";
5
- export * from "./link-client";
6
- export * from "./popover";
7
- export * from "./tabs";
8
- export * from "./modal";
9
- export * from "./number";
2
+ export * from "./link-client";
@@ -0,0 +1,7 @@
1
+ export {};
2
+
3
+ declare global {
4
+ interface Window {
5
+ lastCta?: string;
6
+ }
7
+ }
package/src/index.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  export * from "./astro";
2
- export * from "./entify";
3
2
  export * from "./component-logic";
4
- export * from "./motion";
3
+ export * from "./entify";
5
4
  export * from "./react";
6
- export * from "./controller";
7
5
  export * from "./robots";
8
6
  export * from "./lib";
@@ -1,10 +1,39 @@
1
1
  import { useEffect, useRef, type VideoHTMLAttributes } from "react";
2
2
  import Hls from "hls.js";
3
3
 
4
+ // 需要过滤掉的非 video 属性(Astro runtime 透传的方法/对象)
5
+ const FORBIDDEN_PROPS = new Set([
6
+ 'createMetadata',
7
+ 'createComponent',
8
+ 'createAstro',
9
+ 'renderComponent',
10
+ 'renderSlot',
11
+ 'render',
12
+ 'addAttribute',
13
+ 'spreadAttributes',
14
+ 'defineStyleVars',
15
+ 'defineScriptVars',
16
+ 'Fragment',
17
+ 'unescapeHTML',
18
+ 'maybeRenderHead',
19
+ 'renderHead',
20
+ 'slots',
21
+ 'props',
22
+ 'children',
23
+ ]);
24
+
4
25
  export function BackgroundHlsVideoPlayer(
5
26
  props: VideoHTMLAttributes<HTMLVideoElement>
6
27
  ) {
7
- const { poster, src, className, ...restProps } = props;
28
+ const { poster, src, className, ...rawRestProps } = props;
29
+ // 过滤掉 Astro runtime 透传的非 video 属性
30
+ const restProps: Record<string, unknown> = {};
31
+ for (const [k, v] of Object.entries(rawRestProps)) {
32
+ if (FORBIDDEN_PROPS.has(k)) continue;
33
+ if (k.startsWith('_')) continue;
34
+ if (typeof v === 'function') continue;
35
+ restProps[k] = v;
36
+ }
8
37
  const videoRef = useRef<HTMLVideoElement>(null);
9
38
 
10
39
  useEffect(() => {
@@ -2,7 +2,6 @@ import { forwardRef, useState } from "react";
2
2
  import { Submit } from "./Submit";
3
3
  import { type UploadedFile } from "./FileUpload2";
4
4
  import clsx from "clsx";
5
- import { modal } from "../../../controller";
6
5
  import { encrypt } from "./funcs";
7
6
  import { ContactFormProps, QuoteRequest } from "./types";
8
7
  import { getControl, getFileUpload } from "./factory";
@@ -22,6 +21,7 @@ export const ContactForm = forwardRef<HTMLDivElement, ContactFormProps>(
22
21
  fields = [],
23
22
  className,
24
23
  classNames,
24
+ fromCta,
25
25
  ...rest
26
26
  } = props;
27
27
  const [formData, setFormData] = useState<QuoteRequest>({
@@ -129,7 +129,8 @@ export const ContactForm = forwardRef<HTMLDivElement, ContactFormProps>(
129
129
  method: "POST",
130
130
  body: JSON.stringify({
131
131
  ...formData,
132
- fromCta: modal.lastCta,
132
+ //TODO:后面改成从window 或者传入
133
+ fromCta: fromCta || window?.lastCta,
133
134
  encryptedField: encrypt(formData.phone, formSalt),
134
135
  }),
135
136
  headers: {
@@ -39,6 +39,7 @@ export type ContactFormProps = {
39
39
  required?: string;
40
40
  };
41
41
  fields: FieldConfig[];
42
+ fromCta?: string;
42
43
  };
43
44
 
44
45
  export interface FileAttachment {
@@ -1,11 +1,39 @@
1
- import { useScroll } from "../hooks";
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+
3
+ export const defaultThreshold = 10;
2
4
 
3
5
  export type ScrollerProps = {
4
6
  threshold?: number;
5
7
  };
6
8
 
7
9
  export function Scroller(props: ScrollerProps) {
8
- const { threshold } = props;
9
- useScroll(threshold);
10
- return <></>;
10
+ const { threshold = defaultThreshold } = props;
11
+ const ref = useRef<HTMLDivElement>(null);
12
+ const [win, setWin] = useState<Window | null>(null);
13
+
14
+ useEffect(() => {
15
+ if (ref.current) {
16
+ setWin(ref.current.ownerDocument.defaultView);
17
+ }
18
+ }, []);
19
+
20
+ const onScroll = useCallback(() => {
21
+ if (!win) return;
22
+ const scrolled = win.scrollY > threshold;
23
+ const doc = win.document;
24
+
25
+ if (scrolled) {
26
+ doc.body.classList.add("scrolled");
27
+ } else {
28
+ doc.body.classList.remove("scrolled");
29
+ }
30
+ }, [threshold, win]);
31
+
32
+ useEffect(() => {
33
+ if (!win) return;
34
+ win.addEventListener("scroll", onScroll);
35
+ return () => win.removeEventListener("scroll", onScroll);
36
+ }, [onScroll, win]);
37
+
38
+ return <div ref={ref} style={{ display: "none" }} />;
11
39
  }
@@ -1,8 +1,7 @@
1
-
2
1
  export interface IconListType {
3
2
  [key: string]: {
4
3
  title: string;
5
- path: JSX.Element;
4
+ path: Element;
6
5
  url: (l: string, t?: string, ti?: string) => string;
7
6
  color: string;
8
7
  viewBox?: string;
@@ -0,0 +1,39 @@
1
+ import { Analytics } from "./Analytics";
2
+ import { AttachmentIcon } from "./AttachmentIcon";
3
+ import { BackgroundHlsVideoPlayer } from "./BackgroundHlsVideoPlayer";
4
+ import { BackgroundVideoPlayer } from "./BackgroundVideoPlayer";
5
+ import { Bulletin } from "./Bulletin";
6
+ import { ContactForm } from "./ContactForm";
7
+ import { Icon } from "./Icon";
8
+ import { Medias } from "./Medias";
9
+ import { ProductCard, ProductCta, ProductDescription, ProductMedia, ProductTitle } from "./ProductCard";
10
+ import { ReactModalTrigger } from "./ReactModalTrigger";
11
+ import { ReactVideoPlayer } from "./ReactVideoPlayer";
12
+ import { RichTextOutline } from "./RichTextOutline";
13
+ import { Scroller } from "./Scroller";
14
+ import { SearchInput } from "./SearchInput";
15
+ import { Share } from "./Share";
16
+ import { ToTop } from "./ToTop";
17
+
18
+ export const allCoreComponents = {
19
+ Analytics,
20
+ AttachmentIcon,
21
+ BackgroundHlsVideoPlayer,
22
+ BackgroundVideoPlayer,
23
+ Bulletin,
24
+ ContactForm,
25
+ Icon,
26
+ Medias,
27
+ ProductCard,
28
+ ProductCta,
29
+ ProductDescription,
30
+ ProductMedia,
31
+ ProductTitle,
32
+ ReactModalTrigger,
33
+ ReactVideoPlayer,
34
+ RichTextOutline,
35
+ Scroller,
36
+ SearchInput,
37
+ Share,
38
+ ToTop,
39
+ };
@@ -14,5 +14,4 @@ export * from "./BackgroundHlsVideoPlayer";
14
14
  export * from "./Bulletin";
15
15
  export * from "./ReactModalTrigger";
16
16
  export * from "./ReactVideoPlayer";
17
-
18
-
17
+ export * from "./all"
@@ -1,2 +1 @@
1
- export * from "./components";
2
- export * from "./hooks";
1
+ export * from "./components";
@@ -1,61 +0,0 @@
1
- import { DATA_OPENABLE, DATA_OPENABLE_ROLE, OpenAble } from "../controller";
2
- import { AnimationConfig, OpenableAnimationConfig } from "../motion";
3
- import { HTMLElementsWithChildren, IMotionProps } from "./motion";
4
-
5
- export type CollapseTriggerProps = IMotionProps & {
6
- as?: HTMLElementsWithChildren;
7
- };
8
-
9
- export const defaultCollapsePanelOpen: AnimationConfig = {
10
- fromTo: {
11
- from: {
12
- height: 0,
13
- opacity: 0,
14
- },
15
- to: {
16
- height: "auto",
17
- opacity: 1,
18
- },
19
- },
20
- duration: 0.6,
21
- ease: "spring",
22
- };
23
-
24
- export const defaultCollapsePanelClose: AnimationConfig = {
25
- fromTo: {
26
- from: {
27
- height: "auto",
28
- opacity: 1,
29
- },
30
- to: {
31
- height: 0,
32
- opacity: 0,
33
- },
34
- },
35
- duration: 0.25,
36
- ease: "cubic-bezier(0.4, 0.0, 0.2, 1)",
37
- };
38
-
39
- export const defaultCollapsePanelAnimation: OpenableAnimationConfig = {
40
- open: defaultCollapsePanelOpen,
41
- close: defaultCollapsePanelClose,
42
- };
43
-
44
- export function getCollapseDataAttrs(openableKey: string = crypto.randomUUID()) {
45
- return {
46
- [DATA_OPENABLE]: openableKey,
47
- [DATA_OPENABLE_ROLE]: OpenAble.CollapseContainer,
48
- };
49
- }
50
-
51
- export function getCollapseTriggerDataAttrs() {
52
- return {
53
- [DATA_OPENABLE_ROLE]: OpenAble.CollapseTrigger,
54
- };
55
- }
56
-
57
- export function getCollapsePanelDataAttrs() {
58
- return {
59
- [DATA_OPENABLE_ROLE]: OpenAble.CollapsePanel,
60
- };
61
- }
@@ -1,4 +0,0 @@
1
- declare module 'gsap/dist/gsap' {
2
- export * from 'gsap';
3
- export { default } from 'gsap';
4
- }
@@ -1,45 +0,0 @@
1
- import {
2
- DATA_OPENABLE,
3
- DATA_OPENABLE_ROLE,
4
- DATA_POPUP_CTA,
5
- OpenAble,
6
- } from "../controller";
7
- import { HTMLElementsWithChildren, IMotionProps } from "./motion";
8
-
9
- export type ModalTriggerProps = IMotionProps & {
10
- openableKey: string;
11
- callToAction?: string;
12
- as?: HTMLElementsWithChildren;
13
- };
14
-
15
- export function getModalDataAttrs(openableKey?: string) {
16
- return {
17
- [DATA_OPENABLE]: openableKey,
18
- [DATA_OPENABLE_ROLE]: OpenAble.ModalContainer,
19
- };
20
- }
21
-
22
- export function getModalCloserDataAttrs(openableKey?: string) {
23
- return {
24
- [DATA_OPENABLE]: openableKey,
25
- [DATA_OPENABLE_ROLE]: OpenAble.ModalCloser,
26
- };
27
- }
28
-
29
- export function getModalPanelDataAttrs(openableKey?: string) {
30
- return {
31
- [DATA_OPENABLE]: openableKey,
32
- [DATA_OPENABLE_ROLE]: OpenAble.ModalPanel,
33
- };
34
- }
35
-
36
- export function getModalTriggerDataAttrs(
37
- openableKey: string | undefined,
38
- callToAction?: string
39
- ) {
40
- return {
41
- [DATA_OPENABLE]: openableKey,
42
- [DATA_OPENABLE_ROLE]: OpenAble.ModalTrigger,
43
- [DATA_POPUP_CTA]: callToAction,
44
- };
45
- }
@@ -1,272 +0,0 @@
1
- import {
2
- normalizeAnimation,
3
- DATA_MOTION,
4
- DATA_MOTION_HOVER,
5
- DATA_MOTION_INVIEW,
6
- DATA_MOTION_TAP,
7
- AnimationConfig,
8
- AosAnimationConfig,
9
- HoverAnimationConfig,
10
- OpenableAnimationConfig,
11
- DATA_MOTION_OPENABLE,
12
- normalizePopupAnimation,
13
- normalizeAosAnimation,
14
- } from "../motion";
15
- import { DATA_MOTION_SELECTION, DATA_MOTION_FLIP } from "./tabs";
16
- import { CSSProperties } from "react";
17
-
18
- // 排除不能包含子元素的标签
19
- export type ExcludedElements =
20
- | "img"
21
- | "input"
22
- | "br"
23
- | "hr"
24
- | "area"
25
- | "base"
26
- | "col"
27
- | "embed"
28
- | "link"
29
- | "meta"
30
- | "param"
31
- | "source"
32
- | "track"
33
- | "wbr";
34
-
35
- export type HTMLElementsWithChildren = Exclude<
36
- keyof HTMLElementTagNameMap,
37
- ExcludedElements
38
- >;
39
-
40
- // CSS 属性的单位处理映射
41
- export const cssPropertyUnits = {
42
- // 无单位的属性
43
- opacity: "",
44
- scale: "",
45
- fontWeight: "",
46
- lineHeight: "",
47
- zIndex: "",
48
- flex: "",
49
- flexGrow: "",
50
- flexShrink: "",
51
- order: "",
52
- // 使用px的属性
53
- width: "px",
54
- height: "px",
55
- minWidth: "px",
56
- minHeight: "px",
57
- maxWidth: "px",
58
- maxHeight: "px",
59
- padding: "px",
60
- margin: "px",
61
- top: "px",
62
- right: "px",
63
- bottom: "px",
64
- left: "px",
65
- gap: "px",
66
- columnGap: "px",
67
- rowGap: "px",
68
- // transform 相关的属性
69
- x: "transform",
70
- y: "transform",
71
- z: "transform",
72
- } as const;
73
-
74
- export interface IMotionProps {
75
- animate?: AnimationConfig | string;
76
- whileHover?: HoverAnimationConfig | string;
77
- whileInView?: AosAnimationConfig | string;
78
- whileTap?: AnimationConfig | string;
79
- whileOpenable?: OpenableAnimationConfig | string;
80
- whileSelection?: AnimationConfig | string;
81
- // 在flip的父元素中使用
82
- flipTransition?: AnimationConfig | string;
83
- class?: string;
84
- style?: CSSProperties;
85
- }
86
-
87
- export interface MotionAttributes {
88
- className?: string;
89
- style?: CSSProperties;
90
- class?: string;
91
- [DATA_MOTION]?: string;
92
- [DATA_MOTION_HOVER]?: string;
93
- [DATA_MOTION_INVIEW]?: string;
94
- [DATA_MOTION_TAP]?: string;
95
- [DATA_MOTION_OPENABLE]?: string;
96
- [DATA_MOTION_SELECTION]?: string;
97
- [DATA_MOTION_FLIP]?: string;
98
- }
99
-
100
- export function getMotionProps(props: IMotionProps): MotionAttributes {
101
- const {
102
- animate,
103
- whileHover,
104
- whileInView,
105
- whileTap,
106
- whileOpenable,
107
- whileSelection,
108
- flipTransition,
109
- class: className,
110
- style,
111
- ...rest
112
- } = props;
113
- const normalizedAnimate = normalizeAnimation(animate);
114
- const normalizedWhileHover = normalizeAnimation(whileHover);
115
- const normalizedWhileInView = normalizeAosAnimation(whileInView);
116
- const normalizedWhileTap = normalizeAnimation(whileTap);
117
- const normalizedWhilePopup = normalizePopupAnimation(whileOpenable);
118
- const normalizedWhileSelection = normalizeAnimation(whileSelection);
119
-
120
- const dataWhileHover = JSON.stringify(normalizedWhileHover);
121
- const dataWhileInView = JSON.stringify(normalizedWhileInView);
122
- const dataWhileTap = JSON.stringify(normalizedWhileTap);
123
- const dataWhilePopup = JSON.stringify(normalizedWhilePopup);
124
- const dataWhileSelection = JSON.stringify(normalizedWhileSelection);
125
- const motions: Record<string, string> = {
126
- [DATA_MOTION_HOVER]: dataWhileHover,
127
- [DATA_MOTION_INVIEW]: dataWhileInView,
128
- [DATA_MOTION_TAP]: dataWhileTap,
129
- [DATA_MOTION_OPENABLE]: dataWhilePopup,
130
- [DATA_MOTION_SELECTION]: dataWhileSelection,
131
- [DATA_MOTION_FLIP]: JSON.stringify(flipTransition),
132
- };
133
-
134
- if (Object.keys(normalizedAnimate || {}).length > 0) {
135
- motions[DATA_MOTION] = JSON.stringify(normalizedAnimate);
136
- }
137
-
138
- const newClassName = className || "";
139
- const newProps = { ...motions, ...rest };
140
- const mergedStyle = { ...style };
141
-
142
- if (normalizedAnimate?.initial) {
143
- // 处理特殊的transform属性 (x, y, z, rotation, scale等)
144
- // 这些属性需要转换为CSS的transform属性
145
-
146
- // 处理标准CSS属性
147
- if (normalizedAnimate.initial.opacity !== undefined)
148
- mergedStyle.opacity = String(normalizedAnimate.initial.opacity);
149
- if (normalizedAnimate.initial.backgroundColor !== undefined)
150
- mergedStyle.backgroundColor = normalizedAnimate.initial.backgroundColor;
151
- if (normalizedAnimate.initial.color !== undefined)
152
- mergedStyle.color = normalizedAnimate.initial.color;
153
- if (normalizedAnimate.initial.width !== undefined) {
154
- mergedStyle.width =
155
- typeof normalizedAnimate.initial.width === "number"
156
- ? `${normalizedAnimate.initial.width}px`
157
- : normalizedAnimate.initial.width;
158
- }
159
- if (normalizedAnimate.initial.height !== undefined) {
160
- mergedStyle.height =
161
- typeof normalizedAnimate.initial.height === "number"
162
- ? `${normalizedAnimate.initial.height}px`
163
- : normalizedAnimate.initial.height;
164
- }
165
-
166
- // 处理transformOrigin
167
- if (normalizedAnimate.initial.transformOrigin !== undefined) {
168
- mergedStyle.transformOrigin = normalizedAnimate.initial.transformOrigin;
169
- }
170
-
171
- // 处理transform属性
172
- const transforms: string[] = [];
173
-
174
- // 注意:对于x和y,我们使用translateX和translateY,但要确保单位是正确的
175
- if (normalizedAnimate.initial.x !== undefined) {
176
- const value =
177
- typeof normalizedAnimate.initial.x === "number"
178
- ? `${normalizedAnimate.initial.x}px`
179
- : normalizedAnimate.initial.x;
180
- transforms.push(`translateX(${value})`);
181
- }
182
-
183
- if (normalizedAnimate.initial.y !== undefined) {
184
- const value =
185
- typeof normalizedAnimate.initial.y === "number"
186
- ? `${normalizedAnimate.initial.y}px`
187
- : normalizedAnimate.initial.y;
188
- transforms.push(`translateY(${value})`);
189
- }
190
-
191
- if (normalizedAnimate.initial.z !== undefined) {
192
- const value =
193
- typeof normalizedAnimate.initial.z === "number"
194
- ? `${normalizedAnimate.initial.z}px`
195
- : normalizedAnimate.initial.z;
196
- transforms.push(`translateZ(${value})`);
197
- }
198
-
199
- // 处理旋转
200
- if (normalizedAnimate.initial.rotation !== undefined) {
201
- transforms.push(`rotate(${normalizedAnimate.initial.rotation}deg)`);
202
- }
203
-
204
- if (normalizedAnimate.initial.rotationX !== undefined) {
205
- transforms.push(`rotateX(${normalizedAnimate.initial.rotationX}deg)`);
206
- }
207
-
208
- if (normalizedAnimate.initial.rotationY !== undefined) {
209
- transforms.push(`rotateY(${normalizedAnimate.initial.rotationY}deg)`);
210
- }
211
-
212
- if (normalizedAnimate.initial.rotationZ !== undefined) {
213
- transforms.push(`rotateZ(${normalizedAnimate.initial.rotationZ}deg)`);
214
- }
215
-
216
- // 处理缩放
217
- if (normalizedAnimate.initial.scale !== undefined) {
218
- transforms.push(`scale(${normalizedAnimate.initial.scale})`);
219
- }
220
-
221
- if (normalizedAnimate.initial.scaleX !== undefined) {
222
- transforms.push(`scaleX(${normalizedAnimate.initial.scaleX})`);
223
- }
224
-
225
- if (normalizedAnimate.initial.scaleY !== undefined) {
226
- transforms.push(`scaleY(${normalizedAnimate.initial.scaleY})`);
227
- }
228
-
229
- // 如果有transform属性,合并它们
230
- if (transforms.length > 0) {
231
- mergedStyle.transform = transforms.join(" ");
232
- }
233
-
234
- // 处理其他属性
235
- const handledProps = [
236
- "opacity",
237
- "backgroundColor",
238
- "color",
239
- "width",
240
- "height",
241
- "transformOrigin",
242
- "x",
243
- "y",
244
- "z",
245
- "rotation",
246
- "rotationX",
247
- "rotationY",
248
- "rotationZ",
249
- "scale",
250
- "scaleX",
251
- "scaleY",
252
- ];
253
-
254
- // 复制其他没有特殊处理的属性
255
- for (const key in normalizedAnimate.initial) {
256
- if (!handledProps.includes(key)) {
257
- // @ts-expect-error - 允许动态属性赋值
258
- mergedStyle[key] = normalizedAnimate.initial[key];
259
- }
260
- }
261
- }
262
-
263
- // 将 styleProp 的定义移到条件块外部,确保它始终被定义
264
- const styleProp =
265
- Object.keys(mergedStyle).length > 0
266
- ? {
267
- style: mergedStyle,
268
- }
269
- : undefined;
270
-
271
- return { ...newProps, ...styleProp, class: newClassName };
272
- }
@@ -1,45 +0,0 @@
1
- import { DATA_MOTION_NUMBER, DATA_MOTION_NUMBER_ONCE } from "../motion/consts";
2
-
3
- /**
4
- * Animation options for GSAP animations
5
- */
6
- export interface AnimationOptions {
7
- /** Animation duration in seconds */
8
- duration?: number;
9
- /** GSAP easing function (e.g., "power1.out", "power2.in", "elastic.out") */
10
- ease?: string;
11
- /** Delay before animation starts in seconds */
12
- delay?: number;
13
- /** Repeat count (-1 for infinite) */
14
- repeat?: number;
15
- /** Whether to yoyo the animation (play in reverse after completion) */
16
- yoyo?: boolean;
17
- /** Stagger value for multiple animations */
18
- stagger?: number;
19
- }
20
-
21
- export interface AnimationNumberProps {
22
- start?: number;
23
- end?: number;
24
- transition?: AnimationOptions;
25
- class?: string;
26
- sign?: string;
27
- once?: boolean;
28
- type?: "int" | "float" | "percentage" | "currency";
29
- fractionDigits?: number;
30
- }
31
-
32
- export function getAnimationNumberDataAttrs(props: AnimationNumberProps) {
33
- const { start, end, transition, type, fractionDigits } = props;
34
- const motionValue = {
35
- start,
36
- end,
37
- transition,
38
- type,
39
- fractionDigits,
40
- };
41
- return {
42
- [DATA_MOTION_NUMBER]: JSON.stringify(motionValue),
43
- [DATA_MOTION_NUMBER_ONCE]: props.once,
44
- };
45
- }