@rxdrag/website-lib-core 0.0.8 → 0.0.10

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 +4 -4
  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/PageLoader.ts +3 -13
  11. package/src/controller/PopoverController.ts +13 -13
  12. package/src/controller/TabsController.ts +1 -1
  13. package/src/controller/consts.ts +9 -6
  14. package/src/controller/index.ts +1 -0
  15. package/src/entify/IEntify.ts +1 -1
  16. package/src/entify/lib/newQueryProductOptions.ts +2 -11
  17. package/src/entify/lib/queryOneProductBySlug.ts +52 -10
  18. package/src/entify/lib/queryOneTheme.ts +1 -7
  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 +13 -5
  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
@@ -92,6 +92,13 @@ export type ContactFormProps = {
92
92
  submitAlign?: "left" | "center" | "right";
93
93
  actionUrl?: string;
94
94
  formSalt: string;
95
+ labels?: {
96
+ name?: string;
97
+ email?: string;
98
+ company?: string;
99
+ message?: string;
100
+ submit?: string;
101
+ };
95
102
  };
96
103
 
97
104
  export const ContactForm = forwardRef<HTMLDivElement, ContactFormProps>(
@@ -100,6 +107,7 @@ export const ContactForm = forwardRef<HTMLDivElement, ContactFormProps>(
100
107
  submitAlign = "right",
101
108
  actionUrl = "/api/ask-for-quote",
102
109
  formSalt,
110
+ labels = {},
103
111
  } = props;
104
112
  const [formData, setFormData] = useState<QuoteRequest>({
105
113
  name: "",
@@ -256,7 +264,7 @@ export const ContactForm = forwardRef<HTMLDivElement, ContactFormProps>(
256
264
  <Input
257
265
  className="sm:col-span-1"
258
266
  inputClassName="mt-2 block w-full rounded-md outline-none border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-sky-600 sm:text-sm sm:leading-6"
259
- label="Your Email *"
267
+ label={(labels?.email || "Your Email") + " *"}
260
268
  labelClassName="block text-sm font-medium leading-6 text-gray-900"
261
269
  name="email"
262
270
  required={true}
@@ -269,7 +277,7 @@ export const ContactForm = forwardRef<HTMLDivElement, ContactFormProps>(
269
277
  <Input
270
278
  className="sm:col-span-1"
271
279
  inputClassName="mt-2 block w-full rounded-md outline-none border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-sky-600 sm:text-sm sm:leading-6"
272
- label="Your Name"
280
+ label={(labels?.name || "Your Name") + " *"}
273
281
  labelClassName="block text-sm font-medium leading-6 text-gray-900"
274
282
  name="name"
275
283
  value={formData.name}
@@ -279,7 +287,7 @@ export const ContactForm = forwardRef<HTMLDivElement, ContactFormProps>(
279
287
  <Input
280
288
  className="col-span-full"
281
289
  inputClassName="mt-2 block w-full rounded-md outline-none border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-sky-600 sm:text-sm sm:leading-6"
282
- label="Company"
290
+ label={(labels?.company || "Company") + " *"}
283
291
  labelClassName="block text-sm font-medium leading-6 text-gray-900"
284
292
  name="company"
285
293
  value={formData.company}
@@ -287,7 +295,7 @@ export const ContactForm = forwardRef<HTMLDivElement, ContactFormProps>(
287
295
  />
288
296
  <Textarea
289
297
  className="col-span-full"
290
- label="Message *"
298
+ label={(labels?.message || "Message") + " *"}
291
299
  labelClassName="block text-sm font-medium leading-6 text-gray-900"
292
300
  name="message"
293
301
  required={true}
@@ -325,7 +333,7 @@ export const ContactForm = forwardRef<HTMLDivElement, ContactFormProps>(
325
333
  )}
326
334
  <Submit
327
335
  className="flex gap-2 items-center relative shadow-sm btn btn-primary btn-lg nowrap"
328
- title="Send Message"
336
+ title={labels?.submit || "Send Message"}
329
337
  spinner={
330
338
  <div className="left-8 flex items-center justify-center">
331
339
  <div className="animate-spin rounded-full h-5 w-5 border-t-2 border-b-2 border-white" />
@@ -1,10 +1,14 @@
1
- import { Icon as IconifyIcon, IconProps as IconifyIconProps } from "@iconify/react";
1
+ import {
2
+ Icon as IconifyIcon,
3
+ IconProps as IconifyIconProps,
4
+ } from "@iconify/react";
5
+ import { forwardRef } from "react";
2
6
 
3
7
  export type IconProps = Omit<IconifyIconProps, "icon"> & {
4
8
  icon?: string;
5
9
  };
6
10
 
7
- export function Icon(props: IconProps) {
11
+ export const Icon = forwardRef<SVGSVGElement, IconProps>((props, ref) => {
8
12
  const { icon, ...rest } = props;
9
- return icon ? <IconifyIcon {...rest} icon={icon} /> : null;
10
- }
13
+ return icon ? <IconifyIcon ref={ref} {...rest} icon={icon} /> : null;
14
+ });
@@ -8,6 +8,7 @@ export type TSlateProduct = TSlateResizable & {
8
8
  title?: string;
9
9
  description?: string;
10
10
  aspect?: string;
11
+ ctaTitle?: string;
11
12
  };
12
13
 
13
14
  export const PRODUCT_KEY = "Product";
@@ -19,5 +20,5 @@ export type ProductCardProps = {
19
20
 
20
21
  // Slate用的渲染组件
21
22
  export const ProductCard = ({ node }: ProductCardProps) => {
22
- return <ProductView product={node?.product} node={node} />;
23
+ return <ProductView product={node?.product} node={node} ctaTitle={node?.ctaTitle}/>;
23
24
  };
@@ -1,30 +1,31 @@
1
1
  import { Product } from "@rxdrag/rxcms-models";
2
2
  import "./style.css";
3
3
  import {
4
- DATA_POPUP,
4
+ DATA_OPENABLE,
5
5
  DATA_POPUP_CTA,
6
- DATA_POPUP_ROLE,
6
+ DATA_OPENABLE_ROLE,
7
7
  popover,
8
- PopupRole,
8
+ OpenAble,
9
9
  } from "../../../../controller";
10
10
  import { useRef } from "react";
11
11
 
12
12
  //TODO: 跟询盘触发器同样的实现原理,给询盘对话框发消息
13
- export function ProductCta(props: { product?: Product; popupKey?: string }) {
14
- const { product, popupKey = "enquiry-modal" } = props;
13
+ export function ProductCta(props: {
14
+ product?: Product;
15
+ openableKey?: string;
16
+ children?: React.ReactNode;
17
+ }) {
18
+ const { product, openableKey = "enquiry-modal", children } = props;
15
19
  const ref = useRef<HTMLButtonElement>(null);
16
20
  const roleProps = {
17
21
  [DATA_POPUP_CTA]: `From RichText ProductCard-${product?.title}-${product?.id}`,
18
- [DATA_POPUP_ROLE]: PopupRole.ModalTrigger,
19
- [DATA_POPUP]: popupKey,
22
+ [DATA_OPENABLE_ROLE]: OpenAble.ModalTrigger,
23
+ [DATA_OPENABLE]: openableKey,
20
24
  };
21
25
 
22
26
  const handleClick = () => {
23
27
  if (ref.current) {
24
- popover.open(
25
- roleProps[DATA_POPUP_CTA] || popupKey,
26
- ref.current
27
- );
28
+ popover.open(roleProps[DATA_POPUP_CTA] || openableKey, ref.current);
28
29
  }
29
30
  };
30
31
 
@@ -36,7 +37,7 @@ export function ProductCta(props: { product?: Product; popupKey?: string }) {
36
37
  className="product-cta-button relative flex-1 mt-2 flex items-center justify-center rounded-md border border-transparent bg-sky-600 text-md font-smibold text-white hover:bg-sky-700"
37
38
  onClick={handleClick}
38
39
  >
39
- Get a quote
40
+ {children || "Get a quote"}
40
41
  </button>
41
42
  </div>
42
43
  );
@@ -9,9 +9,10 @@ import { ProductCta } from "./ProductCta";
9
9
  export function ProductView(
10
10
  props: {
11
11
  product?: Product;
12
+ ctaTitle?: string;
12
13
  } & ProductCardProps
13
14
  ) {
14
- const { product, node } = props;
15
+ const { product, ctaTitle, node } = props;
15
16
 
16
17
  const title = node?.title || product?.title;
17
18
  const description = node?.description || product?.description;
@@ -28,7 +29,7 @@ export function ProductView(
28
29
  <ProductTitle>{title}</ProductTitle>
29
30
  </a>
30
31
  <ProductDescription>{description}</ProductDescription>
31
- <ProductCta product={product} />
32
+ <ProductCta product={product}>{ctaTitle}</ProductCta>
32
33
  </Figcaption>
33
34
  </Figure>
34
35
  );
@@ -17,7 +17,7 @@ export const ToTop = forwardRef<HTMLDivElement, ToTopProps>((
17
17
  ref={ref}
18
18
  className={
19
19
  clsx(
20
- "fixed bottom-4 right-4 hidden user-select-none scrolling:flex cursor-pointer transition duration-300 ease-in-out z-50",
20
+ "fixed bottom-4 right-4 hidden user-select-none scrolled:flex cursor-pointer transition duration-300 ease-in-out z-50",
21
21
  className,
22
22
  )
23
23
  }
@@ -56,7 +56,7 @@ export const ToTop = forwardRef<HTMLDivElement, ToTopProps>((props, ref) => {
56
56
  <div
57
57
  ref={innerRef}
58
58
  className={clsx(
59
- "fixed bottom-4 right-4 hidden user-select-none shadow-lg scrolling:flex cursor-pointer transition duration-300 ease-in-out z-50",
59
+ "fixed bottom-4 right-4 hidden user-select-none shadow-lg scrolled:flex cursor-pointer transition duration-300 ease-in-out z-50",
60
60
  className
61
61
  )}
62
62
  {...rest}
@@ -1,28 +1,29 @@
1
1
  import { useCallback, useEffect } from "react";
2
2
 
3
- export const defualtThreshold = 10;
3
+ export const defaultThreshold = 10;
4
4
 
5
5
  export function useScroll(
6
- threshold: number = defualtThreshold,
7
- win: Window | undefined = typeof window !== 'undefined' ? window : undefined,
8
- doc: Document | undefined = typeof document !== 'undefined' ? document : undefined
6
+ threshold: number = defaultThreshold,
7
+ win: Window | undefined = typeof window !== "undefined" ? window : undefined,
8
+ doc: Document | undefined = typeof document !== "undefined"
9
+ ? document
10
+ : undefined
9
11
  ) {
10
-
11
12
  const onScroll = useCallback(() => {
12
13
  if (!win || !doc) return;
13
-
14
- const scrolling = win.scrollY > threshold;
15
14
 
16
- if (scrolling) {
17
- doc.body.classList.add("scrolling");
15
+ const scrolled = win.scrollY > threshold;
16
+
17
+ if (scrolled) {
18
+ doc.body.classList.add("scrolled");
18
19
  } else {
19
- doc.body.classList.remove("scrolling");
20
+ doc.body.classList.remove("scrolled");
20
21
  }
21
22
  }, [threshold, win, doc]);
22
23
 
23
24
  useEffect(() => {
24
25
  if (!win) return;
25
-
26
+
26
27
  win.addEventListener("scroll", onScroll);
27
28
  return () => win.removeEventListener("scroll", onScroll);
28
29
  }, [onScroll, win]);