@rxdrag/website-lib-core 0.0.9 → 0.0.11

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 (31) hide show
  1. package/package.json +5 -5
  2. package/src/component-logic/collapse.ts +61 -0
  3. package/src/component-logic/index.ts +1 -0
  4. package/src/component-logic/modal.ts +14 -14
  5. package/src/component-logic/motion.ts +7 -7
  6. package/src/component-logic/popover.ts +9 -9
  7. package/src/controller/CollapseController.ts +130 -0
  8. package/src/controller/ModalController.ts +19 -19
  9. package/src/controller/{popup.ts → OpenableController.ts} +53 -37
  10. package/src/controller/PopoverController.ts +13 -13
  11. package/src/controller/TabsController.ts +1 -1
  12. package/src/controller/consts.ts +9 -6
  13. package/src/controller/index.ts +1 -0
  14. package/src/entify/IEntify.ts +1 -1
  15. package/src/entify/lib/newQueryProductOptions.ts +2 -11
  16. package/src/entify/lib/queryOneProductBySlug.ts +52 -10
  17. package/src/entify/lib/queryOneTheme.ts +1 -7
  18. package/src/entify/types/variables.ts +0 -1
  19. package/src/entify/view-model/funcs.ts +0 -16
  20. package/src/lib/utils.ts +30 -14
  21. package/src/motion/consts.ts +3 -3
  22. package/src/motion/normalizePopupAnimation.ts +3 -3
  23. package/src/motion/types.ts +1 -1
  24. package/src/react/components/ContactForm/index.tsx +16 -8
  25. package/src/react/components/Icon/index.tsx +8 -4
  26. package/src/react/components/ProductCard/ProductCard.tsx +2 -1
  27. package/src/react/components/ProductCard/ProductCta/index.tsx +13 -12
  28. package/src/react/components/ProductCard/ProductView.tsx +3 -2
  29. package/src/react/components/ToTop/index.tsx +1 -1
  30. package/src/react/components/ToTop.tsx +1 -1
  31. package/src/react/hooks/useScroll.ts +12 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rxdrag/website-lib-core",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.ts"
@@ -24,10 +24,10 @@
24
24
  "@types/react-dom": "^18.2.7",
25
25
  "eslint": "^7.32.0",
26
26
  "typescript": "^5",
27
- "@rxdrag/entify-hooks": "0.2.40",
27
+ "@rxdrag/entify-hooks": "0.2.42",
28
+ "@rxdrag/eslint-config-custom": "0.2.12",
28
29
  "@rxdrag/slate-preview": "1.2.55",
29
- "@rxdrag/tsconfig": "0.2.0",
30
- "@rxdrag/eslint-config-custom": "0.2.12"
30
+ "@rxdrag/tsconfig": "0.2.0"
31
31
  },
32
32
  "dependencies": {
33
33
  "clsx": "^2.1.0",
@@ -35,7 +35,7 @@
35
35
  "lodash-es": "^4.17.21",
36
36
  "react": "^18.2.0",
37
37
  "react-dom": "^18.2.0",
38
- "@rxdrag/rxcms-models": "0.3.46"
38
+ "@rxdrag/rxcms-models": "0.3.48"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "astro": "^4.0.0 || ^5.0.0"
@@ -0,0 +1,61 @@
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,3 +1,4 @@
1
+ export * from "./collapse";
1
2
  export * from "./motion";
2
3
  export * from "../controller/FlipController";
3
4
  export * from "./link";
@@ -1,36 +1,36 @@
1
- import { DATA_POPUP, DATA_POPUP_ROLE, PopupRole } from "../controller";
1
+ import { DATA_OPENABLE, DATA_OPENABLE_ROLE, OpenAble } from "../controller";
2
2
  import { HTMLElementsWithChildren, IMotionProps } from "./motion";
3
3
 
4
4
  export type ModalTriggerProps = IMotionProps & {
5
- popupKey: string;
5
+ openableKey: string;
6
6
  callToAction?: string;
7
7
  as?: HTMLElementsWithChildren;
8
8
  };
9
9
 
10
- export function getModalDataAttrs(popupKey?: string) {
10
+ export function getModalDataAttrs(openableKey?: string) {
11
11
  return {
12
- [DATA_POPUP]: popupKey,
13
- [DATA_POPUP_ROLE]: PopupRole.ModalContainer,
12
+ [DATA_OPENABLE]: openableKey,
13
+ [DATA_OPENABLE_ROLE]: OpenAble.ModalContainer,
14
14
  };
15
15
  }
16
16
 
17
- export function getModalCloserDataAttrs(popupKey?: string) {
17
+ export function getModalCloserDataAttrs(openableKey?: string) {
18
18
  return {
19
- [DATA_POPUP]: popupKey,
20
- [DATA_POPUP_ROLE]: PopupRole.ModalCloser,
19
+ [DATA_OPENABLE]: openableKey,
20
+ [DATA_OPENABLE_ROLE]: OpenAble.ModalCloser,
21
21
  };
22
22
  }
23
23
 
24
- export function getModalPanelDataAttrs(popupKey?: string) {
24
+ export function getModalPanelDataAttrs(openableKey?: string) {
25
25
  return {
26
- [DATA_POPUP]: popupKey,
27
- [DATA_POPUP_ROLE]: PopupRole.ModalPanel,
26
+ [DATA_OPENABLE]: openableKey,
27
+ [DATA_OPENABLE_ROLE]: OpenAble.ModalPanel,
28
28
  };
29
29
  }
30
30
 
31
- export function getModalTriggerDataAttrs(popupKey?: string) {
31
+ export function getModalTriggerDataAttrs(openableKey?: string) {
32
32
  return {
33
- [DATA_POPUP]: popupKey,
34
- [DATA_POPUP_ROLE]: PopupRole.ModalTrigger,
33
+ [DATA_OPENABLE]: openableKey,
34
+ [DATA_OPENABLE_ROLE]: OpenAble.ModalTrigger,
35
35
  };
36
36
  }
@@ -7,8 +7,8 @@ import {
7
7
  AnimationConfig,
8
8
  AosAnimationConfig,
9
9
  HoverAnimationConfig,
10
- PopupAnimationConfig,
11
- DATA_MOTION_POPUP,
10
+ OpenableAnimationConfig,
11
+ DATA_MOTION_OPENABLE,
12
12
  normalizePopupAnimation,
13
13
  normalizeAosAnimation,
14
14
  } from "../motion";
@@ -76,7 +76,7 @@ export interface IMotionProps {
76
76
  whileHover?: HoverAnimationConfig | string;
77
77
  whileInView?: AosAnimationConfig | string;
78
78
  whileTap?: AnimationConfig | string;
79
- whilePopup?: PopupAnimationConfig | string;
79
+ whileOpenable?: OpenableAnimationConfig | string;
80
80
  whileSelection?: AnimationConfig | string;
81
81
  // 在flip的父元素中使用
82
82
  flipTransition?: AnimationConfig | string;
@@ -92,7 +92,7 @@ export interface MotionAttributes {
92
92
  [DATA_MOTION_HOVER]?: string;
93
93
  [DATA_MOTION_INVIEW]?: string;
94
94
  [DATA_MOTION_TAP]?: string;
95
- [DATA_MOTION_POPUP]?: string;
95
+ [DATA_MOTION_OPENABLE]?: string;
96
96
  [DATA_MOTION_SELECTION]?: string;
97
97
  [DATA_MOTION_FLIP]?: string;
98
98
  }
@@ -103,7 +103,7 @@ export function getMotionProps(props: IMotionProps): MotionAttributes {
103
103
  whileHover,
104
104
  whileInView,
105
105
  whileTap,
106
- whilePopup,
106
+ whileOpenable,
107
107
  whileSelection,
108
108
  flipTransition,
109
109
  class: className,
@@ -114,7 +114,7 @@ export function getMotionProps(props: IMotionProps): MotionAttributes {
114
114
  const normalizedWhileHover = normalizeAnimation(whileHover);
115
115
  const normalizedWhileInView = normalizeAosAnimation(whileInView);
116
116
  const normalizedWhileTap = normalizeAnimation(whileTap);
117
- const normalizedWhilePopup = normalizePopupAnimation(whilePopup);
117
+ const normalizedWhilePopup = normalizePopupAnimation(whileOpenable);
118
118
  const normalizedWhileSelection = normalizeAnimation(whileSelection);
119
119
 
120
120
  const dataWhileHover = JSON.stringify(normalizedWhileHover);
@@ -126,7 +126,7 @@ export function getMotionProps(props: IMotionProps): MotionAttributes {
126
126
  [DATA_MOTION_HOVER]: dataWhileHover,
127
127
  [DATA_MOTION_INVIEW]: dataWhileInView,
128
128
  [DATA_MOTION_TAP]: dataWhileTap,
129
- [DATA_MOTION_POPUP]: dataWhilePopup,
129
+ [DATA_MOTION_OPENABLE]: dataWhilePopup,
130
130
  [DATA_MOTION_SELECTION]: dataWhileSelection,
131
131
  [DATA_MOTION_FLIP]: JSON.stringify(flipTransition),
132
132
  };
@@ -1,5 +1,5 @@
1
- import { DATA_POPUP, DATA_POPUP_ROLE, PopupRole } from "../controller";
2
- import { AnimationConfig, PopupAnimationConfig } from "../motion";
1
+ import { DATA_OPENABLE, DATA_OPENABLE_ROLE, OpenAble } from "../controller";
2
+ import { AnimationConfig, OpenableAnimationConfig } from "../motion";
3
3
 
4
4
  export const defaultPopoverPanelOpen: AnimationConfig = {
5
5
  fromTo: {
@@ -31,21 +31,21 @@ export const defaultPopoverPanelClose: AnimationConfig = {
31
31
  ease: "cubic-bezier(0.4, 0.0, 0.2, 1)",
32
32
  };
33
33
 
34
- export const defaultPopoverPanelAnimation: PopupAnimationConfig = {
34
+ export const defaultPopoverPanelAnimation: OpenableAnimationConfig = {
35
35
  open: defaultPopoverPanelOpen,
36
36
  close: defaultPopoverPanelClose,
37
37
  };
38
38
 
39
- export function getPopoverDataAttrs(popupKey?: string) {
39
+ export function getPopoverDataAttrs(openableKey?: string) {
40
40
  return {
41
- [DATA_POPUP]: popupKey,
42
- [DATA_POPUP_ROLE]: PopupRole.PopoverContainer,
41
+ [DATA_OPENABLE]: openableKey || crypto.randomUUID(),
42
+ [DATA_OPENABLE_ROLE]: OpenAble.PopoverContainer,
43
43
  };
44
44
  }
45
45
 
46
- export function getPopoverPanelDataAttrs(popupKey?: string) {
46
+ export function getPopoverPanelDataAttrs(openableKey?: string) {
47
47
  return {
48
- [DATA_POPUP]: popupKey || "",
49
- [DATA_POPUP_ROLE]: PopupRole.PopoverPanel,
48
+ [DATA_OPENABLE]: openableKey || "",
49
+ [DATA_OPENABLE_ROLE]: OpenAble.PopoverPanel,
50
50
  };
51
51
  }
@@ -0,0 +1,130 @@
1
+ import { DATA_OPENABLE, DATA_OPENABLE_ROLE, OpenAble } from "./consts";
2
+ import { OpenableController } from "./OpenableController";
3
+
4
+ export class CollapseController extends OpenableController {
5
+ private static instances: Record<string, CollapseController> = {};
6
+
7
+ private constructor(doc?: Document) {
8
+ super(doc);
9
+ }
10
+
11
+ public static getInstance(
12
+ key: string = "runtime",
13
+ doc?: Document
14
+ ): CollapseController {
15
+ if (!CollapseController.instances[key]) {
16
+ CollapseController.instances[key] = new CollapseController(doc);
17
+ } else if (doc) {
18
+ CollapseController.instances[key].setDoc(doc);
19
+ }
20
+ return CollapseController.instances[key];
21
+ }
22
+
23
+ /**
24
+ * 销毁指定 key 的实例
25
+ * @param key 实例的唯一标识
26
+ */
27
+ public static destroyInstance(key: string = "runtime"): void {
28
+ if (CollapseController.instances[key]) {
29
+ CollapseController.instances[key].destroy();
30
+ delete CollapseController.instances[key];
31
+ }
32
+ }
33
+
34
+ private setDoc(doc?: Document) {
35
+ this.doc = doc;
36
+ }
37
+
38
+ mount() {
39
+ super.mount();
40
+ const openables = this.doc?.querySelectorAll(`[${DATA_OPENABLE}]`);
41
+ openables?.forEach((openable) => {
42
+ const openableKey = openable.getAttribute(DATA_OPENABLE);
43
+
44
+ // 获取所有触发器
45
+ const allTriggers = openable?.querySelectorAll(
46
+ `[${DATA_OPENABLE_ROLE}="${OpenAble.CollapseTrigger}"]`
47
+ );
48
+
49
+ // 获取所有嵌套容器
50
+ const nestedContainers = openable?.querySelectorAll(
51
+ `[${DATA_OPENABLE_ROLE}="${OpenAble.PopoverContainer}"],
52
+ [${DATA_OPENABLE_ROLE}="${OpenAble.ModalContainer}"],
53
+ [${DATA_OPENABLE_ROLE}="${OpenAble.CollapseContainer}"]`
54
+ );
55
+
56
+ // 过滤出不在嵌套容器内的触发器
57
+ const filteredTriggers: Element[] = [];
58
+ allTriggers?.forEach((trigger) => {
59
+ let isInNestedContainer = false;
60
+
61
+ nestedContainers?.forEach((container) => {
62
+ if (container.contains(trigger) && container !== openable) {
63
+ isInNestedContainer = true;
64
+ }
65
+ });
66
+
67
+ if (!isInNestedContainer) {
68
+ filteredTriggers.push(trigger);
69
+ }
70
+ });
71
+
72
+ // 为过滤后的触发器添加事件处理
73
+ filteredTriggers.forEach((trigger) => {
74
+ if (openableKey) {
75
+ const unsub = this.initCollapseTrigger(
76
+ openableKey,
77
+ trigger as HTMLElement
78
+ );
79
+ this.unmountHandlers.push(unsub);
80
+ }
81
+ });
82
+ });
83
+ }
84
+ /**
85
+ * 初始化Modal的点击交互事件
86
+ * @param openableKey - 弹出层的唯一标识
87
+ * @param trigger - 触发器元素
88
+ * @returns 清理函数,用于移除事件监听器
89
+ */
90
+ public initCollapseTrigger(
91
+ openableKey: string,
92
+ trigger: HTMLElement
93
+ ): () => void {
94
+ if (!this.doc) return () => {};
95
+
96
+ try {
97
+ // 创建新的事件处理函数
98
+ const handleTriggerClick = () => {
99
+ const container = this.getOpenableContainer(openableKey);
100
+ if (container) {
101
+ if (container.classList.contains("open")) {
102
+ // 传递容器元素而不是触发器,确保正确移除open类
103
+ this.close(openableKey, container);
104
+ } else {
105
+ this.open(openableKey, trigger);
106
+ }
107
+ }
108
+ };
109
+
110
+ // 添加新的事件监听器
111
+ trigger.addEventListener("click", handleTriggerClick);
112
+
113
+ return () => {
114
+ trigger.removeEventListener("click", handleTriggerClick);
115
+ };
116
+ } catch (error) {
117
+ console.error(`初始化Modal事件失败: ${openableKey}`, error);
118
+ return () => {};
119
+ }
120
+ }
121
+
122
+ unmount(): void {
123
+ super.unmount();
124
+ }
125
+ }
126
+
127
+ export const collapse = CollapseController.getInstance(
128
+ "runtime",
129
+ typeof document !== "undefined" ? document : undefined
130
+ );
@@ -1,7 +1,7 @@
1
- import { DATA_POPUP, DATA_POPUP_ROLE, PopupRole } from "./consts";
2
- import { PopupController } from "./popup";
1
+ import { DATA_OPENABLE, DATA_OPENABLE_ROLE, OpenAble } from "./consts";
2
+ import { OpenableController } from "./OpenableController";
3
3
 
4
- export class ModalController extends PopupController {
4
+ export class ModalController extends OpenableController {
5
5
  private static instances: Record<string, ModalController> = {};
6
6
 
7
7
  private constructor(doc?: Document) {
@@ -37,26 +37,26 @@ export class ModalController extends PopupController {
37
37
 
38
38
  mount() {
39
39
  super.mount();
40
- const popups = this.doc?.querySelectorAll(`[${DATA_POPUP}]`);
40
+ const popups = this.doc?.querySelectorAll(`[${DATA_OPENABLE}]`);
41
41
  popups?.forEach((popup) => {
42
- const popupKey = popup.getAttribute(DATA_POPUP);
42
+ const openableKey = popup.getAttribute(DATA_OPENABLE);
43
43
  //处理鼠标交互事件
44
- if (popupKey && popup) {
45
- if (popup.getAttribute(DATA_POPUP_ROLE) === PopupRole.ModalTrigger) {
46
- const unsub = this.initModalTrigger(popupKey, popup as HTMLElement);
44
+ if (openableKey && popup) {
45
+ if (popup.getAttribute(DATA_OPENABLE_ROLE) === OpenAble.ModalTrigger) {
46
+ const unsub = this.initModalTrigger(openableKey, popup as HTMLElement);
47
47
  this.unmountHandlers.push(unsub);
48
48
  }
49
49
  }
50
50
  //获取所有 ModalCloser 实例,并处理点击事件
51
51
  //TODO:未处理嵌套跟Modal外部关闭的情况
52
52
  const closers = popup?.querySelectorAll(
53
- `[${DATA_POPUP_ROLE}="${PopupRole.ModalCloser}"]`
53
+ `[${DATA_OPENABLE_ROLE}="${OpenAble.ModalCloser}"]`
54
54
  );
55
55
 
56
56
  closers?.forEach((closer) => {
57
57
  // 使用initModalCloser函数处理关闭按钮事件
58
- if (popupKey) {
59
- const unsub = this.initModalCloser(popupKey, closer as HTMLElement);
58
+ if (openableKey) {
59
+ const unsub = this.initModalCloser(openableKey, closer as HTMLElement);
60
60
  this.unmountHandlers.push(unsub);
61
61
  }
62
62
  });
@@ -64,18 +64,18 @@ export class ModalController extends PopupController {
64
64
  }
65
65
  /**
66
66
  * 初始化Modal的点击交互事件
67
- * @param popupKey - 弹出层的唯一标识
67
+ * @param openableKey - 弹出层的唯一标识
68
68
  * @param trigger - 触发器元素
69
69
  * @returns 清理函数,用于移除事件监听器
70
70
  */
71
- public initModalTrigger(popupKey: string, trigger: HTMLElement): () => void {
71
+ public initModalTrigger(openableKey: string, trigger: HTMLElement): () => void {
72
72
  if (!this.doc) return () => {};
73
73
 
74
74
  try {
75
75
  // 创建新的事件处理函数
76
76
  const handleTriggerClick = () => {
77
77
  // 查找 Modal 容器
78
- this.open(popupKey, trigger);
78
+ this.open(openableKey, trigger);
79
79
  };
80
80
 
81
81
  // 添加新的事件监听器
@@ -85,24 +85,24 @@ export class ModalController extends PopupController {
85
85
  trigger.removeEventListener("click", handleTriggerClick);
86
86
  };
87
87
  } catch (error) {
88
- console.error(`初始化Modal事件失败: ${popupKey}`, error);
88
+ console.error(`初始化Modal事件失败: ${openableKey}`, error);
89
89
  return () => {};
90
90
  }
91
91
  }
92
92
 
93
93
  /**
94
94
  * 初始化Modal关闭按钮的点击交互事件
95
- * @param popupKey - 弹出层的唯一标识
95
+ * @param openableKey - 弹出层的唯一标识
96
96
  * @param closer - 关闭按钮元素
97
97
  * @returns 清理函数,用于移除事件监听器
98
98
  */
99
- public initModalCloser(popupKey: string, closer: HTMLElement): () => void {
99
+ public initModalCloser(openableKey: string, closer: HTMLElement): () => void {
100
100
  if (!this.doc) return () => {};
101
101
 
102
102
  try {
103
103
  // 创建新的事件处理函数
104
104
  const handleCloserClick = () => {
105
- this.close(popupKey);
105
+ this.close(openableKey);
106
106
  };
107
107
 
108
108
  // 添加新的事件监听器
@@ -112,7 +112,7 @@ export class ModalController extends PopupController {
112
112
  closer.removeEventListener("click", handleCloserClick);
113
113
  };
114
114
  } catch (error) {
115
- console.error(`初始化Modal关闭按钮事件失败: ${popupKey}`, error);
115
+ console.error(`初始化Modal关闭按钮事件失败: ${openableKey}`, error);
116
116
  return () => {};
117
117
  }
118
118
  }