@drawbridge/components 0.1.5 → 0.1.7

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/video.mjs CHANGED
@@ -4,8 +4,13 @@ import dynamic from "next/dynamic";
4
4
  import { Fragment, useEffect, useRef, useState } from "react";
5
5
  import Loader from "./icons/loader.mjs";
6
6
  import Warning from "./icons/warning.mjs";
7
+ import { provideHls, startSeek, videoErrorAction, videoOverlay } from "./shared/lib/video.mjs";
7
8
  const ReactPlayer = dynamic(
8
- () => import("react-player/lazy"),
9
+ () => Promise.all([
10
+ import("hls.js").then((module) => provideHls(module.default || module, window)).catch(() => {
11
+ }),
12
+ import("react-player/lazy")
13
+ ]).then(([, player]) => player),
9
14
  {
10
15
  ssr: false
11
16
  }
@@ -35,17 +40,22 @@ const Video = ({
35
40
  }) => {
36
41
  var _a, _b, _c, _d;
37
42
  const durationFired = useRef(false);
43
+ const errored = useRef(false);
38
44
  const [player, setPlayer] = useState();
39
45
  const [videoUrl, setVideoUrl] = useState(hls ? hls : mp4);
40
46
  const [mountPlayer, setMountPlayer] = useState(!defer);
41
47
  const [posterPainted, setPosterPainted] = useState(false);
42
48
  const [videoPaintable, setVideoPaintable] = useState(false);
43
49
  const [failed, setFailed] = useState(false);
50
+ const wasReset = useRef(reset);
44
51
  useEffect(
45
52
  () => {
46
- if (player && reset) {
47
- player.seekTo(0, "seconds");
53
+ if (!player) return;
54
+ const target = startSeek({ reset, wasReset: wasReset.current });
55
+ if (target !== null) {
56
+ player.seekTo(target, "seconds");
48
57
  }
58
+ wasReset.current = reset;
49
59
  },
50
60
  [player, reset]
51
61
  );
@@ -77,6 +87,11 @@ const Video = ({
77
87
  },
78
88
  [defer, mountPlayer, poster, posterPainted]
79
89
  );
90
+ const overlay = videoOverlay({
91
+ failed,
92
+ poster,
93
+ videoPaintable
94
+ });
80
95
  const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
81
96
  mountPlayer && /* @__PURE__ */ jsx(
82
97
  ReactPlayer,
@@ -122,11 +137,19 @@ const Video = ({
122
137
  onTime == null ? void 0 : onTime(seconds);
123
138
  },
124
139
  progressInterval: 100,
125
- onError: () => {
126
- if (mp4 && videoUrl !== mp4) {
140
+ onError: (error, data) => {
141
+ const action = videoErrorAction({
142
+ data,
143
+ error,
144
+ mp4,
145
+ url: videoUrl
146
+ });
147
+ if (action === "ignore" || errored.current) return;
148
+ if (action === "retry") {
127
149
  setVideoUrl(mp4);
128
150
  return;
129
151
  }
152
+ errored.current = true;
130
153
  setFailed(true);
131
154
  onError();
132
155
  },
@@ -151,7 +174,7 @@ const Video = ({
151
174
  }
152
175
  }
153
176
  ),
154
- !videoPaintable && poster && /* @__PURE__ */ jsx(
177
+ overlay === "poster" && /* @__PURE__ */ jsx(
155
178
  "img",
156
179
  {
157
180
  ...{
@@ -172,7 +195,7 @@ const Video = ({
172
195
  }
173
196
  }
174
197
  ),
175
- !videoPaintable && !poster && !failed && /* @__PURE__ */ jsx(
198
+ overlay === "loader" && /* @__PURE__ */ jsx(
176
199
  "div",
177
200
  {
178
201
  ...{
@@ -195,7 +218,7 @@ const Video = ({
195
218
  )
196
219
  }
197
220
  ),
198
- failed && !poster && /* @__PURE__ */ jsx(
221
+ overlay === "warning" && /* @__PURE__ */ jsx(
199
222
  "div",
200
223
  {
201
224
  ...{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drawbridge/components",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "exports": {
5
5
  "./advertisement": {
6
6
  "types": "./types/advertisement.d.ts",
@@ -1437,6 +1437,11 @@
1437
1437
  "import": "./dist/shared/lib/icon-labels.mjs",
1438
1438
  "default": "./dist/shared/lib/icon-labels.js"
1439
1439
  },
1440
+ "./shared/lib/video": {
1441
+ "types": "./types/shared/lib/video.d.ts",
1442
+ "import": "./dist/shared/lib/video.mjs",
1443
+ "default": "./dist/shared/lib/video.js"
1444
+ },
1440
1445
  "./shared/lib/yup": {
1441
1446
  "types": "./types/shared/lib/yup.d.ts",
1442
1447
  "import": "./dist/shared/lib/yup.mjs",
@@ -1510,15 +1515,15 @@
1510
1515
  "exports": "node scripts/exports.js",
1511
1516
  "test": ". \"$HOME/.nvm/nvm.sh\" && nvm use && node --test",
1512
1517
  "build": ". \"$HOME/.nvm/nvm.sh\" && nvm use && tsup && node scripts/esm-extensions.js && node --test && npm publish",
1513
- "storybook": "storybook dev -p 6006",
1514
- "storybook:build": "storybook build",
1515
- "test-storybook": "vitest --project=storybook",
1518
+ "app": "storybook dev -p 3003",
1519
+ "app:build": "storybook build",
1520
+ "test:app": "vitest --project=storybook",
1516
1521
  "dev": "tsup --watch --onSuccess \"node scripts/esm-extensions.js\""
1517
1522
  },
1518
1523
  "peerDependencies": {
1519
1524
  "@analytics/google-tag-manager": ">=0.5.5",
1520
1525
  "@drawbridge/drawbridge-telemetry": ">=0.0.19",
1521
- "@drawbridge/drawbridge-utils": ">=0.0.221",
1526
+ "@drawbridge/drawbridge-utils": ">=0.0.222",
1522
1527
  "@headlessui/react": ">=2.1.2",
1523
1528
  "@hookform/resolvers": ">=3.1.1",
1524
1529
  "@sentry/nextjs": ">=10.58.0",
@@ -1636,9 +1641,9 @@
1636
1641
  },
1637
1642
  "devDependencies": {
1638
1643
  "@analytics/google-tag-manager": "0.5.5",
1639
- "@drawbridge/drawbridge-agents": "0.1.79",
1644
+ "@drawbridge/drawbridge-agents": "0.1.90",
1640
1645
  "@drawbridge/drawbridge-telemetry": "0.0.19",
1641
- "@drawbridge/drawbridge-utils": "0.0.221",
1646
+ "@drawbridge/drawbridge-utils": "0.0.222",
1642
1647
  "@headlessui/react": "2.2.9",
1643
1648
  "@hookform/resolvers": "3.1.1",
1644
1649
  "@sentry/nextjs": "10.58.0",
@@ -1694,6 +1699,7 @@
1694
1699
  "@dnd-kit/utilities": "3.2.2",
1695
1700
  "embla-carousel-fade": "8.6.0",
1696
1701
  "embla-carousel-react": "8.6.0",
1702
+ "hls.js": "1.6.19",
1697
1703
  "react-floater": "0.7.9",
1698
1704
  "react-phone-number-input": "3.4.12",
1699
1705
  "react-player": "2.16.0"
@@ -3,12 +3,15 @@ import { ComponentType, ReactNode } from 'react';
3
3
  export interface FormActionProps {
4
4
  // The submit button's label; defaults to 'Confirm'.
5
5
  action?: ReactNode;
6
- // The mutation run on submit.
7
- callback: () => Promise<unknown>;
6
+ // The mutation run on submit. It receives the form's values: any field the
7
+ // children render through a Controller (form context), seeded by defaultValues.
8
+ callback: ( values: Record<string, unknown> ) => Promise<unknown>;
8
9
  // Shows a secondary button beside the action.
9
10
  cancel?: { action?: ReactNode; onClick?: () => void };
10
11
  children?: ReactNode;
11
12
  className?: string;
13
+ // Initial values for fields rendered in the children.
14
+ defaultValues?: Record<string, unknown>;
12
15
  disabled?: boolean;
13
16
  fineprint?: ReactNode;
14
17
  onError?: ( error: Error ) => void;
@@ -10,3 +10,13 @@ export declare const connectionControls: ( connection?: {
10
10
  paused: boolean;
11
11
  remove: 'disconnect' | 'manage' | null;
12
12
  };
13
+
14
+ // Whether the connection form shows the stored connection (true) or a fresh
15
+ // connect (false): a stored connection unless its fix is to connect again
16
+ // (requiresReconnect in @drawbridge/drawbridge-utils/connections/reconnect).
17
+ export declare const isConnected: ( connection?: {
18
+ connect?: { type?: string };
19
+ errors?: { source?: string }[];
20
+ id?: string;
21
+ [ key: string ]: unknown;
22
+ } | null ) => boolean;
@@ -0,0 +1,9 @@
1
+ // The Video component's source decisions, kept pure so they can be tested.
2
+
3
+ export declare const provideHls: ( Hls: unknown, target: { Hls?: unknown } ) => void;
4
+
5
+ export declare const videoErrorAction: ( options: { data?: { fatal?: boolean }; error?: unknown; mp4?: string; url?: string } ) => 'ignore' | 'retry' | 'fail';
6
+
7
+ export declare const videoOverlay: ( options: { failed?: boolean; poster?: string; videoPaintable?: boolean } ) => 'poster' | 'loader' | 'warning' | null;
8
+
9
+ export declare const startSeek: ( options: { reset?: boolean; wasReset?: boolean } ) => number | null;