analytica-frontend-lib 1.1.77 → 1.1.79

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
@@ -2398,9 +2398,23 @@ var injectStore3 = (children, store) => {
2398
2398
  return import_react13.Children.map(children, (child) => {
2399
2399
  if ((0, import_react13.isValidElement)(child)) {
2400
2400
  const typedChild = child;
2401
- const newProps = {
2402
- store
2403
- };
2401
+ const displayName = typedChild.type.displayName;
2402
+ const allowed = [
2403
+ "DropdownMenuTrigger",
2404
+ "DropdownContent",
2405
+ "DropdownMenuContent",
2406
+ "DropdownMenuSeparator",
2407
+ "DropdownMenuItem",
2408
+ "MenuLabel",
2409
+ "ProfileMenuTrigger",
2410
+ "ProfileMenuHeader",
2411
+ "ProfileMenuFooter",
2412
+ "ProfileToggleTheme"
2413
+ ];
2414
+ let newProps = {};
2415
+ if (allowed.includes(displayName)) {
2416
+ newProps.store = store;
2417
+ }
2404
2418
  if (typedChild.props.children) {
2405
2419
  newProps.children = injectStore3(typedChild.props.children, store);
2406
2420
  }
@@ -2486,13 +2500,22 @@ var DropdownMenuTrigger = ({
2486
2500
  const open = (0, import_zustand5.useStore)(store, (s) => s.open);
2487
2501
  const toggleOpen = () => store.setState({ open: !open });
2488
2502
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2489
- "button",
2503
+ "div",
2490
2504
  {
2491
2505
  onClick: (e) => {
2492
2506
  e.stopPropagation();
2493
2507
  toggleOpen();
2494
2508
  if (onClick) onClick(e);
2495
2509
  },
2510
+ role: "button",
2511
+ onKeyDown: (e) => {
2512
+ if (e.key === "Enter" || e.key === " ") {
2513
+ e.preventDefault();
2514
+ toggleOpen();
2515
+ if (onClick) onClick(e);
2516
+ }
2517
+ },
2518
+ tabIndex: 0,
2496
2519
  "aria-expanded": open,
2497
2520
  className: cn(className),
2498
2521
  ...props,
@@ -6780,6 +6803,10 @@ var getSubjectName = (subject) => {
6780
6803
  var import_react22 = require("react");
6781
6804
  var MOBILE_WIDTH = 500;
6782
6805
  var TABLET_WIDTH = 931;
6806
+ var SMALL_MOBILE_WIDTH = 425;
6807
+ var EXTRA_SMALL_MOBILE_WIDTH = 375;
6808
+ var ULTRA_SMALL_MOBILE_WIDTH = 375;
6809
+ var TINY_MOBILE_WIDTH = 320;
6783
6810
  var DEFAULT_WIDTH = 1200;
6784
6811
  var getWindowWidth = () => {
6785
6812
  if (typeof window === "undefined") {
@@ -6794,11 +6821,19 @@ var getDeviceType = () => {
6794
6821
  var useMobile = () => {
6795
6822
  const [isMobile, setIsMobile] = (0, import_react22.useState)(false);
6796
6823
  const [isTablet, setIsTablet] = (0, import_react22.useState)(false);
6824
+ const [isSmallMobile, setIsSmallMobile] = (0, import_react22.useState)(false);
6825
+ const [isExtraSmallMobile, setIsExtraSmallMobile] = (0, import_react22.useState)(false);
6826
+ const [isUltraSmallMobile, setIsUltraSmallMobile] = (0, import_react22.useState)(false);
6827
+ const [isTinyMobile, setIsTinyMobile] = (0, import_react22.useState)(false);
6797
6828
  (0, import_react22.useEffect)(() => {
6798
6829
  const checkScreenSize = () => {
6799
6830
  const width = getWindowWidth();
6800
6831
  setIsMobile(width < MOBILE_WIDTH);
6801
6832
  setIsTablet(width < TABLET_WIDTH);
6833
+ setIsSmallMobile(width < SMALL_MOBILE_WIDTH);
6834
+ setIsExtraSmallMobile(width < EXTRA_SMALL_MOBILE_WIDTH);
6835
+ setIsUltraSmallMobile(width < ULTRA_SMALL_MOBILE_WIDTH);
6836
+ setIsTinyMobile(width < TINY_MOBILE_WIDTH);
6802
6837
  };
6803
6838
  checkScreenSize();
6804
6839
  window.addEventListener("resize", checkScreenSize);
@@ -6822,13 +6857,24 @@ var useMobile = () => {
6822
6857
  const getHeaderClasses = () => {
6823
6858
  return isMobile ? getMobileHeaderClasses() : getDesktopHeaderClasses();
6824
6859
  };
6860
+ const getVideoContainerClasses = () => {
6861
+ if (isTinyMobile) return "aspect-square";
6862
+ if (isExtraSmallMobile) return "aspect-[4/3]";
6863
+ if (isSmallMobile) return "aspect-[16/12]";
6864
+ return "aspect-video";
6865
+ };
6825
6866
  return {
6826
6867
  isMobile,
6827
6868
  isTablet,
6869
+ isSmallMobile,
6870
+ isExtraSmallMobile,
6871
+ isUltraSmallMobile,
6872
+ isTinyMobile,
6828
6873
  getFormContainerClasses,
6829
6874
  getHeaderClasses,
6830
6875
  getMobileHeaderClasses,
6831
6876
  getDesktopHeaderClasses,
6877
+ getVideoContainerClasses,
6832
6878
  getDeviceType
6833
6879
  };
6834
6880
  };
@@ -7761,8 +7807,9 @@ var ProgressBar2 = ({
7761
7807
  currentTime,
7762
7808
  duration,
7763
7809
  progressPercentage,
7764
- onSeek
7765
- }) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "px-4 pb-2", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
7810
+ onSeek,
7811
+ className = "px-4 pb-2"
7812
+ }) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
7766
7813
  "input",
7767
7814
  {
7768
7815
  type: "range",
@@ -7781,18 +7828,20 @@ var VolumeControls = ({
7781
7828
  volume,
7782
7829
  isMuted,
7783
7830
  onVolumeChange,
7784
- onToggleMute
7831
+ onToggleMute,
7832
+ iconSize = 24,
7833
+ showSlider = true
7785
7834
  }) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-2", children: [
7786
7835
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
7787
7836
  IconButton_default,
7788
7837
  {
7789
- icon: isMuted ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.SpeakerSlash, { size: 24 }) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.SpeakerHigh, { size: 24 }),
7838
+ icon: isMuted ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.SpeakerSlash, { size: iconSize }) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.SpeakerHigh, { size: iconSize }),
7790
7839
  onClick: onToggleMute,
7791
7840
  "aria-label": isMuted ? "Unmute" : "Mute",
7792
7841
  className: "!bg-transparent !text-white hover:!bg-white/20"
7793
7842
  }
7794
7843
  ),
7795
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
7844
+ showSlider && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
7796
7845
  "input",
7797
7846
  {
7798
7847
  type: "range",
@@ -7813,7 +7862,9 @@ var SpeedMenu = ({
7813
7862
  playbackRate,
7814
7863
  onToggleMenu,
7815
7864
  onSpeedChange,
7816
- isFullscreen
7865
+ isFullscreen,
7866
+ iconSize = 24,
7867
+ isTinyMobile = false
7817
7868
  }) => {
7818
7869
  const buttonRef = (0, import_react26.useRef)(null);
7819
7870
  const speedMenuContainerRef = (0, import_react26.useRef)(null);
@@ -7821,10 +7872,13 @@ var SpeedMenu = ({
7821
7872
  const getMenuPosition = () => {
7822
7873
  if (!buttonRef.current) return { top: 0, left: 0 };
7823
7874
  const rect = buttonRef.current.getBoundingClientRect();
7875
+ const menuHeight = isTinyMobile ? 150 : 180;
7876
+ const menuWidth = isTinyMobile ? 60 : 80;
7877
+ const padding = isTinyMobile ? 4 : 8;
7824
7878
  return {
7825
7879
  // Fixed coords are viewport-based — no scroll offsets.
7826
- top: Math.max(8, rect.top - 180),
7827
- left: Math.max(8, rect.right - 80)
7880
+ top: Math.max(padding, rect.top - menuHeight),
7881
+ left: Math.max(padding, rect.right - menuWidth)
7828
7882
  };
7829
7883
  };
7830
7884
  const position = getMenuPosition();
@@ -7877,7 +7931,7 @@ var SpeedMenu = ({
7877
7931
  IconButton_default,
7878
7932
  {
7879
7933
  ref: buttonRef,
7880
- icon: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.DotsThreeVertical, { size: 24 }),
7934
+ icon: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.DotsThreeVertical, { size: iconSize }),
7881
7935
  onClick: onToggleMenu,
7882
7936
  "aria-label": "Playback speed",
7883
7937
  "aria-haspopup": "menu",
@@ -7903,6 +7957,7 @@ var VideoPlayer = ({
7903
7957
  storageKey = "video-progress"
7904
7958
  }) => {
7905
7959
  const videoRef = (0, import_react26.useRef)(null);
7960
+ const { isUltraSmallMobile, isTinyMobile } = useMobile();
7906
7961
  const [isPlaying, setIsPlaying] = (0, import_react26.useState)(false);
7907
7962
  const [currentTime, setCurrentTime] = (0, import_react26.useState)(0);
7908
7963
  const [duration, setDuration] = (0, import_react26.useState)(0);
@@ -8005,6 +8060,12 @@ var VideoPlayer = ({
8005
8060
  video.removeEventListener("ended", onEnded);
8006
8061
  };
8007
8062
  }, []);
8063
+ (0, import_react26.useEffect)(() => {
8064
+ const video = videoRef.current;
8065
+ if (!video) return;
8066
+ video.setAttribute("playsinline", "");
8067
+ video.setAttribute("webkit-playsinline", "");
8068
+ }, []);
8008
8069
  (0, import_react26.useEffect)(() => {
8009
8070
  if (isPlaying) {
8010
8071
  showControlsWithTimer();
@@ -8211,6 +8272,31 @@ var VideoPlayer = ({
8211
8272
  };
8212
8273
  }, [isPlaying, clearControlsTimeout]);
8213
8274
  const progressPercentage = duration > 0 ? currentTime / duration * 100 : 0;
8275
+ const getIconSize2 = (0, import_react26.useCallback)(() => {
8276
+ if (isTinyMobile) return 18;
8277
+ if (isUltraSmallMobile) return 20;
8278
+ return 24;
8279
+ }, [isTinyMobile, isUltraSmallMobile]);
8280
+ const getControlsPadding = (0, import_react26.useCallback)(() => {
8281
+ if (isTinyMobile) return "px-2 pb-2 pt-1";
8282
+ if (isUltraSmallMobile) return "px-3 pb-3 pt-1";
8283
+ return "px-4 pb-4";
8284
+ }, [isTinyMobile, isUltraSmallMobile]);
8285
+ const getControlsGap = (0, import_react26.useCallback)(() => {
8286
+ if (isTinyMobile) return "gap-1";
8287
+ if (isUltraSmallMobile) return "gap-2";
8288
+ return "gap-4";
8289
+ }, [isTinyMobile, isUltraSmallMobile]);
8290
+ const getProgressBarPadding = (0, import_react26.useCallback)(() => {
8291
+ if (isTinyMobile) return "px-2 pb-1";
8292
+ if (isUltraSmallMobile) return "px-3 pb-1";
8293
+ return "px-4 pb-2";
8294
+ }, [isTinyMobile, isUltraSmallMobile]);
8295
+ const getCenterPlayButtonPosition = (0, import_react26.useCallback)(() => {
8296
+ if (isTinyMobile) return "items-center justify-center -translate-y-12";
8297
+ if (isUltraSmallMobile) return "items-center justify-center -translate-y-8";
8298
+ return "items-center justify-center";
8299
+ }, [isTinyMobile, isUltraSmallMobile]);
8214
8300
  const getTopControlsOpacity = (0, import_react26.useCallback)(() => {
8215
8301
  return showControls ? "opacity-100" : "opacity-0";
8216
8302
  }, [showControls]);
@@ -8318,8 +8404,9 @@ var VideoPlayer = ({
8318
8404
  ref: videoRef,
8319
8405
  src,
8320
8406
  poster,
8321
- className: "w-full h-full object-contain",
8407
+ className: "w-full h-full object-contain analytica-video",
8322
8408
  controlsList: "nodownload",
8409
+ playsInline: true,
8323
8410
  onTimeUpdate: handleTimeUpdate,
8324
8411
  onLoadedMetadata: handleLoadedMetadata,
8325
8412
  onClick: togglePlayPause,
@@ -8339,15 +8426,24 @@ var VideoPlayer = ({
8339
8426
  )
8340
8427
  }
8341
8428
  ),
8342
- !isPlaying && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-black/30 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8343
- IconButton_default,
8429
+ !isPlaying && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8430
+ "div",
8344
8431
  {
8345
- icon: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.Play, { size: 32, weight: "regular", className: "ml-1" }),
8346
- onClick: togglePlayPause,
8347
- "aria-label": "Play video",
8348
- className: "!bg-transparent !text-white !w-auto !h-auto hover:!bg-transparent hover:!text-gray-200"
8432
+ className: cn(
8433
+ "absolute inset-0 flex bg-black/30 transition-opacity",
8434
+ getCenterPlayButtonPosition()
8435
+ ),
8436
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8437
+ IconButton_default,
8438
+ {
8439
+ icon: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.Play, { size: 32, weight: "regular", className: "ml-1" }),
8440
+ onClick: togglePlayPause,
8441
+ "aria-label": "Play video",
8442
+ className: "!bg-transparent !text-white !w-auto !h-auto hover:!bg-transparent hover:!text-gray-200"
8443
+ }
8444
+ )
8349
8445
  }
8350
- ) }),
8446
+ ),
8351
8447
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8352
8448
  "div",
8353
8449
  {
@@ -8380,58 +8476,72 @@ var VideoPlayer = ({
8380
8476
  currentTime,
8381
8477
  duration,
8382
8478
  progressPercentage,
8383
- onSeek: handleSeek
8479
+ onSeek: handleSeek,
8480
+ className: getProgressBarPadding()
8384
8481
  }
8385
8482
  ),
8386
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center justify-between px-4 pb-4", children: [
8387
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-4", children: [
8388
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8389
- IconButton_default,
8390
- {
8391
- icon: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.Pause, { size: 24 }) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.Play, { size: 24 }),
8392
- onClick: togglePlayPause,
8393
- "aria-label": isPlaying ? "Pause" : "Play",
8394
- className: "!bg-transparent !text-white hover:!bg-white/20"
8395
- }
8396
- ),
8397
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8398
- VolumeControls,
8399
- {
8400
- volume,
8401
- isMuted,
8402
- onVolumeChange: handleVolumeChange,
8403
- onToggleMute: toggleMute
8404
- }
8405
- ),
8406
- subtitles && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8407
- IconButton_default,
8408
- {
8409
- icon: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.ClosedCaptioning, { size: 24 }),
8410
- onClick: toggleCaptions,
8411
- "aria-label": showCaptions ? "Hide captions" : "Show captions",
8412
- className: cn(
8413
- "!bg-transparent hover:!bg-white/20",
8414
- showCaptions ? "!text-primary-400" : "!text-white"
8415
- )
8416
- }
8483
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
8484
+ "div",
8485
+ {
8486
+ className: cn(
8487
+ "flex items-center justify-between",
8488
+ getControlsPadding()
8417
8489
  ),
8418
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(Text_default, { size: "sm", weight: "medium", color: "text-white", children: [
8419
- formatTime(currentTime),
8420
- " / ",
8421
- formatTime(duration)
8422
- ] })
8423
- ] }),
8424
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "flex items-center gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8425
- SpeedMenu,
8426
- {
8427
- showSpeedMenu,
8428
- playbackRate,
8429
- onToggleMenu: toggleSpeedMenu,
8430
- onSpeedChange: handleSpeedChange,
8431
- isFullscreen
8432
- }
8433
- ) })
8434
- ] })
8490
+ children: [
8491
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: cn("flex items-center", getControlsGap()), children: [
8492
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8493
+ IconButton_default,
8494
+ {
8495
+ icon: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.Pause, { size: getIconSize2() }) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.Play, { size: getIconSize2() }),
8496
+ onClick: togglePlayPause,
8497
+ "aria-label": isPlaying ? "Pause" : "Play",
8498
+ className: "!bg-transparent !text-white hover:!bg-white/20"
8499
+ }
8500
+ ),
8501
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8502
+ VolumeControls,
8503
+ {
8504
+ volume,
8505
+ isMuted,
8506
+ onVolumeChange: handleVolumeChange,
8507
+ onToggleMute: toggleMute,
8508
+ iconSize: getIconSize2(),
8509
+ showSlider: !isUltraSmallMobile
8510
+ }
8511
+ ),
8512
+ subtitles && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8513
+ IconButton_default,
8514
+ {
8515
+ icon: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_phosphor_react20.ClosedCaptioning, { size: getIconSize2() }),
8516
+ onClick: toggleCaptions,
8517
+ "aria-label": showCaptions ? "Hide captions" : "Show captions",
8518
+ className: cn(
8519
+ "!bg-transparent hover:!bg-white/20",
8520
+ showCaptions ? "!text-primary-400" : "!text-white"
8521
+ )
8522
+ }
8523
+ ),
8524
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(Text_default, { size: "sm", weight: "medium", color: "text-white", children: [
8525
+ formatTime(currentTime),
8526
+ " / ",
8527
+ formatTime(duration)
8528
+ ] })
8529
+ ] }),
8530
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "flex items-center gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8531
+ SpeedMenu,
8532
+ {
8533
+ showSpeedMenu,
8534
+ playbackRate,
8535
+ onToggleMenu: toggleSpeedMenu,
8536
+ onSpeedChange: handleSpeedChange,
8537
+ iconSize: getIconSize2(),
8538
+ isTinyMobile,
8539
+ isFullscreen
8540
+ }
8541
+ ) })
8542
+ ]
8543
+ }
8544
+ )
8435
8545
  ]
8436
8546
  }
8437
8547
  )