highsoft-ui 1.0.146 → 1.0.147

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 (65) hide show
  1. package/CLAUDE.md +13 -1
  2. package/dist/{Button-DIGyNR41.js → Button-BGsqFCRW.js} +1 -1
  3. package/dist/{ButtonGroup-BSQzx-sZ.js → ButtonGroup-DKfaXOeS.js} +1 -1
  4. package/dist/{Checkbox-wlH6EGWW.js → Checkbox-CniRhVkQ.js} +1 -1
  5. package/dist/{CodeBlock-DtTAC5ru.js → CodeBlock-BeseY88j.js} +5 -5
  6. package/dist/{CookiePolicyModal-CGRXL0wR.js → CookiePolicyModal-k89sCBEJ.js} +2 -2
  7. package/dist/{CopyCode-_MHQorJS.js → CopyCode-_yeXCeeq.js} +3 -3
  8. package/dist/{Dropdown-CVyrHJiC.js → Dropdown-B_Ib6i1c.js} +1 -1
  9. package/dist/{Footer-DW2asf8g.js → Footer-_P2pj3K7.js} +8 -8
  10. package/dist/{FooterBottom-CP0f9kYj.js → FooterBottom-CqpN8Wky.js} +1 -1
  11. package/dist/{FooterHelp-BxDXmtHK.js → FooterHelp-Cb5sraAE.js} +3 -3
  12. package/dist/{FooterLinks-BZwAVSm4.js → FooterLinks-CogdK_5Z.js} +2 -2
  13. package/dist/{Header-DQ1xi25C.js → Header-CVKH_INR.js} +25 -25
  14. package/dist/{InputGrouped-BE3zLov9.js → InputGrouped-CHGCMmsK.js} +11 -11
  15. package/dist/{Label-C_KZM-FN.js → Label-CgiWi1v6.js} +1 -1
  16. package/dist/{NewsletterSignup-CJAI81M3.js → NewsletterSignup-DrcPfdrg.js} +2 -2
  17. package/dist/{Notification-C2kN_ceR.js → Notification-B3skQvZE.js} +3 -3
  18. package/dist/{PrefPanel-BZUX1nfw.js → PrefPanel-BGw72I_D.js} +10 -10
  19. package/dist/{RoadmapDetails-CfayA5CZ.js → RoadmapDetails-XS0OylnP.js} +5 -5
  20. package/dist/{Search-Cw_e1PyF.js → Search-UPVxQliM.js} +12 -12
  21. package/dist/{SearchDropdown-ECOTZ1Uf.js → SearchDropdown-L_rQz1vn.js} +1 -1
  22. package/dist/VideoCover-DqMDvzvA.js +195 -0
  23. package/dist/VideoPlayer-Cq_garSg.js +455 -0
  24. package/dist/{VideoPlayerModal-DbP3OjSF.js → VideoPlayerModal-D1v1O2kW.js} +2 -2
  25. package/dist/{YoutubeModal-D_ZHayEn.js → YoutubeModal-BBYdQil8.js} +4 -2
  26. package/dist/components/Button/index.js +1 -1
  27. package/dist/components/ButtonGroup/index.js +1 -1
  28. package/dist/components/Checkbox/index.js +1 -1
  29. package/dist/components/CodeBlock/index.js +1 -1
  30. package/dist/components/CopyCode/index.js +1 -1
  31. package/dist/components/Dropdown/index.js +1 -1
  32. package/dist/components/Footer/CookiePolicyModal.js +1 -1
  33. package/dist/components/Footer/FooterBottom.js +1 -1
  34. package/dist/components/Footer/FooterHelp.js +1 -1
  35. package/dist/components/Footer/FooterLinks.js +1 -1
  36. package/dist/components/Footer/YoutubeModal.js +1 -1
  37. package/dist/components/Footer/index.js +1 -1
  38. package/dist/components/Header/index.js +1 -1
  39. package/dist/components/InputGrouped/index.js +1 -1
  40. package/dist/components/Label/index.js +1 -1
  41. package/dist/components/Modal/ModalContactFooter.js +2 -2
  42. package/dist/components/Modal/index.js +2 -2
  43. package/dist/components/NewsletterSignup/index.js +1 -1
  44. package/dist/components/Notification/index.js +1 -1
  45. package/dist/components/PrefPanel/index.js +1 -1
  46. package/dist/components/RoadmapDetails/index.js +1 -1
  47. package/dist/components/Search/index.js +1 -1
  48. package/dist/components/SearchDropdown/index.js +1 -1
  49. package/dist/components/Sidebar/Sidebar.js +1 -1
  50. package/dist/components/VideoCover/index.js +1 -1
  51. package/dist/components/VideoPlayer/VideoPlayerModal.js +1 -1
  52. package/dist/components/VideoPlayer/index.js +1 -1
  53. package/dist/components/VideoPlayer/useMediaEngine.js +58 -55
  54. package/dist/{create-element-WbENDceu.js → create-element-CDnUGrhg.js} +1 -1
  55. package/dist/{esm-B0YmMAXt.js → esm-BnxclXHW.js} +121 -51
  56. package/dist/highsoft-ui.css +1 -1
  57. package/dist/lib/components/VideoCover/index.d.ts +39 -5
  58. package/dist/lib/components/VideoPlayer/index.d.ts +33 -1
  59. package/dist/lib/main.d.ts +1 -1
  60. package/dist/main.js +18 -18
  61. package/dist/{prism-light-C4xXs3Qn.js → prism-light-COlcVrfu.js} +1 -1
  62. package/dist/scss/variables.scss +4 -0
  63. package/package.json +1 -1
  64. package/dist/VideoCover-BN8wnHpf.js +0 -92
  65. package/dist/VideoPlayer-CKjq7IRq.js +0 -324
@@ -19,7 +19,12 @@ export interface VideoCoverProps {
19
19
  fit?: 'cover' | 'contain' | 'fill';
20
20
  /** Autoplay on mount. Default `true`. */
21
21
  autoPlay?: boolean;
22
- /** Loop when the video ends. Default `true`. */
22
+ /**
23
+ * Loop when the video ends. Default `false` — covers play through once and
24
+ * settle on their final frame (with the control offering replay), keeping
25
+ * automatic motion under WCAG 2.2.2's five-second threshold. Opt in to
26
+ * looping only for genuinely ambient video.
27
+ */
23
28
  loop?: boolean;
24
29
  /** Start muted — required for autoplay. Default `true`. */
25
30
  muted?: boolean;
@@ -53,6 +58,33 @@ export interface VideoCoverProps {
53
58
  aspectRatio?: string;
54
59
  /** Corner radius in px. Default `0`. */
55
60
  radius?: number;
61
+ /**
62
+ * Show a small always-visible playback toggle in the corner (WCAG 2.2.2
63
+ * "Pause, Stop, Hide"). Three states: pause while the video plays, replay
64
+ * once it has ended (`loop={false}`), and play when it isn't running —
65
+ * e.g. for reduced-motion users, who can still opt in to playback.
66
+ * Default `true`. Disable it only for videos that don't loop and finish
67
+ * within ~5 seconds (where WCAG doesn't require a control), or when the
68
+ * cover itself is wrapped in an interactive trigger — a nested button is
69
+ * invalid HTML (see the Footer's video tile).
70
+ */
71
+ playControl?: boolean;
72
+ /**
73
+ * Only play while the cover is actually in the viewport: autoplay waits
74
+ * until ~20% of it is visible, scrolling away pauses, scrolling back
75
+ * resumes. A pause from the toggle is sticky — re-entering the viewport
76
+ * never overrides it — and an ended `loop={false}` video stays on its end
77
+ * frame instead of replaying on re-entry. Default `true`. Set `false` to
78
+ * start playback as soon as the video loads, visible or not.
79
+ */
80
+ playWhenVisible?: boolean;
81
+ /**
82
+ * Short informational text rendered below the cover — a small annotation
83
+ * icon plus tertiary caption. The component wraps itself in a `<figure>` with
84
+ * the caption as its `<figcaption>`; `className`/`style`/`ref` stay on the
85
+ * cover box itself.
86
+ */
87
+ caption?: ReactNode;
56
88
  /**
57
89
  * Overlay content rendered on top of the video (icons, captions, a play
58
90
  * badge, …). Interactive by default; pointer events pass through the video.
@@ -67,9 +99,11 @@ export interface VideoCoverProps {
67
99
  style?: CSSProperties;
68
100
  }
69
101
  /**
70
- * A chrome-less background/cover video — autoplays muted, loops, and stretches
71
- * to fill its box like `object-fit: cover` on an image. No controls, no
72
- * playback engine, no provider SDKs; just a self-hosted `<video>` with built-in
73
- * lazy loading and an optional overlay for arbitrary `children`.
102
+ * A chrome-less background/cover video — autoplays muted once it scrolls into
103
+ * view, plays through a single time, and stretches to fill its box like
104
+ * `object-fit: cover` on an image. No playback engine and no provider SDKs;
105
+ * just a self-hosted `<video>` with built-in lazy loading, an always-visible
106
+ * pause/play/replay toggle (see `playControl`), and an optional overlay for
107
+ * arbitrary `children`.
74
108
  */
75
109
  export declare const VideoCover: import('react').ForwardRefExoticComponent<VideoCoverProps & import('react').RefAttributes<HTMLVideoElement>>;
@@ -1,10 +1,26 @@
1
- import { CSSProperties } from 'react';
1
+ import { CSSProperties, ReactNode } from 'react';
2
2
  /** A single `<source>` entry for the underlying `<video>`. */
3
3
  export interface VideoPlayerSource {
4
4
  src: string;
5
5
  /** MIME type, e.g. `video/mp4`. */
6
6
  type?: string;
7
7
  }
8
+ /** A WebVTT text track for the underlying `<video>` (self-hosted only). */
9
+ export interface VideoPlayerTrack {
10
+ /** URL of the `.vtt` file. */
11
+ src: string;
12
+ /** Language of the track, e.g. `en`. */
13
+ srclang: string;
14
+ /** Human-readable label shown for the track, e.g. `English`. */
15
+ label: string;
16
+ /**
17
+ * Track kind. `captions` (default) and `subtitles` are cycled by the CC
18
+ * button; `descriptions` tracks are exposed to assistive tech only.
19
+ */
20
+ kind?: 'captions' | 'subtitles' | 'descriptions';
21
+ /** Show this track when the player mounts. */
22
+ default?: boolean;
23
+ }
8
24
  export interface VideoPlayerProps {
9
25
  /**
10
26
  * Video URL. A YouTube or Vimeo link is auto-detected and driven through the
@@ -35,6 +51,22 @@ export interface VideoPlayerProps {
35
51
  * color; accepts any CSS color or `<image>` value (e.g. a `linear-gradient`).
36
52
  */
37
53
  accentGradient?: string;
54
+ /**
55
+ * WebVTT text tracks (captions/subtitles/descriptions) for self-hosted
56
+ * video. Adds a CC toggle to the control bar that cycles the available
57
+ * caption/subtitle tracks (also on the `c` key). Ignored for YouTube/Vimeo
58
+ * sources — provider embeds carry their own caption rendering.
59
+ */
60
+ tracks?: VideoPlayerTrack[];
61
+ /**
62
+ * Written transcript, docked as a panel directly below the player and
63
+ * toggled from a control-bar button (also on the `t` key) — the
64
+ * WCAG-friendly companion to captions for users who prefer reading,
65
+ * search, or assistive tech. Any React content.
66
+ */
67
+ transcript?: ReactNode;
68
+ /** Accessible name for the transcript panel. Default `Transcript`. */
69
+ transcriptTitle?: string;
38
70
  /** Accessible label for the player region. */
39
71
  'aria-label'?: string;
40
72
  className?: string;
@@ -59,7 +59,7 @@ export { SidebarLayout, SidebarMain, Sidebar, SidebarHeader, SidebarBody, Sideba
59
59
  export type { SidebarLayoutProps, SidebarProps, SidebarSectionProps, NavItemProps, NavGroupProps, NavDisclosureProps, SidebarLayoutContextValue } from './components/Sidebar';
60
60
  export { PrefPanel } from './components/PrefPanel';
61
61
  export { VideoPlayer } from './components/VideoPlayer';
62
- export type { VideoPlayerProps, VideoPlayerSource } from './components/VideoPlayer';
62
+ export type { VideoPlayerProps, VideoPlayerSource, VideoPlayerTrack } from './components/VideoPlayer';
63
63
  export { VideoPlayerModal } from './components/VideoPlayer/VideoPlayerModal';
64
64
  export type { VideoPlayerModalProps } from './components/VideoPlayer/VideoPlayerModal';
65
65
  export { VideoCover } from './components/VideoCover';
package/dist/main.js CHANGED
@@ -1,37 +1,37 @@
1
1
  import { c as e, d as t, r as n, s as r, u as i } from "./utils-K9S_6_Eq.js";
2
2
  import { t as a } from "./Box-BZgeSeCV.js";
3
- import { t as o } from "./Button-DIGyNR41.js";
4
- import { t as s } from "./CopyCode-_MHQorJS.js";
3
+ import { t as o } from "./Button-BGsqFCRW.js";
4
+ import { t as s } from "./CopyCode-_yeXCeeq.js";
5
5
  import { t as c } from "./FrameworkIcon-Ds6WrxO0.js";
6
- import { t as l } from "./CodeBlock-DtTAC5ru.js";
6
+ import { t as l } from "./CodeBlock-BeseY88j.js";
7
7
  import { t as u } from "./Icon-VeXJMj8Q.js";
8
8
  import { t as d } from "./Link-CYR92_U0.js";
9
9
  import { t as f } from "./ProductIcon-DFLAYWbu.js";
10
- import { t as p } from "./ButtonGroup-BSQzx-sZ.js";
10
+ import { t as p } from "./ButtonGroup-DKfaXOeS.js";
11
11
  import { t as m } from "./InputSolo-DUdKtZjX.js";
12
- import { t as h } from "./SearchDropdown-ECOTZ1Uf.js";
13
- import { i as g, n as _, r as v, t as y } from "./InputGrouped-BE3zLov9.js";
12
+ import { t as h } from "./SearchDropdown-L_rQz1vn.js";
13
+ import { i as g, n as _, r as v, t as y } from "./InputGrouped-CHGCMmsK.js";
14
14
  import { t as b } from "./Container-BDssaLig.js";
15
15
  import { t as x } from "./DiscordInvite-CLYxexdH.js";
16
16
  import { t as S } from "./Heading-DNDHqYWO.js";
17
17
  import { t as C } from "./Typography-AvvBRu-u.js";
18
18
  import { t as w } from "./Logo-Bz0G2G-k.js";
19
- import { t as T } from "./NewsletterSignup-CJAI81M3.js";
20
- import { n as E, r as D, t as O } from "./Dropdown-CVyrHJiC.js";
21
- import { t as k } from "./PrefPanel-BZUX1nfw.js";
22
- import { n as A, t as j } from "./Label-C_KZM-FN.js";
23
- import { t as M } from "./VideoCover-BN8wnHpf.js";
24
- import { t as N } from "./VideoPlayer-CKjq7IRq.js";
25
- import { t as P } from "./VideoPlayerModal-DbP3OjSF.js";
26
- import { t as F } from "./Footer-DW2asf8g.js";
19
+ import { t as T } from "./NewsletterSignup-DrcPfdrg.js";
20
+ import { n as E, r as D, t as O } from "./Dropdown-B_Ib6i1c.js";
21
+ import { t as k } from "./PrefPanel-BGw72I_D.js";
22
+ import { n as A, t as j } from "./Label-CgiWi1v6.js";
23
+ import { t as M } from "./VideoCover-DqMDvzvA.js";
24
+ import { t as N } from "./VideoPlayer-Cq_garSg.js";
25
+ import { t as P } from "./VideoPlayerModal-D1v1O2kW.js";
26
+ import { t as F } from "./Footer-_P2pj3K7.js";
27
27
  import { n as I } from "./GPTInput-C0YG1990.js";
28
- import { t as L } from "./Notification-C2kN_ceR.js";
29
- import { n as R, t as z } from "./Header-DQ1xi25C.js";
28
+ import { t as L } from "./Notification-B3skQvZE.js";
29
+ import { n as R, t as z } from "./Header-CVKH_INR.js";
30
30
  import { t as B } from "./Tabs-BuDaPqdN.js";
31
31
  import { n as V, t as H } from "./RadioBox-o1Ssyj0s.js";
32
- import { n as U, t as W } from "./Checkbox-wlH6EGWW.js";
32
+ import { n as U, t as W } from "./Checkbox-CniRhVkQ.js";
33
33
  import { Modal as G } from "./components/Modal/index.js";
34
- import { t as K } from "./RoadmapDetails-CfayA5CZ.js";
34
+ import { t as K } from "./RoadmapDetails-XS0OylnP.js";
35
35
  import { ModalContactFooter as q } from "./components/Modal/ModalContactFooter.js";
36
36
  import { useOptionalSidebarLayout as J, useSidebarLayout as Y } from "./components/Sidebar/context.js";
37
37
  import { SidebarLayout as X, SidebarMain as Z } from "./components/Sidebar/SidebarLayout.js";
@@ -1,5 +1,5 @@
1
1
  import { r as e } from "./chunk-jwUa06l-.js";
2
- import { r as t, t as n } from "./create-element-WbENDceu.js";
2
+ import { r as t, t as n } from "./create-element-CDnUGrhg.js";
3
3
  import r from "react";
4
4
  //#region node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js
5
5
  function i(e, t) {
@@ -772,6 +772,8 @@ $body-1000: var(--typography-size-1000);
772
772
  --HS-text-attention-default-alt: var(--primitives-attention-1000);
773
773
  --HS-text-danger-default: var(--primitives-danger-500);
774
774
  --HS-common-background: var(--primitives-neutral-50);
775
+ --HS-video-player-chrome: var(--primitives-neutral-0);
776
+ --HS-video-player-scrim: var(--primitives-neutral-1000);
775
777
  --HS-surface-danger-background: var(--primitives-danger-50);
776
778
  --HS-surface-danger-background-boxed: var(--primitives-danger-100);
777
779
  --HS-surface-danger-border: var(--primitives-danger-200);
@@ -893,6 +895,8 @@ $body-1000: var(--typography-size-1000);
893
895
  --HS-text-attention-default-alt: var(--primitives-neutral-0);
894
896
  --HS-text-danger-default: var(--primitives-danger-500);
895
897
  --HS-common-background: var(--primitives-neutral-950);
898
+ --HS-video-player-chrome: var(--primitives-neutral-0);
899
+ --HS-video-player-scrim: var(--primitives-neutral-1000);
896
900
  --HS-surface-danger-background: var(--primitives-danger-1200);
897
901
  --HS-surface-danger-background-boxed: var(--primitives-danger-1100);
898
902
  --HS-surface-danger-border: var(--primitives-danger-700);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "highsoft-ui",
3
- "version": "1.0.146",
3
+ "version": "1.0.147",
4
4
  "description": "Highsoft UI",
5
5
  "type": "module",
6
6
  "repository": {
@@ -1,92 +0,0 @@
1
- import { t as e } from "./clsx-BWCAbrjV.js";
2
- import { forwardRef as t, useCallback as n, useEffect as r, useRef as i, useState as a } from "react";
3
- import { jsx as o, jsxs as s } from "react/jsx-runtime";
4
- var c = {
5
- content: "a1m2bq_content",
6
- cover: "a1m2bq_cover",
7
- hoverZoom: "a1m2bq_hoverZoom",
8
- poster: "a1m2bq_poster",
9
- reduced: "a1m2bq_reduced",
10
- video: "a1m2bq_video"
11
- }, l = t(({ src: t, sources: l, poster: u, fit: d = "cover", autoPlay: f = !0, loop: p = !0, muted: m = !0, playsInline: h = !0, preload: g = "auto", lazy: _ = !0, hoverZoom: v = !1, reducedMotion: y, aspectRatio: b, radius: x = 0, children: S, "aria-label": C, className: w, style: T }, E) => {
12
- let D = i(null), O = i(null), [k, A] = a(!_), [j, M] = a(!1), N = !C, P = n((e) => {
13
- O.current = e, typeof E == "function" ? E(e) : E && (E.current = e);
14
- }, [E]), [F, I] = a(() => typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches);
15
- r(() => {
16
- if (typeof window > "u" || !window.matchMedia) return;
17
- let e = window.matchMedia("(prefers-reduced-motion: reduce)"), t = () => I(e.matches);
18
- return t(), e.addEventListener("change", t), () => e.removeEventListener("change", t);
19
- }, []);
20
- let L = y === void 0 ? F ? "no-animation" : !1 : y === !0 ? "no-animation" : y, R = L !== !1, z = f && !R, B = n(() => {
21
- let e = O.current;
22
- e && (e.pause(), L === "skip-to-end" && Number.isFinite(e.duration) ? e.currentTime = Math.max(0, e.duration - .05) : L === "no-animation" && (e.currentTime = 0));
23
- }, [L]);
24
- return r(() => {
25
- let e = O.current;
26
- !e || !k || (R ? B() : f && e.play().catch(() => {}));
27
- }, [
28
- R,
29
- k,
30
- f,
31
- B
32
- ]), r(() => {
33
- if (k) return;
34
- let e = D.current;
35
- if (!e || typeof IntersectionObserver > "u") {
36
- A(!0);
37
- return;
38
- }
39
- let t = new IntersectionObserver(([e]) => {
40
- e?.isIntersecting && (A(!0), t.disconnect());
41
- }, { rootMargin: "200px" });
42
- return t.observe(e), () => t.disconnect();
43
- }, [k]), /* @__PURE__ */ s("div", {
44
- ref: D,
45
- className: e("hsui-video-cover", c.cover, {
46
- [c.hoverZoom]: v,
47
- [c.reduced]: R
48
- }, w),
49
- style: {
50
- "--vc-radius": `${x}px`,
51
- aspectRatio: b,
52
- ...T
53
- },
54
- role: N ? "presentation" : "img",
55
- "aria-label": C,
56
- children: [
57
- u && /* @__PURE__ */ o("img", {
58
- className: c.poster,
59
- style: { objectFit: d },
60
- src: u,
61
- alt: "",
62
- "aria-hidden": "true"
63
- }),
64
- /* @__PURE__ */ o("video", {
65
- ref: P,
66
- className: c.video,
67
- style: { objectFit: d },
68
- src: k && !l ? t : void 0,
69
- autoPlay: z,
70
- loop: p,
71
- muted: m,
72
- playsInline: h,
73
- preload: k ? g : "none",
74
- "data-ready": j || void 0,
75
- onCanPlay: () => M(!0),
76
- onLoadedMetadata: R ? B : void 0,
77
- "aria-hidden": N || void 0,
78
- children: k && l?.map((e) => /* @__PURE__ */ o("source", {
79
- src: e.src,
80
- type: e.type
81
- }, e.src))
82
- }),
83
- S != null && /* @__PURE__ */ o("div", {
84
- className: c.content,
85
- children: S
86
- })
87
- ]
88
- });
89
- });
90
- l.displayName = "VideoCover";
91
- //#endregion
92
- export { l as t };
@@ -1,324 +0,0 @@
1
- import { t as e } from "./clsx-BWCAbrjV.js";
2
- import { C as t, E as n, a as r, i, r as a } from "./esm-B0YmMAXt.js";
3
- import { t as o } from "./Icon-VeXJMj8Q.js";
4
- import { detectProvider as s, providerPosterUrl as c, useMediaEngine as l } from "./components/VideoPlayer/useMediaEngine.js";
5
- import { forwardRef as u, useCallback as d, useEffect as f, useId as p, useImperativeHandle as m, useRef as h, useState as g } from "react";
6
- import { jsx as _, jsxs as v } from "react/jsx-runtime";
7
- var y = {
8
- button: "_1OFWhq_button",
9
- centerPlay: "_1OFWhq_centerPlay",
10
- controlBar: "_1OFWhq_controlBar",
11
- dragging: "_1OFWhq_dragging",
12
- embed: "_1OFWhq_embed",
13
- idle: "_1OFWhq_idle",
14
- player: "_1OFWhq_player",
15
- progress: "_1OFWhq_progress",
16
- scrim: "_1OFWhq_scrim",
17
- slider: "_1OFWhq_slider",
18
- sliderBuffered: "_1OFWhq_sliderBuffered",
19
- sliderFill: "_1OFWhq_sliderFill",
20
- sliderThumb: "_1OFWhq_sliderThumb",
21
- sliderTrack: "_1OFWhq_sliderTrack",
22
- startCover: "_1OFWhq_startCover",
23
- tapLayer: "_1OFWhq_tapLayer",
24
- time: "_1OFWhq_time",
25
- timeDuration: "_1OFWhq_timeDuration",
26
- video: "_1OFWhq_video",
27
- volumePopover: "_1OFWhq_volumePopover",
28
- volumeSlider: "_1OFWhq_volumeSlider",
29
- volumeWrap: "_1OFWhq_volumeWrap"
30
- }, b = "var(--HS-text-brand-default-alt)", x = 2600;
31
- function S(e) {
32
- if (!Number.isFinite(e) || e < 0) return "0:00";
33
- let t = Math.floor(e), n = Math.floor(t / 3600), r = Math.floor(t % 3600 / 60), i = t % 60, a = n > 0 ? String(r).padStart(2, "0") : String(r), o = String(i).padStart(2, "0");
34
- return n > 0 ? `${n}:${a}:${o}` : `${a}:${o}`;
35
- }
36
- var C = (e) => Math.max(0, Math.min(1, e));
37
- function w({ value: t, buffered: n, ariaLabel: r, ariaValueText: i, className: a, step: o = .05, onChange: s, onScrubStart: c, onScrubEnd: l }) {
38
- let u = h(null), [f, p] = g(!1), m = (e) => `${C(e) * 100}%`, b = d((e) => {
39
- let t = u.current;
40
- if (!t) return 0;
41
- let n = t.getBoundingClientRect();
42
- return C((e - n.left) / n.width);
43
- }, []), x = (e) => {
44
- e.preventDefault(), u.current?.setPointerCapture(e.pointerId), p(!0), c?.(), s(b(e.clientX));
45
- }, S = (e) => {
46
- f && s(b(e.clientX));
47
- }, w = (e) => {
48
- f && (p(!1), l?.(), u.current?.releasePointerCapture?.(e.pointerId));
49
- }, T = (e) => {
50
- let n = null;
51
- switch (e.key) {
52
- case "ArrowRight":
53
- case "ArrowUp":
54
- n = t + o;
55
- break;
56
- case "ArrowLeft":
57
- case "ArrowDown":
58
- n = t - o;
59
- break;
60
- case "Home":
61
- n = 0;
62
- break;
63
- case "End":
64
- n = 1;
65
- break;
66
- default: return;
67
- }
68
- e.preventDefault(), e.stopPropagation(), s(C(n));
69
- };
70
- return /* @__PURE__ */ v("div", {
71
- ref: u,
72
- role: "slider",
73
- tabIndex: 0,
74
- "aria-label": r,
75
- "aria-valuemin": 0,
76
- "aria-valuemax": 100,
77
- "aria-valuenow": Math.round(C(t) * 100),
78
- "aria-valuetext": i,
79
- className: e(y.slider, a, { [y.dragging]: f }),
80
- onPointerDown: x,
81
- onPointerMove: S,
82
- onPointerUp: w,
83
- onPointerCancel: w,
84
- onKeyDown: T,
85
- children: [/* @__PURE__ */ v("div", {
86
- className: y.sliderTrack,
87
- children: [n != null && /* @__PURE__ */ _("div", {
88
- className: y.sliderBuffered,
89
- style: { width: m(n) }
90
- }), /* @__PURE__ */ _("div", {
91
- className: y.sliderFill,
92
- style: { width: m(t) }
93
- })]
94
- }), /* @__PURE__ */ _("span", {
95
- className: y.sliderThumb,
96
- style: { left: m(t) }
97
- })]
98
- });
99
- }
100
- var T = () => /* @__PURE__ */ _("svg", {
101
- viewBox: "0 0 24 24",
102
- "aria-hidden": "true",
103
- focusable: "false",
104
- children: /* @__PURE__ */ _("path", { d: "M8 5.14v13.72c0 .86.94 1.39 1.68.95l11.02-6.86a1.12 1.12 0 0 0 0-1.9L9.68 4.19A1.12 1.12 0 0 0 8 5.14Z" })
105
- }), ee = () => /* @__PURE__ */ v("svg", {
106
- viewBox: "0 0 24 24",
107
- "aria-hidden": "true",
108
- focusable: "false",
109
- children: [/* @__PURE__ */ _("rect", {
110
- x: "6",
111
- y: "5",
112
- width: "4",
113
- height: "14",
114
- rx: "1.6"
115
- }), /* @__PURE__ */ _("rect", {
116
- x: "14",
117
- y: "5",
118
- width: "4",
119
- height: "14",
120
- rx: "1.6"
121
- })]
122
- }), E = u(({ src: u, sources: E, poster: D, muted: O = !1, autoPlay: k = !1, loop: A = !1, playsInline: j = !0, preload: te = "metadata", aspectRatio: ne = "16 / 9", radius: re = 16, accentGradient: ie = b, "aria-label": M = "Video player", className: N, style: P }, F) => {
123
- let I = s(u, !!E?.length), L = I !== "file", R = l({
124
- provider: I,
125
- src: u,
126
- muted: O,
127
- autoPlay: k,
128
- loop: A
129
- }), { state: z } = R, B = h(null), V = h(null), H = h(void 0), U = p(), W = d((e) => {
130
- V.current = e, R.videoRef(e);
131
- }, [R]);
132
- m(F, () => V.current, []);
133
- let [G, K] = g(!1), [q, J] = g(!1), [ae, Y] = g(!1), [oe, se] = g(!1), [ce, X] = g(void 0);
134
- f(() => {
135
- z.playing && se(!0);
136
- }, [z.playing]), f(() => {
137
- if (X(void 0), I !== "vimeo" || D || !u) return;
138
- let e = !1;
139
- return fetch(`https://vimeo.com/api/oembed.json?url=${encodeURIComponent(u)}&width=1280`).then((e) => e.ok ? e.json() : null).then((t) => {
140
- !e && t?.thumbnail_url && X(t.thumbnail_url);
141
- }).catch(() => {}), () => {
142
- e = !0;
143
- };
144
- }, [
145
- I,
146
- D,
147
- u
148
- ]), f(() => {
149
- let e = () => K(document.fullscreenElement === B.current);
150
- return document.addEventListener("fullscreenchange", e), () => document.removeEventListener("fullscreenchange", e);
151
- }, []);
152
- let Z = d(() => {
153
- J(!1), window.clearTimeout(H.current), H.current = window.setTimeout(() => J(!0), x);
154
- }, []);
155
- f(() => () => window.clearTimeout(H.current), []);
156
- let Q = d(() => {
157
- let e = B.current;
158
- e && (document.fullscreenElement === e ? document.exitFullscreen().catch(() => {}) : e.requestFullscreen?.().catch(() => {}));
159
- }, []), le = (e) => {
160
- if (e.target.getAttribute("role") !== "slider") switch (e.key) {
161
- case " ":
162
- case "k":
163
- e.preventDefault(), R.toggle();
164
- break;
165
- case "f":
166
- e.preventDefault(), Q();
167
- break;
168
- case "m":
169
- e.preventDefault(), R.toggleMute();
170
- break;
171
- case "ArrowRight":
172
- e.preventDefault(), R.seekBy(5);
173
- break;
174
- case "ArrowLeft":
175
- e.preventDefault(), R.seekBy(-5);
176
- break;
177
- default:
178
- }
179
- }, $ = D ?? c(I, u) ?? ce, ue = z.duration ? C(z.currentTime / z.duration) : 0, de = z.muted || z.volume === 0 ? a : z.volume < .5 ? i : r, fe = {
180
- "--vp-radius": `${re}px`,
181
- "--vp-gradient": ie,
182
- aspectRatio: G ? void 0 : ne
183
- }, pe = I === "file" ? /* @__PURE__ */ _("video", {
184
- ref: W,
185
- className: y.video,
186
- src: E ? void 0 : u,
187
- poster: D,
188
- muted: O,
189
- autoPlay: k,
190
- loop: A,
191
- playsInline: j,
192
- preload: te,
193
- onClick: R.toggle,
194
- children: E?.map((e) => /* @__PURE__ */ _("source", {
195
- src: e.src,
196
- type: e.type
197
- }, e.src))
198
- }) : /* @__PURE__ */ _("div", {
199
- ref: R.mountRef,
200
- className: y.embed
201
- });
202
- return /* @__PURE__ */ v("div", {
203
- ref: B,
204
- role: "region",
205
- "aria-label": M,
206
- "aria-labelledby": U,
207
- tabIndex: 0,
208
- className: e("hsui-video-player", y.player, {
209
- [y.playing]: z.playing,
210
- [y.ended]: z.ended,
211
- [y.idle]: q && z.playing && !ae
212
- }, N),
213
- style: {
214
- ...fe,
215
- ...P
216
- },
217
- onPointerMove: Z,
218
- onPointerLeave: () => z.playing && J(!0),
219
- onKeyDown: le,
220
- onDoubleClick: Q,
221
- children: [
222
- /* @__PURE__ */ _("span", {
223
- id: U,
224
- className: "sr-only",
225
- children: M
226
- }),
227
- pe,
228
- L && !oe && /* @__PURE__ */ _("div", {
229
- className: y.startCover,
230
- "aria-hidden": "true",
231
- style: $ ? { backgroundImage: `url("${$}")` } : void 0
232
- }),
233
- L && /* @__PURE__ */ _("button", {
234
- type: "button",
235
- className: y.tapLayer,
236
- onClick: R.toggle,
237
- "aria-label": z.playing ? "Pause" : "Play",
238
- tabIndex: -1
239
- }),
240
- /* @__PURE__ */ _("div", {
241
- className: y.scrim,
242
- "aria-hidden": "true"
243
- }),
244
- !z.playing && /* @__PURE__ */ _("button", {
245
- type: "button",
246
- className: y.centerPlay,
247
- onClick: R.toggle,
248
- "aria-label": z.ended ? "Replay" : "Play",
249
- tabIndex: -1,
250
- children: /* @__PURE__ */ _(T, {})
251
- }),
252
- /* @__PURE__ */ v("div", {
253
- className: y.controlBar,
254
- children: [
255
- /* @__PURE__ */ _("button", {
256
- type: "button",
257
- className: y.button,
258
- onClick: R.toggle,
259
- "aria-label": z.playing ? "Pause" : "Play",
260
- children: z.playing ? /* @__PURE__ */ _(ee, {}) : /* @__PURE__ */ _(T, {})
261
- }),
262
- /* @__PURE__ */ v("div", {
263
- className: y.volumeWrap,
264
- children: [/* @__PURE__ */ _("button", {
265
- type: "button",
266
- className: y.button,
267
- onClick: R.toggleMute,
268
- "aria-label": z.muted ? "Unmute" : "Mute",
269
- "aria-pressed": z.muted,
270
- children: /* @__PURE__ */ _(o, {
271
- name: de,
272
- size: 20
273
- })
274
- }), /* @__PURE__ */ _("div", {
275
- className: y.volumePopover,
276
- children: /* @__PURE__ */ _(w, {
277
- className: y.volumeSlider,
278
- value: z.volume,
279
- ariaLabel: "Volume",
280
- ariaValueText: `${Math.round(z.volume * 100)}%`,
281
- onChange: R.setVolume
282
- })
283
- })]
284
- }),
285
- /* @__PURE__ */ _("span", {
286
- className: y.time,
287
- children: S(z.currentTime)
288
- }),
289
- /* @__PURE__ */ _(w, {
290
- className: y.progress,
291
- value: ue,
292
- buffered: z.buffered,
293
- ariaLabel: "Seek",
294
- ariaValueText: `${S(z.currentTime)} of ${S(z.duration)}`,
295
- onChange: R.seekFraction,
296
- onScrubStart: () => {
297
- Y(!0), R.beginSeek();
298
- },
299
- onScrubEnd: () => {
300
- Y(!1), R.endSeek();
301
- }
302
- }),
303
- /* @__PURE__ */ _("span", {
304
- className: e(y.time, y.timeDuration),
305
- children: S(z.duration)
306
- }),
307
- /* @__PURE__ */ _("button", {
308
- type: "button",
309
- className: y.button,
310
- onClick: Q,
311
- "aria-label": G ? "Exit fullscreen" : "Enter fullscreen",
312
- children: /* @__PURE__ */ _(o, {
313
- name: G ? t : n,
314
- size: 20
315
- })
316
- })
317
- ]
318
- })
319
- ]
320
- });
321
- });
322
- E.displayName = "VideoPlayer";
323
- //#endregion
324
- export { E as t };