@doyourjob/gravity-ui-page-constructor 5.31.245 → 5.31.247
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/build/cjs/blocks/LogoRotator/LogoRotator.js +36 -10
- package/build/cjs/blocks/LogoRotator/schema.d.ts +6 -0
- package/build/cjs/blocks/LogoRotator/schema.js +4 -0
- package/build/cjs/blocks/Map/schema.d.ts +3 -0
- package/build/cjs/blocks/Media/schema.d.ts +6 -0
- package/build/cjs/blocks/Media/schema.js +2 -0
- package/build/cjs/components/MediaBase/MediaBase.css +3 -0
- package/build/cjs/components/MediaBase/MediaBase.js +2 -2
- package/build/cjs/models/constructor-items/blocks.d.ts +3 -0
- package/build/esm/blocks/LogoRotator/LogoRotator.js +36 -10
- package/build/esm/blocks/LogoRotator/schema.d.ts +6 -0
- package/build/esm/blocks/LogoRotator/schema.js +4 -0
- package/build/esm/blocks/Map/schema.d.ts +3 -0
- package/build/esm/blocks/Media/schema.d.ts +6 -0
- package/build/esm/blocks/Media/schema.js +2 -0
- package/build/esm/components/MediaBase/MediaBase.css +3 -0
- package/build/esm/components/MediaBase/MediaBase.js +2 -2
- package/build/esm/models/constructor-items/blocks.d.ts +3 -0
- package/package.json +1 -1
- package/schema/index.js +1 -1
- package/server/models/constructor-items/blocks.d.ts +3 -0
- package/widget/index.js +1 -1
|
@@ -10,8 +10,18 @@ const grid_1 = require("../../grid");
|
|
|
10
10
|
const utils_1 = require("../../utils");
|
|
11
11
|
const Item_1 = tslib_1.__importDefault(require("./Item"));
|
|
12
12
|
const b = (0, utils_1.block)('logo-rotator-block');
|
|
13
|
+
const DEFAULT_MIN_ROTATE_COUNT = 2;
|
|
14
|
+
const DEFAULT_MAX_ROTATE_COUNT = 4;
|
|
15
|
+
const pickRandomSlots = (slotIndices, count) => {
|
|
16
|
+
const shuffled = [...slotIndices];
|
|
17
|
+
for (let i = shuffled.length - 1; i > 0; i--) {
|
|
18
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
19
|
+
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
|
20
|
+
}
|
|
21
|
+
return shuffled.slice(0, count);
|
|
22
|
+
};
|
|
13
23
|
const LogoRotatorBlock = (props) => {
|
|
14
|
-
const { animated, title, theme, items, count, colSizes, rowMode } = props;
|
|
24
|
+
const { animated, title, theme, items, count, minRotateCount = DEFAULT_MIN_ROTATE_COUNT, maxRotateCount = DEFAULT_MAX_ROTATE_COUNT, colSizes, rowMode, } = props;
|
|
15
25
|
// Индексы логотипов, которые участвуют в ротации (не статичные)
|
|
16
26
|
const rotatableIndices = (0, react_1.useMemo)(() => items.map((item, i) => (item.isStatic ? -1 : i)).filter((i) => i !== -1), [items]);
|
|
17
27
|
// Инициализация слотов: статичные вставляются в начало, остальные по порядку
|
|
@@ -37,6 +47,7 @@ const LogoRotatorBlock = (props) => {
|
|
|
37
47
|
});
|
|
38
48
|
const [hidden, setHidden] = (0, react_1.useState)(() => Array(count).fill(false));
|
|
39
49
|
const nextIndexRef = (0, react_1.useRef)(count - 1);
|
|
50
|
+
const isHoveredRef = (0, react_1.useRef)(false);
|
|
40
51
|
// Держим актуальные slots в ref, чтобы не пересоздавать интервал при каждом изменении
|
|
41
52
|
const slotsRef = (0, react_1.useRef)(slots);
|
|
42
53
|
(0, react_1.useEffect)(() => {
|
|
@@ -45,33 +56,44 @@ const LogoRotatorBlock = (props) => {
|
|
|
45
56
|
(0, react_1.useEffect)(() => {
|
|
46
57
|
let timeout = null;
|
|
47
58
|
const interval = setInterval(() => {
|
|
59
|
+
if (isHoveredRef.current)
|
|
60
|
+
return;
|
|
48
61
|
// Выбираем только не-статичные слоты для замены
|
|
49
62
|
const rotatableSlotIndices = slotsRef.current
|
|
50
63
|
.map((itemIdx, slotIdx) => { var _a; return (((_a = items[itemIdx]) === null || _a === void 0 ? void 0 : _a.isStatic) ? -1 : slotIdx); })
|
|
51
64
|
.filter((i) => i !== -1);
|
|
52
65
|
if (rotatableSlotIndices.length === 0)
|
|
53
66
|
return;
|
|
54
|
-
const
|
|
67
|
+
const rotateMin = Math.min(minRotateCount, maxRotateCount);
|
|
68
|
+
const rotateMax = Math.max(minRotateCount, maxRotateCount);
|
|
69
|
+
const rotateCount = rotateMin + Math.floor(Math.random() * (rotateMax - rotateMin + 1));
|
|
70
|
+
const slotIndices = pickRandomSlots(rotatableSlotIndices, Math.min(rotateCount, rotatableSlotIndices.length));
|
|
55
71
|
setHidden((prev) => {
|
|
56
72
|
const next = [...prev];
|
|
57
|
-
|
|
73
|
+
slotIndices.forEach((slotIndex) => {
|
|
74
|
+
next[slotIndex] = true;
|
|
75
|
+
});
|
|
58
76
|
return next;
|
|
59
77
|
});
|
|
60
78
|
timeout = setTimeout(() => {
|
|
61
79
|
setSlots((prevSlots) => {
|
|
62
80
|
const newSlots = [...prevSlots];
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
81
|
+
let available = rotatableIndices.filter((i) => !newSlots.includes(i));
|
|
82
|
+
slotIndices.forEach((slotIndex) => {
|
|
83
|
+
if (available.length === 0)
|
|
84
|
+
return;
|
|
66
85
|
const newValue = available[nextIndexRef.current % available.length];
|
|
67
86
|
nextIndexRef.current++;
|
|
68
87
|
newSlots[slotIndex] = newValue;
|
|
69
|
-
|
|
88
|
+
available = available.filter((i) => i !== newValue);
|
|
89
|
+
});
|
|
70
90
|
return newSlots;
|
|
71
91
|
});
|
|
72
92
|
setHidden((prev) => {
|
|
73
93
|
const next = [...prev];
|
|
74
|
-
|
|
94
|
+
slotIndices.forEach((slotIndex) => {
|
|
95
|
+
next[slotIndex] = false;
|
|
96
|
+
});
|
|
75
97
|
return next;
|
|
76
98
|
});
|
|
77
99
|
}, 500);
|
|
@@ -82,14 +104,18 @@ const LogoRotatorBlock = (props) => {
|
|
|
82
104
|
clearTimeout(timeout);
|
|
83
105
|
}
|
|
84
106
|
};
|
|
85
|
-
}, [count, items, rotatableIndices]);
|
|
107
|
+
}, [count, items, maxRotateCount, minRotateCount, rotatableIndices]);
|
|
86
108
|
const renderItems = (0, react_1.useMemo)(() => slots.map((slot, index) => (react_1.default.createElement(Item_1.default, { key: index, colSizes: colSizes, url: items[slot].url, src: items[slot].src, hidden: hidden[index] }))), [colSizes, hidden, items, slots]);
|
|
87
109
|
const titleProps = !title || typeof title === 'string'
|
|
88
110
|
? { text: title, textSize: 'l' }
|
|
89
111
|
: title;
|
|
90
112
|
const hasTitle = Boolean(title);
|
|
91
113
|
return (react_1.default.createElement(AnimateBlock_1.default, { className: b({ theme }), animate: animated },
|
|
92
|
-
react_1.default.createElement("div", { className: b('root')
|
|
114
|
+
react_1.default.createElement("div", { className: b('root'), onMouseEnter: () => {
|
|
115
|
+
isHoveredRef.current = true;
|
|
116
|
+
}, onMouseLeave: () => {
|
|
117
|
+
isHoveredRef.current = false;
|
|
118
|
+
} },
|
|
93
119
|
hasTitle && (react_1.default.createElement(components_1.Title, { title: titleProps, className: b('title'), colSizes: { all: 12 } })),
|
|
94
120
|
rowMode ? (react_1.default.createElement("div", { className: b('row-items') }, slots.map((slot, index) => {
|
|
95
121
|
const item = items[slot];
|
|
@@ -330,6 +330,9 @@ export declare const MediaBlockBaseProps: {
|
|
|
330
330
|
mediaOnly: {
|
|
331
331
|
type: string;
|
|
332
332
|
};
|
|
333
|
+
imageWidthAuto: {
|
|
334
|
+
type: string;
|
|
335
|
+
};
|
|
333
336
|
/**
|
|
334
337
|
* @deprecated use border='none' or border='line' instead
|
|
335
338
|
*/
|
|
@@ -1211,6 +1214,9 @@ export declare const MediaBlock: {
|
|
|
1211
1214
|
mediaOnly: {
|
|
1212
1215
|
type: string;
|
|
1213
1216
|
};
|
|
1217
|
+
imageWidthAuto: {
|
|
1218
|
+
type: string;
|
|
1219
|
+
};
|
|
1214
1220
|
/**
|
|
1215
1221
|
* @deprecated use border='none' or border='line' instead
|
|
1216
1222
|
*/
|
|
@@ -11,7 +11,7 @@ const MediaBaseContent_1 = tslib_1.__importDefault(require("./MediaBaseContent")
|
|
|
11
11
|
const b = (0, utils_1.block)('media-base');
|
|
12
12
|
const Card = () => null;
|
|
13
13
|
const MediaBase = (props) => {
|
|
14
|
-
const { children, largeMedia, smallMedia, direction = 'content-media', mobileDirection = 'content-media', animated, mediaOnly, onScroll, mediaOnlyColSizes = { all: 12, md: 8 } } = props, mediaContentProps = tslib_1.__rest(props, ["children", "largeMedia", "smallMedia", "direction", "mobileDirection", "animated", "mediaOnly", "onScroll", "mediaOnlyColSizes"]);
|
|
14
|
+
const { children, largeMedia, smallMedia, direction = 'content-media', mobileDirection = 'content-media', animated, mediaOnly, imageWidthAuto, onScroll, mediaOnlyColSizes = { all: 12, md: 8 } } = props, mediaContentProps = tslib_1.__rest(props, ["children", "largeMedia", "smallMedia", "direction", "mobileDirection", "animated", "mediaOnly", "imageWidthAuto", "onScroll", "mediaOnlyColSizes"]);
|
|
15
15
|
const { title, description } = mediaContentProps;
|
|
16
16
|
const mediaSizes = (0, react_1.useMemo)(() => {
|
|
17
17
|
let md = 6;
|
|
@@ -47,7 +47,7 @@ const MediaBase = (props) => {
|
|
|
47
47
|
}) },
|
|
48
48
|
react_1.default.createElement(grid_1.Col, { className: b('content'), sizes: contentSizes }, mediaContent),
|
|
49
49
|
card ? (react_1.default.createElement(grid_1.Col, { sizes: mediaSizes },
|
|
50
|
-
react_1.default.createElement("div", { className: b('card') }, card))) : null)))));
|
|
50
|
+
react_1.default.createElement("div", { className: b('card', { imageWidthAuto }) }, card))) : null)))));
|
|
51
51
|
};
|
|
52
52
|
exports.MediaBase = MediaBase;
|
|
53
53
|
exports.MediaBase.Card = Card;
|
|
@@ -303,6 +303,8 @@ export interface LogoRotatorBlockProps extends Animatable {
|
|
|
303
303
|
isStatic?: boolean;
|
|
304
304
|
}[];
|
|
305
305
|
count: number;
|
|
306
|
+
minRotateCount?: number;
|
|
307
|
+
maxRotateCount?: number;
|
|
306
308
|
colSizes?: Partial<Record<GridColumnSize, number>>;
|
|
307
309
|
theme?: TextTheme;
|
|
308
310
|
rowMode?: boolean;
|
|
@@ -376,6 +378,7 @@ export interface MediaBaseBlockProps extends Animatable, MediaContentProps {
|
|
|
376
378
|
largeMedia?: boolean;
|
|
377
379
|
smallMedia?: boolean;
|
|
378
380
|
mediaOnly?: boolean;
|
|
381
|
+
imageWidthAuto?: boolean;
|
|
379
382
|
mediaOnlyColSizes?: GridColumnSizesType;
|
|
380
383
|
}
|
|
381
384
|
export interface MediaContentProps extends Omit<ContentBlockProps, 'colSizes' | 'text' | 'title' | 'theme' | 'centered'> {
|
|
@@ -7,8 +7,18 @@ import { block } from '../../utils';
|
|
|
7
7
|
import Item from './Item';
|
|
8
8
|
import './LogoRotator.css';
|
|
9
9
|
const b = block('logo-rotator-block');
|
|
10
|
+
const DEFAULT_MIN_ROTATE_COUNT = 2;
|
|
11
|
+
const DEFAULT_MAX_ROTATE_COUNT = 4;
|
|
12
|
+
const pickRandomSlots = (slotIndices, count) => {
|
|
13
|
+
const shuffled = [...slotIndices];
|
|
14
|
+
for (let i = shuffled.length - 1; i > 0; i--) {
|
|
15
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
16
|
+
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
|
17
|
+
}
|
|
18
|
+
return shuffled.slice(0, count);
|
|
19
|
+
};
|
|
10
20
|
export const LogoRotatorBlock = (props) => {
|
|
11
|
-
const { animated, title, theme, items, count, colSizes, rowMode } = props;
|
|
21
|
+
const { animated, title, theme, items, count, minRotateCount = DEFAULT_MIN_ROTATE_COUNT, maxRotateCount = DEFAULT_MAX_ROTATE_COUNT, colSizes, rowMode, } = props;
|
|
12
22
|
// Индексы логотипов, которые участвуют в ротации (не статичные)
|
|
13
23
|
const rotatableIndices = useMemo(() => items.map((item, i) => (item.isStatic ? -1 : i)).filter((i) => i !== -1), [items]);
|
|
14
24
|
// Инициализация слотов: статичные вставляются в начало, остальные по порядку
|
|
@@ -34,6 +44,7 @@ export const LogoRotatorBlock = (props) => {
|
|
|
34
44
|
});
|
|
35
45
|
const [hidden, setHidden] = useState(() => Array(count).fill(false));
|
|
36
46
|
const nextIndexRef = useRef(count - 1);
|
|
47
|
+
const isHoveredRef = useRef(false);
|
|
37
48
|
// Держим актуальные slots в ref, чтобы не пересоздавать интервал при каждом изменении
|
|
38
49
|
const slotsRef = useRef(slots);
|
|
39
50
|
useEffect(() => {
|
|
@@ -42,33 +53,44 @@ export const LogoRotatorBlock = (props) => {
|
|
|
42
53
|
useEffect(() => {
|
|
43
54
|
let timeout = null;
|
|
44
55
|
const interval = setInterval(() => {
|
|
56
|
+
if (isHoveredRef.current)
|
|
57
|
+
return;
|
|
45
58
|
// Выбираем только не-статичные слоты для замены
|
|
46
59
|
const rotatableSlotIndices = slotsRef.current
|
|
47
60
|
.map((itemIdx, slotIdx) => { var _a; return (((_a = items[itemIdx]) === null || _a === void 0 ? void 0 : _a.isStatic) ? -1 : slotIdx); })
|
|
48
61
|
.filter((i) => i !== -1);
|
|
49
62
|
if (rotatableSlotIndices.length === 0)
|
|
50
63
|
return;
|
|
51
|
-
const
|
|
64
|
+
const rotateMin = Math.min(minRotateCount, maxRotateCount);
|
|
65
|
+
const rotateMax = Math.max(minRotateCount, maxRotateCount);
|
|
66
|
+
const rotateCount = rotateMin + Math.floor(Math.random() * (rotateMax - rotateMin + 1));
|
|
67
|
+
const slotIndices = pickRandomSlots(rotatableSlotIndices, Math.min(rotateCount, rotatableSlotIndices.length));
|
|
52
68
|
setHidden((prev) => {
|
|
53
69
|
const next = [...prev];
|
|
54
|
-
|
|
70
|
+
slotIndices.forEach((slotIndex) => {
|
|
71
|
+
next[slotIndex] = true;
|
|
72
|
+
});
|
|
55
73
|
return next;
|
|
56
74
|
});
|
|
57
75
|
timeout = setTimeout(() => {
|
|
58
76
|
setSlots((prevSlots) => {
|
|
59
77
|
const newSlots = [...prevSlots];
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
78
|
+
let available = rotatableIndices.filter((i) => !newSlots.includes(i));
|
|
79
|
+
slotIndices.forEach((slotIndex) => {
|
|
80
|
+
if (available.length === 0)
|
|
81
|
+
return;
|
|
63
82
|
const newValue = available[nextIndexRef.current % available.length];
|
|
64
83
|
nextIndexRef.current++;
|
|
65
84
|
newSlots[slotIndex] = newValue;
|
|
66
|
-
|
|
85
|
+
available = available.filter((i) => i !== newValue);
|
|
86
|
+
});
|
|
67
87
|
return newSlots;
|
|
68
88
|
});
|
|
69
89
|
setHidden((prev) => {
|
|
70
90
|
const next = [...prev];
|
|
71
|
-
|
|
91
|
+
slotIndices.forEach((slotIndex) => {
|
|
92
|
+
next[slotIndex] = false;
|
|
93
|
+
});
|
|
72
94
|
return next;
|
|
73
95
|
});
|
|
74
96
|
}, 500);
|
|
@@ -79,14 +101,18 @@ export const LogoRotatorBlock = (props) => {
|
|
|
79
101
|
clearTimeout(timeout);
|
|
80
102
|
}
|
|
81
103
|
};
|
|
82
|
-
}, [count, items, rotatableIndices]);
|
|
104
|
+
}, [count, items, maxRotateCount, minRotateCount, rotatableIndices]);
|
|
83
105
|
const renderItems = useMemo(() => slots.map((slot, index) => (React.createElement(Item, { key: index, colSizes: colSizes, url: items[slot].url, src: items[slot].src, hidden: hidden[index] }))), [colSizes, hidden, items, slots]);
|
|
84
106
|
const titleProps = !title || typeof title === 'string'
|
|
85
107
|
? { text: title, textSize: 'l' }
|
|
86
108
|
: title;
|
|
87
109
|
const hasTitle = Boolean(title);
|
|
88
110
|
return (React.createElement(AnimateBlock, { className: b({ theme }), animate: animated },
|
|
89
|
-
React.createElement("div", { className: b('root')
|
|
111
|
+
React.createElement("div", { className: b('root'), onMouseEnter: () => {
|
|
112
|
+
isHoveredRef.current = true;
|
|
113
|
+
}, onMouseLeave: () => {
|
|
114
|
+
isHoveredRef.current = false;
|
|
115
|
+
} },
|
|
90
116
|
hasTitle && (React.createElement(Title, { title: titleProps, className: b('title'), colSizes: { all: 12 } })),
|
|
91
117
|
rowMode ? (React.createElement("div", { className: b('row-items') }, slots.map((slot, index) => {
|
|
92
118
|
const item = items[slot];
|
|
@@ -330,6 +330,9 @@ export declare const MediaBlockBaseProps: {
|
|
|
330
330
|
mediaOnly: {
|
|
331
331
|
type: string;
|
|
332
332
|
};
|
|
333
|
+
imageWidthAuto: {
|
|
334
|
+
type: string;
|
|
335
|
+
};
|
|
333
336
|
/**
|
|
334
337
|
* @deprecated use border='none' or border='line' instead
|
|
335
338
|
*/
|
|
@@ -1211,6 +1214,9 @@ export declare const MediaBlock: {
|
|
|
1211
1214
|
mediaOnly: {
|
|
1212
1215
|
type: string;
|
|
1213
1216
|
};
|
|
1217
|
+
imageWidthAuto: {
|
|
1218
|
+
type: string;
|
|
1219
|
+
};
|
|
1214
1220
|
/**
|
|
1215
1221
|
* @deprecated use border='none' or border='line' instead
|
|
1216
1222
|
*/
|
|
@@ -9,7 +9,7 @@ import './MediaBase.css';
|
|
|
9
9
|
const b = block('media-base');
|
|
10
10
|
const Card = () => null;
|
|
11
11
|
export const MediaBase = (props) => {
|
|
12
|
-
const { children, largeMedia, smallMedia, direction = 'content-media', mobileDirection = 'content-media', animated, mediaOnly, onScroll, mediaOnlyColSizes = { all: 12, md: 8 } } = props, mediaContentProps = __rest(props, ["children", "largeMedia", "smallMedia", "direction", "mobileDirection", "animated", "mediaOnly", "onScroll", "mediaOnlyColSizes"]);
|
|
12
|
+
const { children, largeMedia, smallMedia, direction = 'content-media', mobileDirection = 'content-media', animated, mediaOnly, imageWidthAuto, onScroll, mediaOnlyColSizes = { all: 12, md: 8 } } = props, mediaContentProps = __rest(props, ["children", "largeMedia", "smallMedia", "direction", "mobileDirection", "animated", "mediaOnly", "imageWidthAuto", "onScroll", "mediaOnlyColSizes"]);
|
|
13
13
|
const { title, description } = mediaContentProps;
|
|
14
14
|
const mediaSizes = useMemo(() => {
|
|
15
15
|
let md = 6;
|
|
@@ -45,7 +45,7 @@ export const MediaBase = (props) => {
|
|
|
45
45
|
}) },
|
|
46
46
|
React.createElement(Col, { className: b('content'), sizes: contentSizes }, mediaContent),
|
|
47
47
|
card ? (React.createElement(Col, { sizes: mediaSizes },
|
|
48
|
-
React.createElement("div", { className: b('card') }, card))) : null)))));
|
|
48
|
+
React.createElement("div", { className: b('card', { imageWidthAuto }) }, card))) : null)))));
|
|
49
49
|
};
|
|
50
50
|
MediaBase.Card = Card;
|
|
51
51
|
export default MediaBase;
|
|
@@ -303,6 +303,8 @@ export interface LogoRotatorBlockProps extends Animatable {
|
|
|
303
303
|
isStatic?: boolean;
|
|
304
304
|
}[];
|
|
305
305
|
count: number;
|
|
306
|
+
minRotateCount?: number;
|
|
307
|
+
maxRotateCount?: number;
|
|
306
308
|
colSizes?: Partial<Record<GridColumnSize, number>>;
|
|
307
309
|
theme?: TextTheme;
|
|
308
310
|
rowMode?: boolean;
|
|
@@ -376,6 +378,7 @@ export interface MediaBaseBlockProps extends Animatable, MediaContentProps {
|
|
|
376
378
|
largeMedia?: boolean;
|
|
377
379
|
smallMedia?: boolean;
|
|
378
380
|
mediaOnly?: boolean;
|
|
381
|
+
imageWidthAuto?: boolean;
|
|
379
382
|
mediaOnlyColSizes?: GridColumnSizesType;
|
|
380
383
|
}
|
|
381
384
|
export interface MediaContentProps extends Omit<ContentBlockProps, 'colSizes' | 'text' | 'title' | 'theme' | 'centered'> {
|