@doyourjob/gravity-ui-page-constructor 5.31.253 → 5.31.256
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/Item.d.ts +8 -3
- package/build/cjs/blocks/LogoRotator/Item.js +14 -9
- package/build/cjs/blocks/LogoRotator/LogoRotator.css +78 -9
- package/build/cjs/blocks/LogoRotator/LogoRotator.js +105 -59
- package/build/cjs/blocks/LogoRotator/schema.d.ts +8 -1
- package/build/cjs/blocks/LogoRotator/schema.js +7 -2
- package/build/cjs/blocks/LogoRotator/utils.d.ts +7 -0
- package/build/cjs/blocks/LogoRotator/utils.js +36 -0
- package/build/cjs/models/constructor-items/blocks.d.ts +3 -1
- package/build/esm/blocks/LogoRotator/Item.d.ts +8 -3
- package/build/esm/blocks/LogoRotator/Item.js +14 -9
- package/build/esm/blocks/LogoRotator/LogoRotator.css +78 -9
- package/build/esm/blocks/LogoRotator/LogoRotator.js +106 -60
- package/build/esm/blocks/LogoRotator/schema.d.ts +8 -1
- package/build/esm/blocks/LogoRotator/schema.js +7 -2
- package/build/esm/blocks/LogoRotator/utils.d.ts +7 -0
- package/build/esm/blocks/LogoRotator/utils.js +31 -0
- package/build/esm/models/constructor-items/blocks.d.ts +3 -1
- package/package.json +1 -1
- package/schema/index.js +1 -1
- package/server/models/constructor-items/blocks.d.ts +3 -1
- package/widget/index.js +1 -1
|
@@ -30,19 +30,44 @@ unpredictable css rules order in build */
|
|
|
30
30
|
gap: 16px;
|
|
31
31
|
}
|
|
32
32
|
.pc-logo-rotator-block__item {
|
|
33
|
+
position: relative;
|
|
33
34
|
display: block;
|
|
34
35
|
height: 100px;
|
|
35
|
-
|
|
36
|
-
opacity: 1;
|
|
37
|
-
}
|
|
38
|
-
.pc-logo-rotator-block__item_hidden {
|
|
39
|
-
opacity: 0;
|
|
36
|
+
overflow: hidden;
|
|
40
37
|
}
|
|
41
38
|
@media (max-width: 769px) {
|
|
42
39
|
.pc-logo-rotator-block__item {
|
|
43
40
|
height: 80px;
|
|
44
41
|
}
|
|
45
42
|
}
|
|
43
|
+
.pc-logo-rotator-block__item-link, .pc-logo-rotator-block__row-item-link {
|
|
44
|
+
display: block;
|
|
45
|
+
height: 100%;
|
|
46
|
+
}
|
|
47
|
+
.pc-logo-rotator-block__logo-layer {
|
|
48
|
+
display: block;
|
|
49
|
+
width: 100%;
|
|
50
|
+
height: 100%;
|
|
51
|
+
}
|
|
52
|
+
.pc-logo-rotator-block__item_swapping .pc-logo-rotator-block__logo-layer, .pc-logo-rotator-block__row-item_swapping .pc-logo-rotator-block__logo-layer {
|
|
53
|
+
position: absolute;
|
|
54
|
+
inset: 0;
|
|
55
|
+
}
|
|
56
|
+
.pc-logo-rotator-block__logo-layer_from {
|
|
57
|
+
pointer-events: none;
|
|
58
|
+
}
|
|
59
|
+
.pc-logo-rotator-block__logo-layer_fade-from {
|
|
60
|
+
animation: logo-rotator-fade-out 0.5s ease 0.1s both;
|
|
61
|
+
}
|
|
62
|
+
.pc-logo-rotator-block__logo-layer_fade-to {
|
|
63
|
+
animation: logo-rotator-fade-in 0.5s ease 0.6s both;
|
|
64
|
+
}
|
|
65
|
+
.pc-logo-rotator-block__logo-layer_morph-from {
|
|
66
|
+
animation: logo-rotator-morph-out 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
67
|
+
}
|
|
68
|
+
.pc-logo-rotator-block__logo-layer_morph-to {
|
|
69
|
+
animation: logo-rotator-morph-in 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
70
|
+
}
|
|
46
71
|
.pc-logo-rotator-block__image {
|
|
47
72
|
display: block;
|
|
48
73
|
width: 100%;
|
|
@@ -57,13 +82,57 @@ unpredictable css rules order in build */
|
|
|
57
82
|
gap: 46px 16px;
|
|
58
83
|
}
|
|
59
84
|
.pc-logo-rotator-block__row-item {
|
|
85
|
+
position: relative;
|
|
60
86
|
display: block;
|
|
61
87
|
height: 36px;
|
|
62
88
|
min-width: 160px;
|
|
63
89
|
flex: 1;
|
|
64
|
-
|
|
65
|
-
opacity: 1;
|
|
90
|
+
overflow: hidden;
|
|
66
91
|
}
|
|
67
|
-
|
|
68
|
-
|
|
92
|
+
|
|
93
|
+
@keyframes logo-rotator-fade-out {
|
|
94
|
+
from {
|
|
95
|
+
opacity: 1;
|
|
96
|
+
}
|
|
97
|
+
to {
|
|
98
|
+
opacity: 0;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
@keyframes logo-rotator-fade-in {
|
|
102
|
+
from {
|
|
103
|
+
opacity: 0;
|
|
104
|
+
}
|
|
105
|
+
to {
|
|
106
|
+
opacity: 1;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
@keyframes logo-rotator-morph-out {
|
|
110
|
+
from {
|
|
111
|
+
clip-path: inset(0 0 0 0);
|
|
112
|
+
transform: translateX(0) scaleX(1);
|
|
113
|
+
opacity: 1;
|
|
114
|
+
}
|
|
115
|
+
to {
|
|
116
|
+
clip-path: inset(0 100% 0 0);
|
|
117
|
+
transform: translateX(-8%) scaleX(0.9);
|
|
118
|
+
opacity: 0;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
@keyframes logo-rotator-morph-in {
|
|
122
|
+
from {
|
|
123
|
+
clip-path: inset(0 0 0 100%);
|
|
124
|
+
transform: translateX(8%) scaleX(0.9);
|
|
125
|
+
opacity: 0;
|
|
126
|
+
}
|
|
127
|
+
to {
|
|
128
|
+
clip-path: inset(0 0 0 0);
|
|
129
|
+
transform: translateX(0) scaleX(1);
|
|
130
|
+
opacity: 1;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
@media (prefers-reduced-motion: reduce) {
|
|
134
|
+
.pc-logo-rotator-block__logo-layer_fade-from, .pc-logo-rotator-block__logo-layer_fade-to, .pc-logo-rotator-block__logo-layer_morph-from, .pc-logo-rotator-block__logo-layer_morph-to {
|
|
135
|
+
animation-duration: 1ms;
|
|
136
|
+
animation-delay: 0ms;
|
|
137
|
+
}
|
|
69
138
|
}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import { Link } from '@gravity-ui/uikit';
|
|
3
3
|
import { ImageBase, Title } from '../../components';
|
|
4
4
|
import AnimateBlock from '../../components/AnimateBlock/AnimateBlock';
|
|
5
|
+
import { BREAKPOINTS } from '../../constants';
|
|
5
6
|
import { Grid, Row } from '../../grid';
|
|
7
|
+
import useWindowBreakpoint from '../../hooks/useWindowBreakpoint';
|
|
6
8
|
import { block } from '../../utils';
|
|
7
9
|
import Item from './Item';
|
|
10
|
+
import { DEFAULT_SWAP_ANIMATION, SWAP_ANIMATION_DURATIONS, getInitialSlots, getLayerModifiers, } from './utils';
|
|
8
11
|
import './LogoRotator.css';
|
|
9
12
|
const b = block('logo-rotator-block');
|
|
10
13
|
const DEFAULT_MIN_ROTATE_COUNT = 2;
|
|
11
14
|
const DEFAULT_MAX_ROTATE_COUNT = 4;
|
|
15
|
+
const emptyTransitions = (count) => Array(count).fill(undefined);
|
|
12
16
|
const pickRandomSlots = (slotIndices, count) => {
|
|
13
17
|
const shuffled = [...slotIndices];
|
|
14
18
|
for (let i = shuffled.length - 1; i > 0; i--) {
|
|
@@ -18,46 +22,47 @@ const pickRandomSlots = (slotIndices, count) => {
|
|
|
18
22
|
return shuffled.slice(0, count);
|
|
19
23
|
};
|
|
20
24
|
export const LogoRotatorBlock = (props) => {
|
|
21
|
-
const { animated, title, theme, items,
|
|
25
|
+
const { animated, title, theme, items, countMobile, countDesktop, minRotateCount = DEFAULT_MIN_ROTATE_COUNT, maxRotateCount = DEFAULT_MAX_ROTATE_COUNT, swapAnimation = DEFAULT_SWAP_ANIMATION, colSizes, rowMode, } = props;
|
|
26
|
+
const breakpoint = useWindowBreakpoint();
|
|
27
|
+
const activeCount = countDesktop !== undefined && breakpoint >= BREAKPOINTS.md ? countDesktop : countMobile;
|
|
22
28
|
// Индексы логотипов, которые участвуют в ротации (не статичные)
|
|
23
29
|
const rotatableIndices = useMemo(() => items.map((item, i) => (item.isStatic ? -1 : i)).filter((i) => i !== -1), [items]);
|
|
24
30
|
// Инициализация слотов: статичные вставляются в начало, остальные по порядку
|
|
25
|
-
const [slots, setSlots] = useState(() =>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
.filter((i) => i !== -1);
|
|
30
|
-
const rotatableIdxList = items
|
|
31
|
-
.map((item, i) => (item.isStatic ? -1 : i))
|
|
32
|
-
.filter((i) => i !== -1);
|
|
33
|
-
const initial = [];
|
|
34
|
-
let rotatablePointer = 0;
|
|
35
|
-
for (let slot = 0; slot < count; slot++) {
|
|
36
|
-
if (slot < staticIdxList.length) {
|
|
37
|
-
initial.push(staticIdxList[slot]);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
initial.push((_a = rotatableIdxList[rotatablePointer++]) !== null && _a !== void 0 ? _a : 0);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return initial;
|
|
44
|
-
});
|
|
45
|
-
const [hidden, setHidden] = useState(() => Array(count).fill(false));
|
|
46
|
-
const nextIndexRef = useRef(count - 1);
|
|
47
|
-
const isHoveredRef = useRef(false);
|
|
31
|
+
const [slots, setSlots] = useState(() => getInitialSlots(items, activeCount));
|
|
32
|
+
const [transitions, setTransitions] = useState(() => emptyTransitions(activeCount));
|
|
33
|
+
const nextIndexRef = useRef(activeCount - 1);
|
|
34
|
+
const hoveredSlotIndicesRef = useRef(new Set());
|
|
48
35
|
// Держим актуальные slots в ref, чтобы не пересоздавать интервал при каждом изменении
|
|
49
36
|
const slotsRef = useRef(slots);
|
|
50
37
|
useEffect(() => {
|
|
51
38
|
slotsRef.current = slots;
|
|
52
39
|
}, [slots]);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
const initialSlots = getInitialSlots(items, activeCount);
|
|
42
|
+
slotsRef.current = initialSlots;
|
|
43
|
+
setSlots(initialSlots);
|
|
44
|
+
setTransitions(emptyTransitions(activeCount));
|
|
45
|
+
nextIndexRef.current = activeCount - 1;
|
|
46
|
+
hoveredSlotIndicesRef.current.clear();
|
|
47
|
+
}, [activeCount, items]);
|
|
48
|
+
const handleSlotMouseEnter = useCallback((slotIndex) => {
|
|
49
|
+
hoveredSlotIndicesRef.current.add(slotIndex);
|
|
50
|
+
}, []);
|
|
51
|
+
const handleSlotMouseLeave = useCallback((slotIndex) => {
|
|
52
|
+
hoveredSlotIndicesRef.current.delete(slotIndex);
|
|
53
|
+
}, []);
|
|
53
54
|
useEffect(() => {
|
|
54
55
|
let timeout = null;
|
|
55
56
|
const interval = setInterval(() => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
const currentSlots = slotsRef.current;
|
|
58
|
+
// Выбираем только не-статичные слоты, на которые не наведен указатель
|
|
59
|
+
const rotatableSlotIndices = currentSlots
|
|
60
|
+
.map((itemIdx, slotIdx) => {
|
|
61
|
+
var _a;
|
|
62
|
+
return ((_a = items[itemIdx]) === null || _a === void 0 ? void 0 : _a.isStatic) || hoveredSlotIndicesRef.current.has(slotIdx)
|
|
63
|
+
? -1
|
|
64
|
+
: slotIdx;
|
|
65
|
+
})
|
|
61
66
|
.filter((i) => i !== -1);
|
|
62
67
|
if (rotatableSlotIndices.length === 0)
|
|
63
68
|
return;
|
|
@@ -65,35 +70,56 @@ export const LogoRotatorBlock = (props) => {
|
|
|
65
70
|
const rotateMax = Math.max(minRotateCount, maxRotateCount);
|
|
66
71
|
const rotateCount = rotateMin + Math.floor(Math.random() * (rotateMax - rotateMin + 1));
|
|
67
72
|
const slotIndices = pickRandomSlots(rotatableSlotIndices, Math.min(rotateCount, rotatableSlotIndices.length));
|
|
68
|
-
|
|
73
|
+
let available = rotatableIndices.filter((i) => !currentSlots.includes(i));
|
|
74
|
+
const blockedTargetSrcs = new Set();
|
|
75
|
+
const nextTransitions = [];
|
|
76
|
+
slotIndices.forEach((slotIndex) => {
|
|
77
|
+
var _a, _b;
|
|
78
|
+
if (available.length === 0)
|
|
79
|
+
return;
|
|
80
|
+
const currentItemIndex = currentSlots[slotIndex];
|
|
81
|
+
const currentSrc = (_a = items[currentItemIndex]) === null || _a === void 0 ? void 0 : _a.src;
|
|
82
|
+
const slotAvailable = available.filter((i) => {
|
|
83
|
+
var _a;
|
|
84
|
+
const src = (_a = items[i]) === null || _a === void 0 ? void 0 : _a.src;
|
|
85
|
+
return src !== currentSrc && !blockedTargetSrcs.has(src);
|
|
86
|
+
});
|
|
87
|
+
if (slotAvailable.length === 0)
|
|
88
|
+
return;
|
|
89
|
+
const newValue = slotAvailable[nextIndexRef.current % slotAvailable.length];
|
|
90
|
+
nextIndexRef.current++;
|
|
91
|
+
available = available.filter((i) => i !== newValue);
|
|
92
|
+
const newSrc = (_b = items[newValue]) === null || _b === void 0 ? void 0 : _b.src;
|
|
93
|
+
if (newSrc) {
|
|
94
|
+
blockedTargetSrcs.add(newSrc);
|
|
95
|
+
}
|
|
96
|
+
nextTransitions.push({ slotIndex, from: currentItemIndex, to: newValue });
|
|
97
|
+
});
|
|
98
|
+
if (nextTransitions.length === 0)
|
|
99
|
+
return;
|
|
100
|
+
setTransitions((prev) => {
|
|
69
101
|
const next = [...prev];
|
|
70
|
-
|
|
71
|
-
next[slotIndex] =
|
|
102
|
+
nextTransitions.forEach(({ slotIndex, from, to }) => {
|
|
103
|
+
next[slotIndex] = { from, to };
|
|
72
104
|
});
|
|
73
105
|
return next;
|
|
74
106
|
});
|
|
75
107
|
timeout = setTimeout(() => {
|
|
76
108
|
setSlots((prevSlots) => {
|
|
77
109
|
const newSlots = [...prevSlots];
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (available.length === 0)
|
|
81
|
-
return;
|
|
82
|
-
const newValue = available[nextIndexRef.current % available.length];
|
|
83
|
-
nextIndexRef.current++;
|
|
84
|
-
newSlots[slotIndex] = newValue;
|
|
85
|
-
available = available.filter((i) => i !== newValue);
|
|
110
|
+
nextTransitions.forEach(({ slotIndex, to }) => {
|
|
111
|
+
newSlots[slotIndex] = to;
|
|
86
112
|
});
|
|
87
113
|
return newSlots;
|
|
88
114
|
});
|
|
89
|
-
|
|
115
|
+
setTransitions((prev) => {
|
|
90
116
|
const next = [...prev];
|
|
91
|
-
|
|
92
|
-
next[slotIndex] =
|
|
117
|
+
nextTransitions.forEach(({ slotIndex }) => {
|
|
118
|
+
next[slotIndex] = undefined;
|
|
93
119
|
});
|
|
94
120
|
return next;
|
|
95
121
|
});
|
|
96
|
-
},
|
|
122
|
+
}, SWAP_ANIMATION_DURATIONS[swapAnimation]);
|
|
97
123
|
}, 2000);
|
|
98
124
|
return () => {
|
|
99
125
|
clearInterval(interval);
|
|
@@ -101,29 +127,49 @@ export const LogoRotatorBlock = (props) => {
|
|
|
101
127
|
clearTimeout(timeout);
|
|
102
128
|
}
|
|
103
129
|
};
|
|
104
|
-
}, [
|
|
105
|
-
const renderItems = useMemo(() => slots.map((slot, index) =>
|
|
130
|
+
}, [activeCount, items, maxRotateCount, minRotateCount, rotatableIndices, swapAnimation]);
|
|
131
|
+
const renderItems = useMemo(() => slots.map((slot, index) => {
|
|
132
|
+
var _a;
|
|
133
|
+
const transition = transitions[index];
|
|
134
|
+
const item = items[(_a = transition === null || transition === void 0 ? void 0 : transition.to) !== null && _a !== void 0 ? _a : slot];
|
|
135
|
+
const previousItem = transition ? items[transition.from] : undefined;
|
|
136
|
+
return (React.createElement(Item, { key: index, colSizes: colSizes, url: item.url, src: item.src, previousUrl: previousItem === null || previousItem === void 0 ? void 0 : previousItem.url, previousSrc: previousItem === null || previousItem === void 0 ? void 0 : previousItem.src, swapAnimation: swapAnimation, onMouseEnter: () => handleSlotMouseEnter(index), onMouseLeave: () => handleSlotMouseLeave(index) }));
|
|
137
|
+
}), [
|
|
138
|
+
colSizes,
|
|
139
|
+
handleSlotMouseEnter,
|
|
140
|
+
handleSlotMouseLeave,
|
|
141
|
+
items,
|
|
142
|
+
slots,
|
|
143
|
+
swapAnimation,
|
|
144
|
+
transitions,
|
|
145
|
+
]);
|
|
106
146
|
const titleProps = !title || typeof title === 'string'
|
|
107
147
|
? { text: title, textSize: 'l' }
|
|
108
148
|
: title;
|
|
109
149
|
const hasTitle = Boolean(title);
|
|
110
150
|
return (React.createElement(AnimateBlock, { className: b({ theme }), animate: animated },
|
|
111
|
-
React.createElement("div", { className: b('root'),
|
|
112
|
-
isHoveredRef.current = true;
|
|
113
|
-
}, onMouseLeave: () => {
|
|
114
|
-
isHoveredRef.current = false;
|
|
115
|
-
} },
|
|
151
|
+
React.createElement("div", { className: b('root') },
|
|
116
152
|
hasTitle && (React.createElement(Title, { title: titleProps, className: b('title'), colSizes: { all: 12 } })),
|
|
117
153
|
rowMode ? (React.createElement("div", { className: b('row-items') }, slots.map((slot, index) => {
|
|
118
|
-
|
|
119
|
-
|
|
154
|
+
var _a;
|
|
155
|
+
const transition = transitions[index];
|
|
156
|
+
const item = items[(_a = transition === null || transition === void 0 ? void 0 : transition.to) !== null && _a !== void 0 ? _a : slot];
|
|
157
|
+
const previousItem = transition ? items[transition.from] : undefined;
|
|
158
|
+
if (item === undefined)
|
|
120
159
|
return null;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
160
|
+
const renderRowLayer = (layerItem, layer) => {
|
|
161
|
+
const layerClassName = b('logo-layer', getLayerModifiers(layer, swapAnimation));
|
|
162
|
+
if (layerItem.url) {
|
|
163
|
+
return (React.createElement(Link, { href: layerItem.url, className: `${b('row-item-link')} ${layerClassName}` },
|
|
164
|
+
React.createElement(ImageBase, { src: layerItem.src, className: b('image'), alt: "", "aria-hidden": "true" })));
|
|
165
|
+
}
|
|
166
|
+
return (React.createElement("div", { className: layerClassName },
|
|
167
|
+
React.createElement(ImageBase, { src: layerItem.src, className: b('image'), alt: "", "aria-hidden": "true" })));
|
|
168
|
+
};
|
|
169
|
+
const content = (React.createElement(React.Fragment, null,
|
|
170
|
+
previousItem && renderRowLayer(previousItem, 'from'),
|
|
171
|
+
renderRowLayer(item, previousItem ? 'to' : 'current')));
|
|
172
|
+
return (React.createElement("div", { key: index, className: b('row-item', { swapping: Boolean(previousItem) }), onMouseEnter: () => handleSlotMouseEnter(index), onMouseLeave: () => handleSlotMouseLeave(index) }, content));
|
|
127
173
|
}))) : (React.createElement(Grid, { className: b('items') },
|
|
128
174
|
React.createElement(Row, { className: b('row') }, renderItems))))));
|
|
129
175
|
};
|
|
@@ -182,7 +182,10 @@ export declare const LogoRotatorBlock: {
|
|
|
182
182
|
};
|
|
183
183
|
};
|
|
184
184
|
};
|
|
185
|
-
|
|
185
|
+
countMobile: {
|
|
186
|
+
type: string;
|
|
187
|
+
};
|
|
188
|
+
countDesktop: {
|
|
186
189
|
type: string;
|
|
187
190
|
};
|
|
188
191
|
minRotateCount: {
|
|
@@ -191,6 +194,10 @@ export declare const LogoRotatorBlock: {
|
|
|
191
194
|
maxRotateCount: {
|
|
192
195
|
type: string;
|
|
193
196
|
};
|
|
197
|
+
swapAnimation: {
|
|
198
|
+
type: string;
|
|
199
|
+
enum: string[];
|
|
200
|
+
};
|
|
194
201
|
colSizes: {
|
|
195
202
|
type: string;
|
|
196
203
|
additionalProperties: {
|
|
@@ -2,7 +2,7 @@ import { AnimatableProps, BaseProps, ThemeProps, TitleProps, containerSizesObjec
|
|
|
2
2
|
export const LogoRotatorBlock = {
|
|
3
3
|
'logo-rotator-block': {
|
|
4
4
|
additionalProperties: false,
|
|
5
|
-
required: ['items', '
|
|
5
|
+
required: ['items', 'countMobile'],
|
|
6
6
|
properties: Object.assign(Object.assign(Object.assign({}, BaseProps), AnimatableProps), { title: {
|
|
7
7
|
oneOf: [
|
|
8
8
|
{
|
|
@@ -24,12 +24,17 @@ export const LogoRotatorBlock = {
|
|
|
24
24
|
isStatic: { type: 'boolean' },
|
|
25
25
|
},
|
|
26
26
|
},
|
|
27
|
-
},
|
|
27
|
+
}, countMobile: {
|
|
28
|
+
type: 'number',
|
|
29
|
+
}, countDesktop: {
|
|
28
30
|
type: 'number',
|
|
29
31
|
}, minRotateCount: {
|
|
30
32
|
type: 'number',
|
|
31
33
|
}, maxRotateCount: {
|
|
32
34
|
type: 'number',
|
|
35
|
+
}, swapAnimation: {
|
|
36
|
+
type: 'string',
|
|
37
|
+
enum: ['fade', 'morph'],
|
|
33
38
|
}, colSizes: {
|
|
34
39
|
type: 'object',
|
|
35
40
|
additionalProperties: containerSizesObject,
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { LogoRotatorBlockProps } from '../../models';
|
|
2
|
+
export type LogoRotatorLayer = 'current' | 'from' | 'to';
|
|
3
|
+
export type LogoRotatorSwapAnimation = NonNullable<LogoRotatorBlockProps['swapAnimation']>;
|
|
4
|
+
export declare const DEFAULT_SWAP_ANIMATION: LogoRotatorSwapAnimation;
|
|
5
|
+
export declare const SWAP_ANIMATION_DURATIONS: Record<LogoRotatorSwapAnimation, number>;
|
|
6
|
+
export declare const getLayerModifiers: (layer: LogoRotatorLayer, swapAnimation: LogoRotatorSwapAnimation) => Record<string, boolean>;
|
|
7
|
+
export declare const getInitialSlots: (items: LogoRotatorBlockProps['items'], count: number) => number[];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const DEFAULT_SWAP_ANIMATION = 'fade';
|
|
2
|
+
export const SWAP_ANIMATION_DURATIONS = {
|
|
3
|
+
fade: 1100,
|
|
4
|
+
morph: 500,
|
|
5
|
+
};
|
|
6
|
+
export const getLayerModifiers = (layer, swapAnimation) => {
|
|
7
|
+
const animationModifier = layer === 'current' ? undefined : `${swapAnimation}-${layer}`;
|
|
8
|
+
const modifiers = { [layer]: true };
|
|
9
|
+
if (animationModifier) {
|
|
10
|
+
modifiers[animationModifier] = true;
|
|
11
|
+
}
|
|
12
|
+
return modifiers;
|
|
13
|
+
};
|
|
14
|
+
export const getInitialSlots = (items, count) => {
|
|
15
|
+
var _a;
|
|
16
|
+
const staticIdxList = items.map((item, i) => (item.isStatic ? i : -1)).filter((i) => i !== -1);
|
|
17
|
+
const rotatableIdxList = items
|
|
18
|
+
.map((item, i) => (item.isStatic ? -1 : i))
|
|
19
|
+
.filter((i) => i !== -1);
|
|
20
|
+
const initial = [];
|
|
21
|
+
let rotatablePointer = 0;
|
|
22
|
+
for (let slot = 0; slot < count; slot++) {
|
|
23
|
+
if (slot < staticIdxList.length) {
|
|
24
|
+
initial.push(staticIdxList[slot]);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
initial.push((_a = rotatableIdxList[rotatablePointer++]) !== null && _a !== void 0 ? _a : 0);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return initial;
|
|
31
|
+
};
|
|
@@ -302,9 +302,11 @@ export interface LogoRotatorBlockProps extends Animatable {
|
|
|
302
302
|
src: string;
|
|
303
303
|
isStatic?: boolean;
|
|
304
304
|
}[];
|
|
305
|
-
|
|
305
|
+
countMobile: number;
|
|
306
|
+
countDesktop?: number;
|
|
306
307
|
minRotateCount?: number;
|
|
307
308
|
maxRotateCount?: number;
|
|
309
|
+
swapAnimation?: 'fade' | 'morph';
|
|
308
310
|
colSizes?: Partial<Record<GridColumnSize, number>>;
|
|
309
311
|
theme?: TextTheme;
|
|
310
312
|
rowMode?: boolean;
|