@wix/editor-react-components 1.2760.0 → 1.2762.0

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.
@@ -1,3 +1,89 @@
1
+ .root-Y7wYn3 {
2
+ box-sizing: border-box;
3
+ width: 100%;
4
+ min-width: 0;
5
+ font: var(--wst-paragraph-2-font);
6
+ color: var(--wst-paragraph-2-color, #000);
7
+ border-width: var(--wst-system-line-1-width, 1px);
8
+ border-style: solid;
9
+ border-color: color-mix(in srgb,
10
+ var(--wst-system-line-1-color, #000) 60%,
11
+ transparent);
12
+ background-color: var(--wst-primary-background-color, #fff);
13
+ vertical-align: middle;
14
+ border-radius: 4px;
15
+ margin: 0;
16
+ padding-block: 8px;
17
+ padding-inline: 12px;
18
+ display: block;
19
+ }
20
+
21
+ .root-Y7wYn3:hover {
22
+ border-color: var(--wst-system-line-1-color, #000);
23
+ }
24
+
25
+ .root-Y7wYn3:focus {
26
+ border-color: var(--wst-system-line-1-color, #000);
27
+ outline: none;
28
+ }
29
+
30
+ .root-Y7wYn3:disabled {
31
+ color: var(--wst-system-disabled-color, #939393);
32
+ border-color: color-mix(in srgb,
33
+ var(--wst-system-line-1-color, #000) 60%,
34
+ transparent);
35
+ cursor: not-allowed;
36
+ }
37
+
38
+ .root-Y7wYn3[aria-invalid="true"] {
39
+ border-color: color-mix(in srgb,
40
+ var(--wst-system-error-color, #df3131) 60%,
41
+ transparent);
42
+ }
43
+
44
+ .root-Y7wYn3[aria-invalid="true"]:hover {
45
+ border-color: var(--wst-system-error-color, #df3131);
46
+ }
47
+
48
+ .root-Y7wYn3[aria-invalid="true"]:focus {
49
+ border-color: var(--wst-system-error-color, #df3131);
50
+ outline: none;
51
+ }
52
+
53
+ .root-Y7wYn3[data-valid] {
54
+ border-color: color-mix(in srgb,
55
+ var(--wst-system-success-color, #008250) 60%,
56
+ transparent);
57
+ }
58
+
59
+ .root-Y7wYn3::selection {
60
+ background-color: color-mix(in srgb,
61
+ var(--wst-paragraph-2-color, #000) 20%,
62
+ transparent);
63
+ }
64
+
65
+ .root-Y7wYn3::placeholder {
66
+ color: var(--wst-shade-3-color, #767676);
67
+ font: var(--wst-paragraph-2-font);
68
+ }
69
+
70
+ .root-Y7wYn3:disabled::placeholder {
71
+ color: var(--wst-system-disabled-color, #939393);
72
+ }
73
+
74
+ .root-Y7wYn3:-webkit-autofill {
75
+ -webkit-text-fill-color: var(--wst-paragraph-2-color, #000);
76
+ box-shadow: 0 0 0 1.5em var(--wst-primary-background-color, #fff) inset !important;
77
+ }
78
+
79
+ .root-Y7wYn3[type="number"]::-webkit-inner-spin-button, .root-Y7wYn3[type="number"]::-webkit-outer-spin-button {
80
+ appearance: none;
81
+ }
82
+
83
+ .root-Y7wYn3[type="number"] {
84
+ appearance: textfield;
85
+ }
86
+
1
87
  .root-ECdHfF {
2
88
  flex-direction: column;
3
89
  gap: 4px;
@@ -569,8 +569,7 @@ const itemLabelConfig = {
569
569
  textDecorationLine: { defaultValue: "none" },
570
570
  textTransform: { defaultValue: "none" },
571
571
  letterSpacing: { defaultValue: "normal" },
572
- textShadow: { defaultValue: "none" },
573
- textAlign: { defaultValue: "center" }
572
+ textShadow: { defaultValue: "none" }
574
573
  }
575
574
  }
576
575
  };
@@ -4,11 +4,20 @@ export declare enum ScrollSpeed {
4
4
  normal = "normal",
5
5
  fast = "fast"
6
6
  }
7
+ /** Where on the screen the top of the component is when the video starts to move. */
8
+ export declare enum ScrubStart {
9
+ /** As soon as the component comes into view. */
10
+ bottom = "bottom",
11
+ center = "center",
12
+ /** When the stage sticks under the header. */
13
+ top = "top"
14
+ }
7
15
  export interface VideoScrubProps {
8
16
  id: string;
9
17
  className?: string;
10
18
  video?: VideoMedia;
11
19
  scrollSpeed?: ScrollSpeed;
20
+ scrubStart?: ScrubStart;
12
21
  /**
13
22
  * Whether this render may scrub. The live bundle always may; the editor bundle may only in
14
23
  * Preview, because the editor stage keeps the designed height.
@@ -2,7 +2,7 @@ import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { useRef, useState, useEffect, useCallback } from "react";
3
3
  import { c as clsx } from "../chunks/clsx.js";
4
4
  import { V as Video } from "../chunks/Video.js";
5
- import { S as ScrollSpeed, a as SCROLL_VH_PER_SECOND, M as MAX_SCROLL_VH, b as MIN_SCROLL_VH, D as DEFAULT_VIDEO, c as DEFAULT_VIDEO_RATIO, R as ROOT_CLASS } from "../chunks/constants2.js";
5
+ import { S as STICKY_TOP, a as ScrollSpeed, b as SCROLL_VH_PER_SECOND, c as START_LINE, M as MAX_SCROLL_VH, d as MIN_SCROLL_VH, D as DEFAULT_VIDEO_RATIO, R as ROOT_CLASS, e as ScrubStart } from "../chunks/constants2.js";
6
6
  import { useService } from "@wix/services-manager-react";
7
7
  import { E as EnvironmentDefinition } from "../chunks/index2.js";
8
8
  const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
@@ -18,14 +18,29 @@ const getVideoRatio = (video) => {
18
18
  const height = Number(sized == null ? void 0 : sized.height);
19
19
  return width > 0 && height > 0 ? height / width : void 0;
20
20
  };
21
- const getScrubProgress = (root2, stage2) => {
21
+ const getScrollSpaceHeight = (duration, speed, start) => {
22
+ const length = `${getScrollLengthVh(duration, speed)}vh`;
23
+ const part = START_LINE[start];
24
+ return part === void 0 ? length : `max(0px, ${length} - max(0px, ${part * 100}vh - ${STICKY_TOP}))`;
25
+ };
26
+ const getScrubProgress = (root2, stage2, {
27
+ start,
28
+ viewportHeight,
29
+ stickyTop
30
+ }) => {
22
31
  const rootRect = root2.getBoundingClientRect();
23
32
  const stageRect = stage2.getBoundingClientRect();
24
- const travel = rootRect.height - stageRect.height;
25
- if (!(travel > 0)) {
33
+ const travel = Math.max(0, rootRect.height - stageRect.height);
34
+ const part = START_LINE[start];
35
+ const line = part === void 0 ? stickyTop : Math.max(part * viewportHeight, stickyTop);
36
+ const preRoll = line - stickyTop;
37
+ const distance = preRoll + travel;
38
+ if (!(distance > 0)) {
26
39
  return 0;
27
40
  }
28
- return clamp((stageRect.top - rootRect.top) / travel, 0, 1);
41
+ const preRolled = clamp(line - rootRect.top, 0, preRoll);
42
+ const stuck = clamp(stageRect.top - rootRect.top, 0, travel);
43
+ return clamp((preRolled + stuck) / distance, 0, 1);
29
44
  };
30
45
  const useScrubGate = ({
31
46
  scrubAllowed,
@@ -142,6 +157,7 @@ const useScrubVideo = ({
142
157
  };
143
158
  const useScrubProgress = ({
144
159
  enabled,
160
+ start,
145
161
  rootRef,
146
162
  stageRef,
147
163
  onProgress
@@ -153,7 +169,14 @@ const useScrubProgress = ({
153
169
  return void 0;
154
170
  }
155
171
  let frame = 0;
156
- const read = () => onProgress(getScrubProgress(root2, stage2));
172
+ const stageStyle = getComputedStyle(stage2);
173
+ const read = () => onProgress(
174
+ getScrubProgress(root2, stage2, {
175
+ start,
176
+ viewportHeight: window.innerHeight,
177
+ stickyTop: parseFloat(stageStyle.top) || 0
178
+ })
179
+ );
157
180
  const tick = () => {
158
181
  read();
159
182
  frame = requestAnimationFrame(tick);
@@ -178,16 +201,18 @@ const useScrubProgress = ({
178
201
  observer.disconnect();
179
202
  stop();
180
203
  };
181
- }, [enabled, rootRef, stageRef, onProgress]);
204
+ }, [enabled, start, rootRef, stageRef, onProgress]);
182
205
  };
183
206
  const root = "root__Wv1E1";
184
207
  const stage = "stage__XFpev";
208
+ const media = "media__tTFno";
185
209
  const scrubbing = "scrubbing__yEgJI";
186
210
  const scrollSpace = "scrollSpace__oaKzu";
187
211
  const frameReady = "frameReady__g-HFT";
188
212
  const styles = {
189
213
  root,
190
214
  stage,
215
+ media,
191
216
  scrubbing,
192
217
  scrollSpace,
193
218
  frameReady
@@ -199,23 +224,24 @@ const SCRUB_ROOT_STYLE = {
199
224
  const VideoScrub = ({
200
225
  id,
201
226
  className,
202
- video: savedVideo,
227
+ video,
203
228
  scrollSpeed = ScrollSpeed.normal,
229
+ scrubStart = ScrubStart.top,
204
230
  scrubAllowed = true
205
231
  }) => {
206
232
  const rootRef = useRef(null);
207
233
  const stageRef = useRef(null);
208
234
  const videoRef = useRef(null);
209
- const video = savedVideo ?? DEFAULT_VIDEO;
210
- const duration = video.duration ?? 0;
235
+ const duration = (video == null ? void 0 : video.duration) ?? 0;
211
236
  const { layout, seek } = useScrubGate({ scrubAllowed, duration });
212
237
  const { seekProgress, frameReady: frameReady2 } = useScrubVideo({
213
238
  enabled: seek,
214
239
  videoRef,
215
- videoKey: video.uri
240
+ videoKey: video == null ? void 0 : video.uri
216
241
  });
217
242
  useScrubProgress({
218
243
  enabled: seek,
244
+ start: scrubStart,
219
245
  rootRef,
220
246
  stageRef,
221
247
  onProgress: seekProgress
@@ -238,21 +264,27 @@ const VideoScrub = ({
238
264
  {
239
265
  ref: stageRef,
240
266
  className: clsx(styles.stage, frameReady2 && styles.frameReady),
241
- style: layout ? {
242
- aspectRatio: `1 / ${getVideoRatio(video) ?? DEFAULT_VIDEO_RATIO}`
243
- } : void 0,
244
267
  "data-scrub-stage": layout ? "" : void 0,
245
268
  "aria-hidden": "true",
246
269
  children: /* @__PURE__ */ jsx(
247
- Video,
270
+ "div",
248
271
  {
249
- id: `video_${id}`,
250
- videoMedia: video,
251
- videoRef,
252
- qualityPolicy: "proportional",
253
- autoplay: false,
254
- loop: false,
255
- muted: true
272
+ className: styles.media,
273
+ style: layout ? {
274
+ aspectRatio: `1 / ${getVideoRatio(video) ?? DEFAULT_VIDEO_RATIO}`
275
+ } : void 0,
276
+ children: video && /* @__PURE__ */ jsx(
277
+ Video,
278
+ {
279
+ id: `video_${id}`,
280
+ videoMedia: video,
281
+ videoRef,
282
+ qualityPolicy: "proportional",
283
+ autoplay: false,
284
+ loop: false,
285
+ muted: true
286
+ }
287
+ )
256
288
  }
257
289
  )
258
290
  }
@@ -261,7 +293,9 @@ const VideoScrub = ({
261
293
  "div",
262
294
  {
263
295
  className: styles.scrollSpace,
264
- style: { height: `${getScrollLengthVh(duration, scrollSpeed)}vh` }
296
+ style: {
297
+ height: getScrollSpaceHeight(duration, scrollSpeed, scrubStart)
298
+ }
265
299
  }
266
300
  )
267
301
  ]
@@ -1,8 +1,8 @@
1
- import { VideoMedia } from '@wix/video';
2
- import { ScrollSpeed } from './VideoScrub.types';
1
+ import { ScrollSpeed, ScrubStart } from './VideoScrub.types';
3
2
  export declare const ROOT_CLASS = "video-scrub";
4
3
  export declare const DEFAULT_VIDEO_RATIO: number;
5
4
  export declare const SCROLL_VH_PER_SECOND: Record<ScrollSpeed, number>;
6
5
  export declare const MIN_SCROLL_VH = 50;
7
6
  export declare const MAX_SCROLL_VH = 1000;
8
- export declare const DEFAULT_VIDEO: VideoMedia;
7
+ export declare const STICKY_TOP = "var(--video-scrub-sticky-top)";
8
+ export declare const START_LINE: Partial<Record<ScrubStart, number>>;
@@ -1,18 +1,71 @@
1
1
  .root__Wv1E1 {
2
+ --maskImage: initial;
3
+ --boxShadow: initial;
4
+ --border-width-top: initial;
5
+ --border-width-inline-end: initial;
6
+ --border-width-bottom: initial;
7
+ --border-width-inline-start: initial;
8
+ --border-color-top: initial;
9
+ --border-color-inline-end: initial;
10
+ --border-color-bottom: initial;
11
+ --border-color-inline-start: initial;
12
+ --border-style-top: initial;
13
+ --border-style-inline-end: initial;
14
+ --border-style-bottom: initial;
15
+ --border-style-inline-start: initial;
16
+ --borderStartStartRadius: initial;
17
+ --borderStartEndRadius: initial;
18
+ --borderEndStartRadius: initial;
19
+ --borderEndEndRadius: initial;
2
20
  position: relative;
3
21
  box-sizing: border-box;
4
22
  }
5
23
 
6
24
  .stage__XFpev {
7
25
  position: relative;
26
+ box-sizing: border-box;
8
27
  width: 100%;
9
28
  height: 100%;
10
29
  overflow: hidden;
30
+ box-shadow: var(--boxShadow, none);
31
+ border-top-width: var(--border-width-top, 0);
32
+ border-inline-end-width: var(--border-width-inline-end, 0);
33
+ border-bottom-width: var(--border-width-bottom, 0);
34
+ border-inline-start-width: var(--border-width-inline-start, 0);
35
+ border-top-color: var(--border-color-top, transparent);
36
+ border-inline-end-color: var(--border-color-inline-end, transparent);
37
+ border-bottom-color: var(--border-color-bottom, transparent);
38
+ border-inline-start-color: var(--border-color-inline-start, transparent);
39
+ border-top-style: var(--border-style-top, solid);
40
+ border-inline-end-style: var(--border-style-inline-end, solid);
41
+ border-bottom-style: var(--border-style-bottom, solid);
42
+ border-inline-start-style: var(--border-style-inline-start, solid);
43
+ border-start-start-radius: var(--borderStartStartRadius, 0);
44
+ border-start-end-radius: var(--borderStartEndRadius, 0);
45
+ border-end-start-radius: var(--borderEndStartRadius, 0);
46
+ border-end-end-radius: var(--borderEndEndRadius, 0);
47
+ }
48
+
49
+ .media__tTFno {
50
+ position: relative;
51
+ width: 100%;
52
+ height: 100%;
53
+ mask-image: var(--maskImage, none);
54
+ mask-size: 100% 100%;
55
+ mask-repeat: no-repeat;
56
+ mask-position: center;
57
+ }
58
+
59
+ .scrubbing__yEgJI {
60
+ --video-scrub-sticky-top: var(
61
+ --wix-top-inset,
62
+ calc(var(--wix-ads-top-height, 0px) + var(--top-offset, 0px))
63
+ );
11
64
  }
12
65
 
13
66
  .scrubbing__yEgJI .stage__XFpev {
14
67
  position: sticky;
15
- top: var(--wix-top-inset, calc(var(--wix-ads-top-height, 0px) + var(--top-offset, 0px)));
68
+ top: var(--video-scrub-sticky-top);
16
69
  transition: top var(--wix-top-inset-transition-duration, 0ms) var(--wix-top-inset-transition-easing, linear);
17
70
  height: inherit;
18
71
  }
@@ -1,10 +1,12 @@
1
1
  import { RefObject } from 'react';
2
+ import { ScrubStart } from '../VideoScrub.types';
2
3
  /**
3
4
  * Calls `onProgress` every frame with the scroll progress through the tall root, while the root
4
- * is on screen. It only reads layout, so it adds no forced reflow to the frame.
5
+ * is on screen. It only reads layout and style, so it adds no forced reflow to the frame.
5
6
  */
6
- export declare const useScrubProgress: ({ enabled, rootRef, stageRef, onProgress, }: {
7
+ export declare const useScrubProgress: ({ enabled, start, rootRef, stageRef, onProgress, }: {
7
8
  enabled: boolean;
9
+ start: ScrubStart;
8
10
  rootRef: RefObject<HTMLElement | null>;
9
11
  stageRef: RefObject<HTMLElement | null>;
10
12
  onProgress: (progress: number) => void;
@@ -1,9 +1,9 @@
1
- import { D as DATA, A as Archetype, L as LAYOUT } from "../chunks/chunk-EVX7ZUBD.js";
1
+ import { b as DISPLAY_GROUPS, C as CSS_PROPERTIES, M as MEDIA, D as DATA, A as Archetype, L as LAYOUT } from "../chunks/chunk-EVX7ZUBD.js";
2
2
  import { V as VideoCategoryTypes } from "../chunks/types.impl.js";
3
- import { S as ScrollSpeed, R as ROOT_CLASS } from "../chunks/constants2.js";
3
+ import { a as ScrollSpeed, e as ScrubStart, R as ROOT_CLASS } from "../chunks/constants2.js";
4
4
  const manifest = {
5
- id: "c3bdf192-6423-4d70-a0f5-d5542d6a3e3f",
6
- type: "wixEditorElements.VideoScrub__DEV__v1",
5
+ id: "45b42eec-531c-46e4-980f-0546afae1eaa",
6
+ type: "wixEditorElements.VideoScrub__DEV__v4",
7
7
  description: "A video that plays by page scroll: while the visitor scrolls past it, the video stays on screen and its time follows the scroll.",
8
8
  installation: {
9
9
  initialSize: {
@@ -29,6 +29,18 @@ const manifest = {
29
29
  },
30
30
  disableDeletion: true
31
31
  },
32
+ scrubStart: {
33
+ displayName: "Starts when video reaches",
34
+ dataType: DATA.DATA_TYPE.textEnum,
35
+ defaultValue: ScrubStart.top,
36
+ [DATA.DATA_TYPE.textEnum]: {
37
+ options: [
38
+ { value: ScrubStart.bottom, displayName: "Bottom of screen" },
39
+ { value: ScrubStart.center, displayName: "Center of screen" },
40
+ { value: ScrubStart.top, displayName: "Top of screen" }
41
+ ]
42
+ }
43
+ },
32
44
  scrollSpeed: {
33
45
  displayName: "Scroll speed",
34
46
  dataType: DATA.DATA_TYPE.textEnum,
@@ -41,6 +53,160 @@ const manifest = {
41
53
  ]
42
54
  }
43
55
  }
56
+ },
57
+ // Custom properties, not cssProperties: Studio puts cssProperties on the root, and the root is
58
+ // the tall scroll track. The sticky stage reads these (VideoScrub.module.scss). Same set as
59
+ // VideoUpload, but the borders are per side (Tabs pattern).
60
+ cssCustomProperties: {
61
+ maskImage: {
62
+ displayName: "Mask",
63
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.maskImage,
64
+ defaultValue: "none",
65
+ maskImage: {
66
+ vectorArtCategory: MEDIA.VECTOR_ART_CATEGORY.SHAPE_LOCATION,
67
+ imageTypes: [CSS_PROPERTIES.IMAGE_TYPE.url]
68
+ }
69
+ },
70
+ boxShadow: {
71
+ displayName: "Shadow",
72
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.boxShadow,
73
+ defaultValue: "none"
74
+ },
75
+ "border-width-top": {
76
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderTopWidth,
77
+ displayName: "Border Width Top",
78
+ defaultValue: "0px"
79
+ },
80
+ "border-width-inline-end": {
81
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderInlineEndWidth,
82
+ displayName: "Border Width End",
83
+ defaultValue: "0px"
84
+ },
85
+ "border-width-bottom": {
86
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderBottomWidth,
87
+ displayName: "Border Width Bottom",
88
+ defaultValue: "0px"
89
+ },
90
+ "border-width-inline-start": {
91
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderInlineStartWidth,
92
+ displayName: "Border Width Start",
93
+ defaultValue: "0px"
94
+ },
95
+ "border-color-top": {
96
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderTopColor,
97
+ displayName: "Border Color Top",
98
+ defaultValue: "transparent"
99
+ },
100
+ "border-color-inline-end": {
101
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderInlineEndColor,
102
+ displayName: "Border Color End",
103
+ defaultValue: "transparent"
104
+ },
105
+ "border-color-bottom": {
106
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderBottomColor,
107
+ displayName: "Border Color Bottom",
108
+ defaultValue: "transparent"
109
+ },
110
+ "border-color-inline-start": {
111
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderInlineStartColor,
112
+ displayName: "Border Color Start",
113
+ defaultValue: "transparent"
114
+ },
115
+ "border-style-top": {
116
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderTopStyle,
117
+ displayName: "Border Style Top",
118
+ defaultValue: "solid"
119
+ },
120
+ "border-style-inline-end": {
121
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderInlineEndStyle,
122
+ displayName: "Border Style End",
123
+ defaultValue: "solid"
124
+ },
125
+ "border-style-bottom": {
126
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderBottomStyle,
127
+ displayName: "Border Style Bottom",
128
+ defaultValue: "solid"
129
+ },
130
+ "border-style-inline-start": {
131
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderInlineStartStyle,
132
+ displayName: "Border Style Start",
133
+ defaultValue: "solid"
134
+ },
135
+ borderStartStartRadius: {
136
+ displayName: "Top Start Corner",
137
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderStartStartRadius,
138
+ defaultValue: "0px"
139
+ },
140
+ borderStartEndRadius: {
141
+ displayName: "Top End Corner",
142
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderStartEndRadius,
143
+ defaultValue: "0px"
144
+ },
145
+ borderEndStartRadius: {
146
+ displayName: "Bottom Start Corner",
147
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderEndStartRadius,
148
+ defaultValue: "0px"
149
+ },
150
+ borderEndEndRadius: {
151
+ displayName: "Bottom End Corner",
152
+ cssPropertyType: CSS_PROPERTIES.CSS_PROPERTY_TYPE.borderEndEndRadius,
153
+ defaultValue: "0px"
154
+ }
155
+ },
156
+ displayGroups: {
157
+ borderColorGroup: {
158
+ groupType: DISPLAY_GROUPS.GROUP_TYPE.borderColor,
159
+ [DISPLAY_GROUPS.GROUP_TYPE.borderColor]: {
160
+ top: "border-color-top",
161
+ right: "border-color-inline-end",
162
+ bottom: "border-color-bottom",
163
+ left: "border-color-inline-start"
164
+ }
165
+ },
166
+ borderWidthGroup: {
167
+ groupType: DISPLAY_GROUPS.GROUP_TYPE.borderWidth,
168
+ [DISPLAY_GROUPS.GROUP_TYPE.borderWidth]: {
169
+ top: "border-width-top",
170
+ right: "border-width-inline-end",
171
+ bottom: "border-width-bottom",
172
+ left: "border-width-inline-start"
173
+ }
174
+ },
175
+ borderStyleGroup: {
176
+ groupType: DISPLAY_GROUPS.GROUP_TYPE.borderStyle,
177
+ [DISPLAY_GROUPS.GROUP_TYPE.borderStyle]: {
178
+ top: "border-style-top",
179
+ right: "border-style-inline-end",
180
+ bottom: "border-style-bottom",
181
+ left: "border-style-inline-start"
182
+ }
183
+ },
184
+ // Per side, so a breakpoint can override one side only (like Tabs).
185
+ borderGroup: {
186
+ groupType: DISPLAY_GROUPS.GROUP_TYPE.border,
187
+ [DISPLAY_GROUPS.GROUP_TYPE.border]: {
188
+ color: "displayGroups.borderColorGroup",
189
+ width: "displayGroups.borderWidthGroup",
190
+ style: "displayGroups.borderStyleGroup"
191
+ }
192
+ },
193
+ cornersGroup: {
194
+ groupType: DISPLAY_GROUPS.GROUP_TYPE.borderRadius,
195
+ displayName: "Corner radius",
196
+ borderRadius: {
197
+ topLeft: "borderStartStartRadius",
198
+ topRight: "borderStartEndRadius",
199
+ bottomLeft: "borderEndStartRadius",
200
+ bottomRight: "borderEndEndRadius"
201
+ }
202
+ },
203
+ // The Settings panel does not follow the `data` key order.
204
+ orderedDataGroup: {
205
+ groupType: DISPLAY_GROUPS.GROUP_TYPE.data,
206
+ data: {
207
+ items: ["video", "scrubStart", "scrollSpeed"]
208
+ }
209
+ }
44
210
  }
45
211
  },
46
212
  resources: {
@@ -1,6 +1,6 @@
1
1
  import { VideoMedia } from '@wix/video';
2
- import { ScrollSpeed } from './VideoScrub.types';
3
- /** How far the visitor scrolls while the stage is stuck, in vh. */
2
+ import { ScrubStart, ScrollSpeed } from './VideoScrub.types';
3
+ /** How far the visitor scrolls from the first frame to the last, in vh. */
4
4
  export declare const getScrollLengthVh: (duration: number, speed?: ScrollSpeed) => number;
5
5
  /**
6
6
  * The video's height / width, from its saved sources (or poster). The stage falls back to it when
@@ -8,7 +8,21 @@ export declare const getScrollLengthVh: (duration: number, speed?: ScrollSpeed)
8
8
  */
9
9
  export declare const getVideoRatio: (video?: VideoMedia) => number | undefined;
10
10
  /**
11
- * Scroll progress through the tall root, 0 to 1: how far the sticky stage has moved down its
12
- * root. 0 until it sticks, 1 once it lets go, so the header and Wix Ads offsets need no math here.
11
+ * The scroll space under the stage, as a CSS height. An earlier start uses part of the scroll
12
+ * length before the stage sticks (the pre-roll), so the stuck part gets that much shorter. The
13
+ * video moves the same amount per scroll for every start.
13
14
  */
14
- export declare const getScrubProgress: (root: Element, stage: Element) => number;
15
+ export declare const getScrollSpaceHeight: (duration: number, speed: ScrollSpeed, start: ScrubStart) => string;
16
+ /**
17
+ * Scroll progress, 0 to 1. 0 while the top of the root is below the start line, 1 once the
18
+ * sticky stage lets go. In between it follows the scroll at the same rate: first the pre-roll,
19
+ * while the stage moves up to its sticky top, then while it is stuck and moves down its root.
20
+ *
21
+ * The stuck part is how far the stage moved down its root, so the header and Wix Ads offsets need
22
+ * no math there. `viewportHeight` and `stickyTop` are used only for the pre-roll of an early start.
23
+ */
24
+ export declare const getScrubProgress: (root: Element, stage: Element, { start, viewportHeight, stickyTop, }: {
25
+ start: ScrubStart;
26
+ viewportHeight: number;
27
+ stickyTop: number;
28
+ }) => number;
@@ -4,6 +4,12 @@ var ScrollSpeed = /* @__PURE__ */ ((ScrollSpeed2) => {
4
4
  ScrollSpeed2["fast"] = "fast";
5
5
  return ScrollSpeed2;
6
6
  })(ScrollSpeed || {});
7
+ var ScrubStart = /* @__PURE__ */ ((ScrubStart2) => {
8
+ ScrubStart2["bottom"] = "bottom";
9
+ ScrubStart2["center"] = "center";
10
+ ScrubStart2["top"] = "top";
11
+ return ScrubStart2;
12
+ })(ScrubStart || {});
7
13
  const ROOT_CLASS = "video-scrub";
8
14
  const DEFAULT_VIDEO_RATIO = 9 / 16;
9
15
  const SCROLL_VH_PER_SECOND = {
@@ -13,40 +19,19 @@ const SCROLL_VH_PER_SECOND = {
13
19
  };
14
20
  const MIN_SCROLL_VH = 50;
15
21
  const MAX_SCROLL_VH = 1e3;
16
- const mp4 = (quality, width, height) => ({
17
- quality,
18
- width,
19
- height,
20
- types: [
21
- {
22
- format: "mp4",
23
- uri: `video/11062b_953b517691e34052afc53ccacc33fc67/${quality}/mp4/file.mp4`
24
- }
25
- ]
26
- });
27
- const DEFAULT_VIDEO = {
28
- name: "Neutral Living Room",
29
- uri: "",
30
- duration: 12.5,
31
- hasAudio: false,
32
- sources: [
33
- mp4("360p", 640, 360),
34
- mp4("480p", 854, 480),
35
- mp4("720p", 1280, 720),
36
- mp4("1080p", 1920, 1080)
37
- ],
38
- poster: {
39
- uri: "11062b_953b517691e34052afc53ccacc33fc67f000.jpg",
40
- width: 2560,
41
- height: 1440
42
- }
22
+ const STICKY_TOP = "var(--video-scrub-sticky-top)";
23
+ const START_LINE = {
24
+ [ScrubStart.bottom]: 1,
25
+ [ScrubStart.center]: 0.5
43
26
  };
44
27
  export {
45
- DEFAULT_VIDEO as D,
28
+ DEFAULT_VIDEO_RATIO as D,
46
29
  MAX_SCROLL_VH as M,
47
30
  ROOT_CLASS as R,
48
- ScrollSpeed as S,
49
- SCROLL_VH_PER_SECOND as a,
50
- MIN_SCROLL_VH as b,
51
- DEFAULT_VIDEO_RATIO as c
31
+ STICKY_TOP as S,
32
+ ScrollSpeed as a,
33
+ SCROLL_VH_PER_SECOND as b,
34
+ START_LINE as c,
35
+ MIN_SCROLL_VH as d,
36
+ ScrubStart as e
52
37
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/editor-react-components",
3
- "version": "1.2760.0",
3
+ "version": "1.2762.0",
4
4
  "description": "React components for the Wix Editor",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -222,5 +222,5 @@
222
222
  "registry": "https://registry.npmjs.org/",
223
223
  "access": "public"
224
224
  },
225
- "falconPackageHash": "52fc139ca2f0f74dea0a25be0a9921ead081f48fde38f674e2ce4087"
225
+ "falconPackageHash": "0fc08bcce0472bac58f4e032897a0c5b0cd25dbb6d24f30f083ec36f"
226
226
  }