@doyourjob/gravity-ui-page-constructor 5.31.228 → 5.31.231

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 (30) hide show
  1. package/build/cjs/blocks/HeaderMinify/HeaderMinify.css +2 -2
  2. package/build/cjs/blocks/LogoRotator/Item.d.ts +1 -1
  3. package/build/cjs/blocks/LogoRotator/Item.js +8 -2
  4. package/build/cjs/blocks/LogoRotator/LogoRotator.js +11 -2
  5. package/build/cjs/blocks/LogoRotator/schema.js +1 -1
  6. package/build/cjs/blocks/Scroller/Scroller.css +14 -9
  7. package/build/cjs/blocks/Scroller/Scroller.js +81 -27
  8. package/build/cjs/blocks/Scroller/schema.d.ts +28 -8
  9. package/build/cjs/blocks/Scroller/schema.js +17 -7
  10. package/build/cjs/blocks/WhatsNew/WhatsNew.js +2 -2
  11. package/build/cjs/blocks/WhatsNew/schema.d.ts +12 -0
  12. package/build/cjs/blocks/WhatsNew/schema.js +2 -1
  13. package/build/cjs/models/constructor-items/blocks.d.ts +3 -2
  14. package/build/esm/blocks/HeaderMinify/HeaderMinify.css +2 -2
  15. package/build/esm/blocks/LogoRotator/Item.d.ts +1 -1
  16. package/build/esm/blocks/LogoRotator/Item.js +8 -2
  17. package/build/esm/blocks/LogoRotator/LogoRotator.js +11 -2
  18. package/build/esm/blocks/LogoRotator/schema.js +1 -1
  19. package/build/esm/blocks/Scroller/Scroller.css +14 -9
  20. package/build/esm/blocks/Scroller/Scroller.js +81 -27
  21. package/build/esm/blocks/Scroller/schema.d.ts +28 -8
  22. package/build/esm/blocks/Scroller/schema.js +16 -6
  23. package/build/esm/blocks/WhatsNew/WhatsNew.js +2 -2
  24. package/build/esm/blocks/WhatsNew/schema.d.ts +12 -0
  25. package/build/esm/blocks/WhatsNew/schema.js +2 -1
  26. package/build/esm/models/constructor-items/blocks.d.ts +3 -2
  27. package/package.json +1 -1
  28. package/schema/index.js +1 -1
  29. package/server/models/constructor-items/blocks.d.ts +3 -2
  30. package/widget/index.js +1 -1
@@ -1,9 +1,26 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import { AnimateBlock } from '../../components';
3
- import { BREAKPOINTS } from '../../constants';
4
3
  import { block } from '../../utils';
5
4
  import './Scroller.css';
6
5
  const b = block('scroller-block');
6
+ const getChild = (parent, index) => {
7
+ const child = parent.children[index];
8
+ return child instanceof HTMLElement ? child : null;
9
+ };
10
+ const getCenteredChildIndex = (content) => {
11
+ const midLine = content.getBoundingClientRect().left + content.clientWidth / 2;
12
+ for (let i = 0; i < content.children.length; i++) {
13
+ const rect = content.children[i].getBoundingClientRect();
14
+ if (rect.left <= midLine && rect.right >= midLine) {
15
+ return i;
16
+ }
17
+ }
18
+ return 0;
19
+ };
20
+ const scrollToChild = (content, child, behavior = 'smooth') => {
21
+ const left = child.offsetLeft - (content.offsetWidth - child.offsetWidth) / 2;
22
+ content.scrollTo({ left, behavior });
23
+ };
7
24
  const PlayIcon = () => {
8
25
  return (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "30", height: "30", viewBox: "0 0 30 30", fill: "none" },
9
26
  React.createElement("path", { d: "M13.765 9.83831L20.3154 13.7086C21.2977 14.289 21.298 15.7102 20.3159 16.2911L13.7714 20.1618C12.7719 20.7529 11.5086 20.033 11.5078 18.8718L11.502 11.1309C11.5011 9.96894 12.7646 9.24725 13.765 9.83831Z", fill: "currentColor" })));
@@ -13,7 +30,8 @@ const PauseIcon = () => {
13
30
  React.createElement("path", { d: "M12.5 10C13.3284 10 14 10.6716 14 11.5V18.5C14 19.3284 13.3284 20 12.5 20C11.6716 20 11 19.3284 11 18.5V11.5C11 10.6716 11.6716 10 12.5 10ZM17.5 10C18.3284 10 19 10.6716 19 11.5V18.5C19 19.3284 18.3284 20 17.5 20C16.6716 20 16 19.3284 16 18.5V11.5C16 10.6716 16.6716 10 17.5 10Z", fill: "currentColor" })));
14
31
  };
15
32
  export const ScrollerBlock = (props) => {
16
- const { animated, widths, gapLong, fullWidth, scrollSnapCenter, children, autoScroll, autoScrollInterval = 3000, } = props;
33
+ const { animated, widths, gapLong, fullWidth, scrollSnapCenter, children, autoScroll = true, autoScrollInterval = 3000, infinite = false, } = props;
34
+ const childCount = React.Children.count(children);
17
35
  const rootRef = useRef(null);
18
36
  const contentRef = useRef(null);
19
37
  const [currentElement, setCurrentElement] = useState(0);
@@ -32,28 +50,12 @@ export const ScrollerBlock = (props) => {
32
50
  content.style.setProperty('left', `${-space}px`);
33
51
  content.style.setProperty('width', `calc(100% + ${2 * space}px)`);
34
52
  }
35
- if (scrollSnapCenter && window.innerWidth >= BREAKPOINTS.md) {
36
- content.style.setProperty('--scroller-edge-margin', `${content.clientWidth / 3}px`);
37
- }
38
- else {
39
- content.style.removeProperty('--scroller-edge-margin');
40
- }
41
53
  };
42
54
  const determineCurrentElement = () => {
43
- var _a;
44
- const childCount = ((_a = content === null || content === void 0 ? void 0 : content.children) === null || _a === void 0 ? void 0 : _a.length) || 0;
45
55
  if (!content || childCount <= 1) {
46
56
  return;
47
57
  }
48
- const currentMidLine = content.clientWidth / 2;
49
- [...content.children].find((child, index) => {
50
- const childRect = child.getBoundingClientRect();
51
- if (currentMidLine > childRect.left && currentMidLine < childRect.right) {
52
- setCurrentElement(index);
53
- return true;
54
- }
55
- return false;
56
- });
58
+ setCurrentElement(getCenteredChildIndex(content) % childCount);
57
59
  };
58
60
  updateSize();
59
61
  determineCurrentElement();
@@ -63,23 +65,69 @@ export const ScrollerBlock = (props) => {
63
65
  window.removeEventListener('resize', updateSize);
64
66
  content === null || content === void 0 ? void 0 : content.removeEventListener('scroll', determineCurrentElement);
65
67
  };
66
- }, [fullWidth, scrollSnapCenter]);
68
+ }, [fullWidth, childCount, children]);
69
+ useEffect(() => {
70
+ const content = contentRef.current;
71
+ if (!content || !infinite || childCount <= 1) {
72
+ return () => { };
73
+ }
74
+ const middleCenterIndex = Math.floor(childCount * 1.5);
75
+ const copyStartIndex = childCount;
76
+ const endCopyStartIndex = childCount * 2;
77
+ const scrollToMiddle = () => {
78
+ const middleChild = getChild(content, middleCenterIndex);
79
+ if (middleChild) {
80
+ content.scrollTo(middleChild.offsetLeft + content.offsetWidth / 2 - middleChild.offsetWidth / 2, 0);
81
+ }
82
+ };
83
+ const handleInfiniteScroll = () => {
84
+ const scrollLeft = content.scrollLeft;
85
+ const endCopyChild = getChild(content, endCopyStartIndex);
86
+ const copyStartChild = getChild(content, copyStartIndex);
87
+ if (endCopyChild && scrollLeft > endCopyChild.offsetLeft) {
88
+ const delta = endCopyChild.offsetLeft - scrollLeft;
89
+ const resetChild = getChild(content, copyStartIndex);
90
+ if (resetChild) {
91
+ content.scrollTo(resetChild.offsetLeft + delta, 0);
92
+ }
93
+ }
94
+ if (copyStartChild && scrollLeft < copyStartChild.offsetLeft - content.clientWidth) {
95
+ const endChild = getChild(content, endCopyStartIndex);
96
+ if (endChild) {
97
+ content.scrollTo(endChild.offsetLeft - content.clientWidth, 0);
98
+ }
99
+ }
100
+ };
101
+ content.addEventListener('scroll', handleInfiniteScroll, { passive: true });
102
+ scrollToMiddle();
103
+ return () => {
104
+ content.removeEventListener('scroll', handleInfiniteScroll);
105
+ };
106
+ }, [infinite, childCount]);
67
107
  useEffect(() => {
68
108
  if (autoScroll) {
69
109
  setIsPaused(false);
70
110
  }
71
111
  }, [autoScroll]);
72
- const childCount = React.Children.count(children);
73
112
  const scrollToNext = useCallback(() => {
74
113
  const content = contentRef.current;
75
- if (!content) {
114
+ if (!content || childCount <= 1) {
115
+ return;
116
+ }
117
+ if (infinite) {
118
+ const centeredIndex = getCenteredChildIndex(content);
119
+ const nextElement = getChild(content, centeredIndex + 1);
120
+ if (nextElement) {
121
+ scrollToChild(content, nextElement);
122
+ }
76
123
  return;
77
124
  }
78
125
  const nextIndex = (currentElement + 1) % childCount;
79
- const nextElement = content.children[nextIndex];
80
- const nextIndexLeft = nextElement.offsetLeft - (content.offsetWidth - nextElement.offsetWidth) / 2;
81
- content.scrollTo({ left: nextIndexLeft, behavior: 'smooth' });
82
- }, [childCount, currentElement]);
126
+ const nextElement = getChild(content, nextIndex);
127
+ if (nextElement) {
128
+ scrollToChild(content, nextElement);
129
+ }
130
+ }, [childCount, currentElement, infinite]);
83
131
  useEffect(() => {
84
132
  let timeout = null;
85
133
  if (!isPaused) {
@@ -95,7 +143,13 @@ export const ScrollerBlock = (props) => {
95
143
  }, [isPaused, currentElement, autoScrollInterval, scrollToNext]);
96
144
  return (React.createElement(AnimateBlock, { className: b({ fullWidth }), animate: animated },
97
145
  React.createElement("div", { className: b('root'), ref: rootRef },
98
- React.createElement("div", { className: b('content', { gapLong, fullWidth, scrollSnapCenter }), ref: contentRef }, React.Children.map(children, (child, index) => (React.createElement("div", { key: index, className: b('item'), style: { width: (widths === null || widths === void 0 ? void 0 : widths[index]) || 'auto' } }, child))))),
146
+ React.createElement("div", { className: b('content', {
147
+ gapLong,
148
+ fullWidth,
149
+ 'scroll-snap-center': infinite ? false : scrollSnapCenter,
150
+ }), ref: contentRef }, (infinite ? [0, 1, 2] : [0])
151
+ .map((mi) => React.Children.map(children, (child, index) => (React.createElement("div", { key: mi * childCount + index, className: b('item'), style: { width: (widths === null || widths === void 0 ? void 0 : widths[index]) || 'auto' } }, child))))
152
+ .flat())),
99
153
  autoScroll && childCount > 0 && (React.createElement("div", { className: b('pagination-container') },
100
154
  React.createElement("div", { className: b('pagination') }, Array.from({ length: childCount }, (_, index) => (React.createElement("div", { key: index, className: b('pip', { active: index === currentElement }) },
101
155
  React.createElement("div", { style: {
@@ -1,18 +1,29 @@
1
+ export declare const ScrollerControlsProps: {
2
+ infinite: {
3
+ type: string;
4
+ };
5
+ scrollSnapCenter: {
6
+ type: string;
7
+ };
8
+ autoScroll: {
9
+ type: string;
10
+ };
11
+ autoScrollInterval: {
12
+ type: string;
13
+ };
14
+ };
1
15
  export declare const ScrollerBlock: {
2
16
  'scroller-block': {
3
17
  additionalProperties: boolean;
4
18
  required: boolean;
5
19
  properties: {
6
- widths: {
20
+ children: {
7
21
  type: string;
8
22
  items: {
9
- type: string;
23
+ $ref: string;
10
24
  };
11
25
  };
12
- gapLong: {
13
- type: string;
14
- };
15
- fullWidth: {
26
+ infinite: {
16
27
  type: string;
17
28
  };
18
29
  scrollSnapCenter: {
@@ -21,12 +32,21 @@ export declare const ScrollerBlock: {
21
32
  autoScroll: {
22
33
  type: string;
23
34
  };
24
- children: {
35
+ autoScrollInterval: {
36
+ type: string;
37
+ };
38
+ widths: {
25
39
  type: string;
26
40
  items: {
27
- $ref: string;
41
+ type: string;
28
42
  };
29
43
  };
44
+ gapLong: {
45
+ type: string;
46
+ };
47
+ fullWidth: {
48
+ type: string;
49
+ };
30
50
  animated: {
31
51
  type: string;
32
52
  };
@@ -1,9 +1,23 @@
1
1
  import { AnimatableProps, BaseProps, ChildrenCardsProps } from '../../schema/validators/common';
2
+ export const ScrollerControlsProps = {
3
+ infinite: {
4
+ type: 'boolean',
5
+ },
6
+ scrollSnapCenter: {
7
+ type: 'boolean',
8
+ },
9
+ autoScroll: {
10
+ type: 'boolean',
11
+ },
12
+ autoScrollInterval: {
13
+ type: 'number',
14
+ },
15
+ };
2
16
  export const ScrollerBlock = {
3
17
  'scroller-block': {
4
18
  additionalProperties: false,
5
19
  required: false,
6
- properties: Object.assign(Object.assign(Object.assign({}, BaseProps), AnimatableProps), { widths: {
20
+ properties: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, BaseProps), AnimatableProps), { widths: {
7
21
  type: 'array',
8
22
  items: {
9
23
  type: 'string',
@@ -12,10 +26,6 @@ export const ScrollerBlock = {
12
26
  type: 'boolean',
13
27
  }, fullWidth: {
14
28
  type: 'boolean',
15
- }, scrollSnapCenter: {
16
- type: 'boolean',
17
- }, autoScroll: {
18
- type: 'boolean',
19
- }, children: ChildrenCardsProps }),
29
+ } }), ScrollerControlsProps), { children: ChildrenCardsProps }),
20
30
  },
21
31
  };
@@ -5,12 +5,12 @@ import { block } from '../../utils';
5
5
  import ScrollerBlock from '../Scroller/Scroller';
6
6
  import './WhatsNew.css';
7
7
  const b = block('whats-new-block');
8
- const WhatsNew = ({ title, items, footnote, links, animated }) => {
8
+ const WhatsNew = ({ title, items, footnote, links, animated, infinite, scrollSnapCenter, autoScroll, autoScrollInterval, }) => {
9
9
  return (React.createElement(AnimateBlock, { className: b(), animate: animated },
10
10
  React.createElement("div", { className: b('root') },
11
11
  title && (React.createElement("div", { className: b('head') },
12
12
  React.createElement("h2", { className: b('title') }, title))),
13
- React.createElement(ScrollerBlock, { fullWidth: true, scrollSnapCenter: true, autoScroll: true }, items.map((item, index) => (React.createElement(NewsCard, Object.assign({ key: index }, item))))),
13
+ React.createElement(ScrollerBlock, { fullWidth: true, infinite: infinite, scrollSnapCenter: scrollSnapCenter, autoScroll: autoScroll !== null && autoScroll !== void 0 ? autoScroll : true, autoScrollInterval: autoScrollInterval }, items.map((item, index) => (React.createElement(NewsCard, Object.assign({ key: index }, item))))),
14
14
  (footnote || (links === null || links === void 0 ? void 0 : links.length)) && (React.createElement("div", { className: b('footer') },
15
15
  footnote && React.createElement("div", { className: b('footnote') }, footnote),
16
16
  (links === null || links === void 0 ? void 0 : links.length) ? (React.createElement("div", { className: b('links') }, links.map((link, index) => (React.createElement("a", { key: index, href: link.url, className: b('link'), target: "_blank", rel: "noopener noreferrer" },
@@ -56,6 +56,18 @@ export declare const WhatsNewBlock: {
56
56
  };
57
57
  };
58
58
  };
59
+ infinite: {
60
+ type: string;
61
+ };
62
+ scrollSnapCenter: {
63
+ type: string;
64
+ };
65
+ autoScroll: {
66
+ type: string;
67
+ };
68
+ autoScrollInterval: {
69
+ type: string;
70
+ };
59
71
  title: {
60
72
  oneOf: ({
61
73
  type: string;
@@ -1,9 +1,10 @@
1
1
  import { AnimatableProps, BlockBaseProps, BlockHeaderProps } from '../../schema/validators/common';
2
+ import { ScrollerControlsProps } from '../Scroller/schema';
2
3
  export const WhatsNewBlock = {
3
4
  'whats-new-block': {
4
5
  additionalProperties: false,
5
6
  required: ['items'],
6
- properties: Object.assign(Object.assign(Object.assign(Object.assign({}, BlockBaseProps), AnimatableProps), BlockHeaderProps), { items: {
7
+ properties: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, BlockBaseProps), AnimatableProps), BlockHeaderProps), ScrollerControlsProps), { items: {
7
8
  type: 'array',
8
9
  items: {
9
10
  type: 'object',
@@ -298,7 +298,7 @@ export interface BannerBlockProps extends BannerCardProps, Animatable {
298
298
  export interface LogoRotatorBlockProps extends Animatable {
299
299
  title?: TitleItemBaseProps | string;
300
300
  items: {
301
- url: string;
301
+ url?: string;
302
302
  src: string;
303
303
  isStatic?: boolean;
304
304
  }[];
@@ -359,6 +359,7 @@ export interface ScrollerBlockProps extends Animatable {
359
359
  widths?: string[];
360
360
  gapLong?: boolean;
361
361
  fullWidth?: boolean;
362
+ infinite?: boolean;
362
363
  scrollSnapCenter?: boolean;
363
364
  autoScroll?: boolean;
364
365
  autoScrollInterval?: number;
@@ -641,7 +642,7 @@ export interface BenchmarkBlockProps extends Animatable {
641
642
  postfix?: string;
642
643
  }[];
643
644
  }
644
- export interface WhatsNewBlockProps extends Animatable {
645
+ export interface WhatsNewBlockProps extends Animatable, Pick<ScrollerBlockProps, 'infinite' | 'scrollSnapCenter' | 'autoScroll' | 'autoScrollInterval'> {
645
646
  title?: string;
646
647
  items: NewsCardProps[];
647
648
  footnote?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doyourjob/gravity-ui-page-constructor",
3
- "version": "5.31.228",
3
+ "version": "5.31.231",
4
4
  "description": "Gravity UI Page Constructor",
5
5
  "license": "MIT",
6
6
  "repository": {