@deriv-web-design/ui 0.1.15 → 0.1.18

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/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // index.ts
@@ -79,6 +89,8 @@ __export(index_exports, {
79
89
  ParallaxBanner: () => ParallaxBanner,
80
90
  PartnersPayout: () => PartnersPayout,
81
91
  PeopleGrid: () => PeopleGrid,
92
+ RESOURCE_BANNER_DERIV_CONTENT: () => RESOURCE_BANNER_DERIV_CONTENT,
93
+ ResourceBanner: () => ResourceBanner,
82
94
  STEPS_DATA: () => STEPS_DATA,
83
95
  SearchField: () => SearchField,
84
96
  Stats: () => Stats,
@@ -149,6 +161,7 @@ var Link = ({
149
161
  colorScheme = "coral",
150
162
  label,
151
163
  icon,
164
+ iconPosition = "left",
152
165
  showChevron = true,
153
166
  disabled = false,
154
167
  children,
@@ -180,8 +193,9 @@ var Link = ({
180
193
  onClick: handleClick,
181
194
  ...props,
182
195
  children: [
183
- hasIcon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "icon", children: icon }),
196
+ hasIcon && iconPosition === "left" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "icon", children: icon }),
184
197
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "label", children: label ?? children }),
198
+ hasIcon && iconPosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "icon", children: icon }),
185
199
  !hasIcon && showChevron && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "chevron", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChevronIcon, {}) })
186
200
  ]
187
201
  }
@@ -2631,18 +2645,22 @@ var import_react13 = require("react");
2631
2645
 
2632
2646
  // components/DotLottieInView/DotLottieInView.tsx
2633
2647
  var import_react12 = require("react");
2634
- var import_dotlottie_react = require("@lottiefiles/dotlottie-react");
2635
2648
  var import_jsx_runtime27 = require("react/jsx-runtime");
2649
+ var DotLottiePlayer = (0, import_react12.lazy)(
2650
+ () => import("@lottiefiles/dotlottie-react").then((m) => ({ default: m.DotLottieReact }))
2651
+ );
2636
2652
  function DotLottieInView({
2637
2653
  enabled = true,
2638
2654
  rootMargin = "0px",
2639
2655
  threshold = 0.2,
2640
2656
  className,
2641
2657
  style,
2658
+ poster,
2642
2659
  ...dotProps
2643
2660
  }) {
2644
2661
  const wrapRef = (0, import_react12.useRef)(null);
2645
2662
  const [inView, setInView] = (0, import_react12.useState)(false);
2663
+ const [mounted, setMounted] = (0, import_react12.useState)(false);
2646
2664
  const [dotLottie, setDotLottie] = (0, import_react12.useState)(null);
2647
2665
  (0, import_react12.useEffect)(() => {
2648
2666
  const el = wrapRef.current;
@@ -2656,6 +2674,24 @@ function DotLottieInView({
2656
2674
  observer.observe(el);
2657
2675
  return () => observer.disconnect();
2658
2676
  }, [rootMargin, threshold]);
2677
+ (0, import_react12.useEffect)(() => {
2678
+ if (mounted) return;
2679
+ if (!(inView && enabled)) return;
2680
+ if (typeof window === "undefined") return;
2681
+ let cancelled = false;
2682
+ const commit = () => {
2683
+ if (!cancelled) setMounted(true);
2684
+ };
2685
+ const idleId = typeof window.requestIdleCallback === "function" ? window.requestIdleCallback(commit, { timeout: 400 }) : null;
2686
+ const timerId = idleId === null ? window.setTimeout(commit, 0) : null;
2687
+ return () => {
2688
+ cancelled = true;
2689
+ if (idleId !== null && typeof window.cancelIdleCallback === "function") {
2690
+ window.cancelIdleCallback(idleId);
2691
+ }
2692
+ if (timerId !== null) window.clearTimeout(timerId);
2693
+ };
2694
+ }, [inView, enabled, mounted]);
2659
2695
  (0, import_react12.useEffect)(() => {
2660
2696
  if (!dotLottie) return;
2661
2697
  if (!enabled || !inView) {
@@ -2680,15 +2716,15 @@ function DotLottieInView({
2680
2716
  backgroundColor: "transparent",
2681
2717
  ...style
2682
2718
  },
2683
- children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2684
- import_dotlottie_react.DotLottieReact,
2719
+ children: mounted ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react12.Suspense, { fallback: poster ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2720
+ DotLottiePlayer,
2685
2721
  {
2686
2722
  ...dotProps,
2687
2723
  loop: false,
2688
2724
  autoplay: false,
2689
2725
  dotLottieRefCallback: setDotLottie
2690
2726
  }
2691
- )
2727
+ ) }) : poster ?? null
2692
2728
  }
2693
2729
  );
2694
2730
  }
@@ -2760,26 +2796,45 @@ var ChevronRight2 = () => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2760
2796
  )
2761
2797
  }
2762
2798
  );
2799
+ function mediaSrc(item) {
2800
+ return typeof item.mediaUrl === "string" && item.mediaUrl !== "" ? item.mediaUrl : null;
2801
+ }
2763
2802
  function resolveMediaType(item) {
2764
2803
  if (item.mediaType) return item.mediaType;
2765
- return item.mediaUrl.split("?")[0].endsWith(".lottie") ? "lottie" : "image";
2804
+ const src = mediaSrc(item);
2805
+ return src?.split("?")[0].endsWith(".lottie") ? "lottie" : "image";
2766
2806
  }
2767
- var MediaRenderer = ({ item, active }) => {
2807
+ var MediaRenderer = ({ item, active, rootMargin, threshold }) => {
2808
+ const src = mediaSrc(item);
2809
+ if (!src) return null;
2768
2810
  if (resolveMediaType(item) === "lottie") {
2769
2811
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2770
2812
  DotLottieInView,
2771
2813
  {
2772
- src: item.mediaUrl,
2773
- enabled: active
2814
+ src,
2815
+ enabled: active,
2816
+ rootMargin,
2817
+ threshold,
2818
+ poster: item.posterUrl ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2819
+ "img",
2820
+ {
2821
+ src: item.posterUrl,
2822
+ alt: "",
2823
+ "aria-hidden": "true",
2824
+ loading: "lazy",
2825
+ decoding: "async"
2826
+ }
2827
+ ) : void 0
2774
2828
  }
2775
2829
  );
2776
2830
  }
2777
2831
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2778
2832
  "img",
2779
2833
  {
2780
- src: item.mediaUrl,
2834
+ src,
2781
2835
  alt: item.title,
2782
- loading: "lazy"
2836
+ loading: "lazy",
2837
+ decoding: "async"
2783
2838
  }
2784
2839
  );
2785
2840
  };
@@ -2788,10 +2843,16 @@ var FeatureScroll = ({
2788
2843
  items,
2789
2844
  variant = "media-right",
2790
2845
  className,
2846
+ // Destructured, not spread: `...props` lands on the <section>, and an
2847
+ // unknown attribute there is a React DOM warning at best.
2848
+ mediaRootMargin,
2849
+ mediaThreshold,
2791
2850
  ...props
2792
2851
  }) => {
2793
2852
  const [activeIndex, setActiveIndex] = (0, import_react13.useState)(0);
2853
+ const [mobileActiveIndex, setMobileActiveIndex] = (0, import_react13.useState)(0);
2794
2854
  const titleRefs = (0, import_react13.useRef)([]);
2855
+ const mobileItemRefs = (0, import_react13.useRef)([]);
2795
2856
  const mediaColRef = (0, import_react13.useRef)(null);
2796
2857
  (0, import_react13.useLayoutEffect)(() => {
2797
2858
  if (items.length === 0) return;
@@ -2839,6 +2900,40 @@ var FeatureScroll = ({
2839
2900
  if (rafId !== 0) window.cancelAnimationFrame(rafId);
2840
2901
  };
2841
2902
  }, [items.length]);
2903
+ (0, import_react13.useEffect)(() => {
2904
+ if (items.length === 0) return;
2905
+ if (typeof window === "undefined") return;
2906
+ const ratios = /* @__PURE__ */ new Map();
2907
+ const observer = new IntersectionObserver(
2908
+ (entries) => {
2909
+ if (window.matchMedia("(min-width: 992px)").matches) return;
2910
+ for (const entry of entries) {
2911
+ const idx = Number(entry.target.getAttribute("data-fs-mobile-idx"));
2912
+ if (!Number.isFinite(idx)) continue;
2913
+ ratios.set(idx, entry.isIntersecting ? entry.intersectionRatio : 0);
2914
+ }
2915
+ let best = 0;
2916
+ let bestRatio = -1;
2917
+ for (const [idx, ratio] of ratios) {
2918
+ if (ratio > bestRatio) {
2919
+ bestRatio = ratio;
2920
+ best = idx;
2921
+ }
2922
+ }
2923
+ if (bestRatio <= 0) return;
2924
+ setMobileActiveIndex((prev) => prev === best ? prev : best);
2925
+ },
2926
+ {
2927
+ root: null,
2928
+ rootMargin: "-28% 0px -28% 0px",
2929
+ threshold: [0, 0.15, 0.3, 0.5, 0.75, 1]
2930
+ }
2931
+ );
2932
+ for (const el of mobileItemRefs.current) {
2933
+ if (el) observer.observe(el);
2934
+ }
2935
+ return () => observer.disconnect();
2936
+ }, [items.length]);
2842
2937
  const rootClass = [
2843
2938
  "fs",
2844
2939
  `fs--${variant}`,
@@ -2866,7 +2961,9 @@ var FeatureScroll = ({
2866
2961
  MediaRenderer,
2867
2962
  {
2868
2963
  item,
2869
- active: i === activeIndex
2964
+ active: i === activeIndex,
2965
+ rootMargin: mediaRootMargin,
2966
+ threshold: mediaThreshold
2870
2967
  }
2871
2968
  )
2872
2969
  },
@@ -2906,22 +3003,41 @@ var FeatureScroll = ({
2906
3003
  i
2907
3004
  )) })
2908
3005
  ] }),
2909
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "fs__mobile-list", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "fs__mobile-item", children: [
2910
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h3", { className: "fs__item-title", children: item.title }),
2911
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "fs__mobile-media", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(MediaRenderer, { item, active: true }) }),
2912
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "fs__item-desc", children: item.description }),
2913
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
2914
- "a",
2915
- {
2916
- href: item.link,
2917
- className: "fs__item-link",
2918
- children: [
2919
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: item.linkLabel }),
2920
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChevronRight2, {})
2921
- ]
2922
- }
2923
- )
2924
- ] }, i)) })
3006
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "fs__mobile-list", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
3007
+ "div",
3008
+ {
3009
+ className: "fs__mobile-item",
3010
+ "data-fs-mobile-idx": i,
3011
+ ref: (el) => {
3012
+ mobileItemRefs.current[i] = el;
3013
+ },
3014
+ children: [
3015
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h3", { className: "fs__item-title", children: item.title }),
3016
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "fs__mobile-media", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3017
+ MediaRenderer,
3018
+ {
3019
+ item,
3020
+ active: i === mobileActiveIndex,
3021
+ rootMargin: mediaRootMargin,
3022
+ threshold: mediaThreshold
3023
+ }
3024
+ ) }),
3025
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "fs__item-desc", children: item.description }),
3026
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
3027
+ "a",
3028
+ {
3029
+ href: item.link,
3030
+ className: "fs__item-link",
3031
+ children: [
3032
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: item.linkLabel }),
3033
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChevronRight2, {})
3034
+ ]
3035
+ }
3036
+ )
3037
+ ]
3038
+ },
3039
+ i
3040
+ )) })
2925
3041
  ] }) });
2926
3042
  };
2927
3043
 
@@ -8335,6 +8451,66 @@ var MasterPartner = ({
8335
8451
  ] }, index)) })
8336
8452
  ] }) });
8337
8453
  };
8454
+
8455
+ // templates/ResourceBanner/ResourceBanner.tsx
8456
+ var import_jsx_runtime62 = require("react/jsx-runtime");
8457
+ var DEFAULT_LINKS = [{ label: "Learn more", href: "#" }];
8458
+ var RESOURCE_BANNER_DERIV_CONTENT = {
8459
+ title: "Learn more about staying safe",
8460
+ description: "Read our guide on secure and responsible trading for more on protecting your account.",
8461
+ links: [
8462
+ {
8463
+ id: "responsible",
8464
+ label: "Secure and responsible trading",
8465
+ href: "/responsible",
8466
+ external: true
8467
+ }
8468
+ ]
8469
+ };
8470
+ var ExternalLinkIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
8471
+ "path",
8472
+ {
8473
+ d: "M4.5 11.5 11.5 4.5M5.5 4.5h6v6",
8474
+ stroke: "currentColor",
8475
+ strokeWidth: "1.75",
8476
+ strokeLinecap: "round",
8477
+ strokeLinejoin: "round"
8478
+ }
8479
+ ) });
8480
+ var ResourceBanner = ({
8481
+ title = "Section title goes here",
8482
+ description = "Explain how this specific feature helps your user.",
8483
+ links,
8484
+ headingLevel: HeadingTag = "h2",
8485
+ className,
8486
+ ...props
8487
+ }) => {
8488
+ const resolvedLinks = links && links.length > 0 ? links : DEFAULT_LINKS;
8489
+ const rootClass = ["rsb", className].filter(Boolean).join(" ");
8490
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("section", { className: rootClass, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "rsb__inner", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "rsb__card", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "rsb__grid", children: [
8491
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "rsb__content", children: [
8492
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(HeadingTag, { className: "rsb__title", children: title }),
8493
+ description && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "rsb__description", children: description })
8494
+ ] }),
8495
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("ul", { className: "rsb__links", children: resolvedLinks.map((link, i) => {
8496
+ const isExternal = link.external ?? true;
8497
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("li", { className: "rsb__links-item", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
8498
+ Link,
8499
+ {
8500
+ className: "rsb__link",
8501
+ colorScheme: "white",
8502
+ href: link.href,
8503
+ label: link.label,
8504
+ icon: isExternal ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(ExternalLinkIcon2, {}) : void 0,
8505
+ iconPosition: "right",
8506
+ showChevron: !isExternal,
8507
+ target: isExternal ? "_blank" : void 0,
8508
+ rel: isExternal ? "noopener noreferrer" : void 0
8509
+ }
8510
+ ) }, link.id ?? i);
8511
+ }) })
8512
+ ] }) }) }) });
8513
+ };
8338
8514
  // Annotate the CommonJS export names for ESM import in node:
8339
8515
  0 && (module.exports = {
8340
8516
  AVATAR_DATA,
@@ -8396,6 +8572,8 @@ var MasterPartner = ({
8396
8572
  ParallaxBanner,
8397
8573
  PartnersPayout,
8398
8574
  PeopleGrid,
8575
+ RESOURCE_BANNER_DERIV_CONTENT,
8576
+ ResourceBanner,
8399
8577
  STEPS_DATA,
8400
8578
  SearchField,
8401
8579
  Stats,