@doyourjob/gravity-ui-page-constructor 5.31.184 → 5.31.186

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.
@@ -68,6 +68,30 @@ unpredictable css rules order in build */
68
68
  .pc-header-block__content_vertical-offset_xl {
69
69
  padding: 160px 0;
70
70
  }
71
+ .pc-header-block__content_vertical-offset-top_s {
72
+ padding-top: 64px;
73
+ }
74
+ .pc-header-block__content_vertical-offset-top_m {
75
+ padding-top: 96px;
76
+ }
77
+ .pc-header-block__content_vertical-offset-top_l {
78
+ padding-top: 128px;
79
+ }
80
+ .pc-header-block__content_vertical-offset-top_xl {
81
+ padding-top: 160px;
82
+ }
83
+ .pc-header-block__content_vertical-offset-bottom_s {
84
+ padding-bottom: 64px;
85
+ }
86
+ .pc-header-block__content_vertical-offset-bottom_m {
87
+ padding-bottom: 96px;
88
+ }
89
+ .pc-header-block__content_vertical-offset-bottom_l {
90
+ padding-bottom: 128px;
91
+ }
92
+ .pc-header-block__content_vertical-offset-bottom_xl {
93
+ padding-bottom: 160px;
94
+ }
71
95
  .pc-header-block__content_offset_large {
72
96
  padding: calc(128px - 16px) 0 16px;
73
97
  }
@@ -30,7 +30,7 @@ const Background = ({ background, isMobile }) => {
30
30
  const FullWidthBackground = ({ background }) => (react_1.default.createElement("div", { className: b('background', { ['full-width']: true }), style: { backgroundColor: background === null || background === void 0 ? void 0 : background.color } }));
31
31
  // eslint-disable-next-line complexity
32
32
  const HeaderBlock = (props) => {
33
- const { title, switchingTitle, topTags, bottomTags, overtitle, description, buttons, stock, stockPrice, stockShares, image, video, width = 's', imageSize, offset = 'default', background, theme: textTheme = 'light', verticalOffset = 'm', className, breadcrumbs, status, renderTitle, children, mediaView = 'full', backgroundEffect, headerSpace, backLink, } = props;
33
+ const { title, switchingTitle, topTags, bottomTags, overtitle, description, buttons, stock, stockPrice, stockShares, image, video, width = 's', imageSize, offset = 'default', background, theme: textTheme = 'light', verticalOffset = 'm', verticalOffsetTop, verticalOffsetBottom, className, breadcrumbs, status, renderTitle, children, mediaView = 'full', backgroundEffect, headerSpace, backLink, } = props;
34
34
  const isMobile = (0, react_1.useContext)(mobileContext_1.MobileContext);
35
35
  const { backButton, blockTag } = (0, react_1.useContext)(headerContext_1.HeaderContext);
36
36
  const theme = (0, theme_1.useTheme)();
@@ -73,6 +73,8 @@ const HeaderBlock = (props) => {
73
73
  offset,
74
74
  theme: textTheme,
75
75
  'vertical-offset': curVerticalOffset,
76
+ 'vertical-offset-top': verticalOffsetTop,
77
+ 'vertical-offset-bottom': verticalOffsetBottom,
76
78
  }) },
77
79
  react_1.default.createElement(HeaderTags_1.default, { theme: textTheme, tags: topTags, className: b('tags', { top: true }), sizes: titleSizes }),
78
80
  react_1.default.createElement(grid_1.Col, { sizes: titleSizes, className: b('content-inner') },
@@ -576,6 +576,14 @@ export declare const HeaderProperties: {
576
576
  type: string;
577
577
  enum: string[];
578
578
  };
579
+ verticalOffsetTop: {
580
+ type: string;
581
+ enum: string[];
582
+ };
583
+ verticalOffsetBottom: {
584
+ type: string;
585
+ enum: string[];
586
+ };
579
587
  background: {
580
588
  oneOf: (({
581
589
  type: string;
@@ -1265,6 +1273,14 @@ export declare const HeaderBlock: {
1265
1273
  type: string;
1266
1274
  enum: string[];
1267
1275
  };
1276
+ verticalOffsetTop: {
1277
+ type: string;
1278
+ enum: string[];
1279
+ };
1280
+ verticalOffsetBottom: {
1281
+ type: string;
1282
+ enum: string[];
1283
+ };
1268
1284
  background: {
1269
1285
  oneOf: (({
1270
1286
  type: string;
@@ -127,6 +127,14 @@ exports.HeaderProperties = {
127
127
  type: 'string',
128
128
  enum: ['0', 's', 'm', 'l', 'xl'],
129
129
  },
130
+ verticalOffsetTop: {
131
+ type: 'string',
132
+ enum: ['s', 'm', 'l', 'xl'],
133
+ },
134
+ verticalOffsetBottom: {
135
+ type: 'string',
136
+ enum: ['s', 'm', 'l', 'xl'],
137
+ },
130
138
  background: (0, common_1.withTheme)(exports.HeaderBackgroundProps),
131
139
  theme: {
132
140
  type: 'string',
@@ -270,6 +270,14 @@ export declare const HeaderSliderBlock: {
270
270
  type: string;
271
271
  enum: string[];
272
272
  };
273
+ verticalOffsetTop: {
274
+ type: string;
275
+ enum: string[];
276
+ };
277
+ verticalOffsetBottom: {
278
+ type: string;
279
+ enum: string[];
280
+ };
273
281
  background: {
274
282
  oneOf: (({
275
283
  type: string;
@@ -17,14 +17,11 @@ unpredictable css rules order in build */
17
17
  justify-content: center;
18
18
  }
19
19
  .pc-logo-rotator-block_theme_dark .pc-logo-rotator-block__title {
20
- color: #ffffff;
20
+ --pc-text-header-color: #ffffff;
21
21
  }
22
22
  .pc-logo-rotator-block__title {
23
23
  margin-bottom: 48px;
24
24
  text-align: center;
25
- font-size: 48px;
26
- line-height: 52px;
27
- font-weight: 600;
28
25
  }
29
26
  .pc-logo-rotator-block__items {
30
27
  display: flex;
@@ -12,13 +12,46 @@ const Item_1 = tslib_1.__importDefault(require("./Item"));
12
12
  const b = (0, utils_1.block)('logo-rotator-block');
13
13
  const LogoRotatorBlock = (props) => {
14
14
  const { animated, title, theme, items, count, colSizes, rowMode } = props;
15
- const [slots, setSlots] = (0, react_1.useState)(new Array(count).fill(0).map((_, index) => index));
15
+ // Индексы логотипов, которые участвуют в ротации (не статичные)
16
+ const rotatableIndices = (0, react_1.useMemo)(() => items.map((item, i) => (item.isStatic ? -1 : i)).filter((i) => i !== -1), [items]);
17
+ // Инициализация слотов: статичные вставляются в начало, остальные по порядку
18
+ const [slots, setSlots] = (0, react_1.useState)(() => {
19
+ var _a;
20
+ const staticIdxList = items
21
+ .map((item, i) => (item.isStatic ? i : -1))
22
+ .filter((i) => i !== -1);
23
+ const rotatableIdxList = items
24
+ .map((item, i) => (item.isStatic ? -1 : i))
25
+ .filter((i) => i !== -1);
26
+ const initial = [];
27
+ let rotatablePointer = 0;
28
+ for (let slot = 0; slot < count; slot++) {
29
+ if (slot < staticIdxList.length) {
30
+ initial.push(staticIdxList[slot]);
31
+ }
32
+ else {
33
+ initial.push((_a = rotatableIdxList[rotatablePointer++]) !== null && _a !== void 0 ? _a : 0);
34
+ }
35
+ }
36
+ return initial;
37
+ });
16
38
  const [hidden, setHidden] = (0, react_1.useState)(() => Array(count).fill(false));
17
39
  const nextIndexRef = (0, react_1.useRef)(count - 1);
40
+ // Держим актуальные slots в ref, чтобы не пересоздавать интервал при каждом изменении
41
+ const slotsRef = (0, react_1.useRef)(slots);
42
+ (0, react_1.useEffect)(() => {
43
+ slotsRef.current = slots;
44
+ }, [slots]);
18
45
  (0, react_1.useEffect)(() => {
19
46
  let timeout = null;
20
47
  const interval = setInterval(() => {
21
- const slotIndex = Math.floor(Math.random() * count);
48
+ // Выбираем только не-статичные слоты для замены
49
+ const rotatableSlotIndices = slotsRef.current
50
+ .map((itemIdx, slotIdx) => { var _a; return (((_a = items[itemIdx]) === null || _a === void 0 ? void 0 : _a.isStatic) ? -1 : slotIdx); })
51
+ .filter((i) => i !== -1);
52
+ if (rotatableSlotIndices.length === 0)
53
+ return;
54
+ const slotIndex = rotatableSlotIndices[Math.floor(Math.random() * rotatableSlotIndices.length)];
22
55
  setHidden((prev) => {
23
56
  const next = [...prev];
24
57
  next[slotIndex] = true;
@@ -27,7 +60,8 @@ const LogoRotatorBlock = (props) => {
27
60
  timeout = setTimeout(() => {
28
61
  setSlots((prevSlots) => {
29
62
  const newSlots = [...prevSlots];
30
- const available = items.map((_, i) => i).filter((i) => !newSlots.includes(i));
63
+ // Доступные для показа только ротируемые, не отображаемые сейчас
64
+ const available = rotatableIndices.filter((i) => !newSlots.includes(i));
31
65
  if (available.length > 0) {
32
66
  const newValue = available[nextIndexRef.current % available.length];
33
67
  nextIndexRef.current++;
@@ -48,11 +82,15 @@ const LogoRotatorBlock = (props) => {
48
82
  clearTimeout(timeout);
49
83
  }
50
84
  };
51
- }, [count, items]);
85
+ }, [count, items, rotatableIndices]);
52
86
  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
+ const titleProps = !title || typeof title === 'string'
88
+ ? { text: title, textSize: 'l' }
89
+ : title;
90
+ const hasTitle = Boolean(title);
53
91
  return (react_1.default.createElement(AnimateBlock_1.default, { className: b({ theme }), animate: animated },
54
92
  react_1.default.createElement("div", { className: b('root') },
55
- title && react_1.default.createElement("div", { className: b('title') }, title),
93
+ hasTitle && (react_1.default.createElement(components_1.Title, { title: titleProps, className: b('title'), colSizes: { all: 12 } })),
56
94
  rowMode ? (react_1.default.createElement("div", { className: b('row-items') }, slots.map((slot, index) => (react_1.default.createElement(uikit_1.Link, { key: index, href: items[slot].url, className: b('row-item', { hidden: hidden[index] }) },
57
95
  react_1.default.createElement(components_1.ImageBase, { src: items[slot].src, className: b('image'), alt: "", "aria-hidden": "true" })))))) : (react_1.default.createElement(grid_1.Grid, { className: b('items') },
58
96
  react_1.default.createElement(grid_1.Row, { className: b('row') }, renderItems))))));
@@ -4,7 +4,153 @@ export declare const LogoRotatorBlock: {
4
4
  required: string[];
5
5
  properties: {
6
6
  title: {
7
- type: string;
7
+ oneOf: ({
8
+ type: string;
9
+ contentType: string;
10
+ optionName: string;
11
+ } | {
12
+ optionName: string;
13
+ type: string;
14
+ additionalProperties: boolean;
15
+ required: string[];
16
+ properties: {
17
+ text: {
18
+ type: string;
19
+ contentType: string;
20
+ };
21
+ link: {
22
+ type: string;
23
+ additionalProperties: boolean;
24
+ required: string[];
25
+ properties: {
26
+ text: {
27
+ type: string;
28
+ contentType: string;
29
+ };
30
+ url: {
31
+ type: string;
32
+ };
33
+ urlTitle: {
34
+ type: string;
35
+ };
36
+ arrow: {
37
+ type: string;
38
+ };
39
+ theme: {
40
+ type: string;
41
+ enum: string[];
42
+ };
43
+ textSize: {
44
+ type: string;
45
+ enum: string[];
46
+ };
47
+ target: {
48
+ type: string;
49
+ enum: string[];
50
+ };
51
+ analyticsEvents: {
52
+ oneOf: ({
53
+ optionName: string;
54
+ type: string;
55
+ additionalProperties: {
56
+ type: string;
57
+ };
58
+ required: string[];
59
+ properties: {
60
+ name: {
61
+ type: string;
62
+ };
63
+ type: {
64
+ type: string;
65
+ };
66
+ counters: {
67
+ type: string;
68
+ additionalProperties: boolean;
69
+ required: never[];
70
+ properties: {
71
+ include: {
72
+ type: string;
73
+ items: {
74
+ type: string;
75
+ };
76
+ };
77
+ exclude: {
78
+ type: string;
79
+ items: {
80
+ type: string;
81
+ };
82
+ };
83
+ };
84
+ };
85
+ context: {
86
+ type: string;
87
+ };
88
+ };
89
+ items?: undefined;
90
+ } | {
91
+ type: string;
92
+ items: {
93
+ type: string;
94
+ additionalProperties: {
95
+ type: string;
96
+ };
97
+ required: string[];
98
+ properties: {
99
+ name: {
100
+ type: string;
101
+ };
102
+ type: {
103
+ type: string;
104
+ };
105
+ counters: {
106
+ type: string;
107
+ additionalProperties: boolean;
108
+ required: never[];
109
+ properties: {
110
+ include: {
111
+ type: string;
112
+ items: {
113
+ type: string;
114
+ };
115
+ };
116
+ exclude: {
117
+ type: string;
118
+ items: {
119
+ type: string;
120
+ };
121
+ };
122
+ };
123
+ };
124
+ context: {
125
+ type: string;
126
+ };
127
+ };
128
+ };
129
+ optionName: string;
130
+ })[];
131
+ };
132
+ type: {};
133
+ when: {
134
+ type: string;
135
+ };
136
+ };
137
+ };
138
+ textSize: {
139
+ type: string;
140
+ enum: string[];
141
+ };
142
+ url: {
143
+ type: string;
144
+ };
145
+ urlTitle: {
146
+ type: string;
147
+ };
148
+ resetMargin: {
149
+ type: string;
150
+ };
151
+ };
152
+ contentType?: undefined;
153
+ })[];
8
154
  };
9
155
  theme: {
10
156
  type: string;
@@ -23,6 +169,9 @@ export declare const LogoRotatorBlock: {
23
169
  src: {
24
170
  type: string;
25
171
  };
172
+ isStatic: {
173
+ type: string;
174
+ };
26
175
  };
27
176
  };
28
177
  };
@@ -6,7 +6,16 @@ exports.LogoRotatorBlock = {
6
6
  'logo-rotator-block': {
7
7
  additionalProperties: false,
8
8
  required: ['items', 'count'],
9
- properties: Object.assign(Object.assign(Object.assign({}, common_1.BaseProps), common_1.AnimatableProps), { title: { type: 'string' }, theme: common_1.ThemeProps, items: {
9
+ properties: Object.assign(Object.assign(Object.assign({}, common_1.BaseProps), common_1.AnimatableProps), { title: {
10
+ oneOf: [
11
+ {
12
+ type: 'string',
13
+ contentType: 'text',
14
+ optionName: 'text',
15
+ },
16
+ Object.assign(Object.assign({}, common_1.TitleProps), { optionName: 'options' }),
17
+ ],
18
+ }, theme: common_1.ThemeProps, items: {
10
19
  type: 'array',
11
20
  items: {
12
21
  type: 'object',
@@ -15,6 +24,7 @@ exports.LogoRotatorBlock = {
15
24
  properties: {
16
25
  url: { type: 'string' },
17
26
  src: { type: 'string' },
27
+ isStatic: { type: 'boolean' },
18
28
  },
19
29
  },
20
30
  }, count: {
@@ -216,6 +216,8 @@ export interface HeaderBlockProps {
216
216
  background?: ThemedHeaderBlockBackground;
217
217
  theme?: 'light' | 'dark';
218
218
  verticalOffset?: '0' | 's' | 'm' | 'l' | 'xl';
219
+ verticalOffsetTop?: 's' | 'm' | 'l' | 'xl';
220
+ verticalOffsetBottom?: 's' | 'm' | 'l' | 'xl';
219
221
  breadcrumbs?: HeaderBreadCrumbsProps;
220
222
  backLink?: {
221
223
  url: string;
@@ -285,10 +287,11 @@ export interface QuestionBlockItemProps extends QuestionItem {
285
287
  export interface BannerBlockProps extends BannerCardProps, Animatable {
286
288
  }
287
289
  export interface LogoRotatorBlockProps extends Animatable {
288
- title?: string;
290
+ title?: TitleItemBaseProps | string;
289
291
  items: {
290
292
  url: string;
291
293
  src: string;
294
+ isStatic?: boolean;
292
295
  }[];
293
296
  count: number;
294
297
  colSizes?: Partial<Record<GridColumnSize, number>>;
@@ -68,6 +68,30 @@ unpredictable css rules order in build */
68
68
  .pc-header-block__content_vertical-offset_xl {
69
69
  padding: 160px 0;
70
70
  }
71
+ .pc-header-block__content_vertical-offset-top_s {
72
+ padding-top: 64px;
73
+ }
74
+ .pc-header-block__content_vertical-offset-top_m {
75
+ padding-top: 96px;
76
+ }
77
+ .pc-header-block__content_vertical-offset-top_l {
78
+ padding-top: 128px;
79
+ }
80
+ .pc-header-block__content_vertical-offset-top_xl {
81
+ padding-top: 160px;
82
+ }
83
+ .pc-header-block__content_vertical-offset-bottom_s {
84
+ padding-bottom: 64px;
85
+ }
86
+ .pc-header-block__content_vertical-offset-bottom_m {
87
+ padding-bottom: 96px;
88
+ }
89
+ .pc-header-block__content_vertical-offset-bottom_l {
90
+ padding-bottom: 128px;
91
+ }
92
+ .pc-header-block__content_vertical-offset-bottom_xl {
93
+ padding-bottom: 160px;
94
+ }
71
95
  .pc-header-block__content_offset_large {
72
96
  padding: calc(128px - 16px) 0 16px;
73
97
  }
@@ -27,7 +27,7 @@ const Background = ({ background, isMobile }) => {
27
27
  const FullWidthBackground = ({ background }) => (React.createElement("div", { className: b('background', { ['full-width']: true }), style: { backgroundColor: background === null || background === void 0 ? void 0 : background.color } }));
28
28
  // eslint-disable-next-line complexity
29
29
  export const HeaderBlock = (props) => {
30
- const { title, switchingTitle, topTags, bottomTags, overtitle, description, buttons, stock, stockPrice, stockShares, image, video, width = 's', imageSize, offset = 'default', background, theme: textTheme = 'light', verticalOffset = 'm', className, breadcrumbs, status, renderTitle, children, mediaView = 'full', backgroundEffect, headerSpace, backLink, } = props;
30
+ const { title, switchingTitle, topTags, bottomTags, overtitle, description, buttons, stock, stockPrice, stockShares, image, video, width = 's', imageSize, offset = 'default', background, theme: textTheme = 'light', verticalOffset = 'm', verticalOffsetTop, verticalOffsetBottom, className, breadcrumbs, status, renderTitle, children, mediaView = 'full', backgroundEffect, headerSpace, backLink, } = props;
31
31
  const isMobile = useContext(MobileContext);
32
32
  const { backButton, blockTag } = useContext(HeaderContext);
33
33
  const theme = useTheme();
@@ -70,6 +70,8 @@ export const HeaderBlock = (props) => {
70
70
  offset,
71
71
  theme: textTheme,
72
72
  'vertical-offset': curVerticalOffset,
73
+ 'vertical-offset-top': verticalOffsetTop,
74
+ 'vertical-offset-bottom': verticalOffsetBottom,
73
75
  }) },
74
76
  React.createElement(HeaderTags, { theme: textTheme, tags: topTags, className: b('tags', { top: true }), sizes: titleSizes }),
75
77
  React.createElement(Col, { sizes: titleSizes, className: b('content-inner') },
@@ -576,6 +576,14 @@ export declare const HeaderProperties: {
576
576
  type: string;
577
577
  enum: string[];
578
578
  };
579
+ verticalOffsetTop: {
580
+ type: string;
581
+ enum: string[];
582
+ };
583
+ verticalOffsetBottom: {
584
+ type: string;
585
+ enum: string[];
586
+ };
579
587
  background: {
580
588
  oneOf: (({
581
589
  type: string;
@@ -1265,6 +1273,14 @@ export declare const HeaderBlock: {
1265
1273
  type: string;
1266
1274
  enum: string[];
1267
1275
  };
1276
+ verticalOffsetTop: {
1277
+ type: string;
1278
+ enum: string[];
1279
+ };
1280
+ verticalOffsetBottom: {
1281
+ type: string;
1282
+ enum: string[];
1283
+ };
1268
1284
  background: {
1269
1285
  oneOf: (({
1270
1286
  type: string;
@@ -124,6 +124,14 @@ export const HeaderProperties = {
124
124
  type: 'string',
125
125
  enum: ['0', 's', 'm', 'l', 'xl'],
126
126
  },
127
+ verticalOffsetTop: {
128
+ type: 'string',
129
+ enum: ['s', 'm', 'l', 'xl'],
130
+ },
131
+ verticalOffsetBottom: {
132
+ type: 'string',
133
+ enum: ['s', 'm', 'l', 'xl'],
134
+ },
127
135
  background: withTheme(HeaderBackgroundProps),
128
136
  theme: {
129
137
  type: 'string',
@@ -270,6 +270,14 @@ export declare const HeaderSliderBlock: {
270
270
  type: string;
271
271
  enum: string[];
272
272
  };
273
+ verticalOffsetTop: {
274
+ type: string;
275
+ enum: string[];
276
+ };
277
+ verticalOffsetBottom: {
278
+ type: string;
279
+ enum: string[];
280
+ };
273
281
  background: {
274
282
  oneOf: (({
275
283
  type: string;
@@ -17,14 +17,11 @@ unpredictable css rules order in build */
17
17
  justify-content: center;
18
18
  }
19
19
  .pc-logo-rotator-block_theme_dark .pc-logo-rotator-block__title {
20
- color: #ffffff;
20
+ --pc-text-header-color: #ffffff;
21
21
  }
22
22
  .pc-logo-rotator-block__title {
23
23
  margin-bottom: 48px;
24
24
  text-align: center;
25
- font-size: 48px;
26
- line-height: 52px;
27
- font-weight: 600;
28
25
  }
29
26
  .pc-logo-rotator-block__items {
30
27
  display: flex;
@@ -1,6 +1,6 @@
1
1
  import React, { useEffect, useMemo, useRef, useState } from 'react';
2
2
  import { Link } from '@gravity-ui/uikit';
3
- import { ImageBase } from '../../components';
3
+ import { ImageBase, Title } from '../../components';
4
4
  import AnimateBlock from '../../components/AnimateBlock/AnimateBlock';
5
5
  import { Grid, Row } from '../../grid';
6
6
  import { block } from '../../utils';
@@ -9,13 +9,46 @@ import './LogoRotator.css';
9
9
  const b = block('logo-rotator-block');
10
10
  export const LogoRotatorBlock = (props) => {
11
11
  const { animated, title, theme, items, count, colSizes, rowMode } = props;
12
- const [slots, setSlots] = useState(new Array(count).fill(0).map((_, index) => index));
12
+ // Индексы логотипов, которые участвуют в ротации (не статичные)
13
+ const rotatableIndices = useMemo(() => items.map((item, i) => (item.isStatic ? -1 : i)).filter((i) => i !== -1), [items]);
14
+ // Инициализация слотов: статичные вставляются в начало, остальные по порядку
15
+ const [slots, setSlots] = useState(() => {
16
+ var _a;
17
+ const staticIdxList = items
18
+ .map((item, i) => (item.isStatic ? i : -1))
19
+ .filter((i) => i !== -1);
20
+ const rotatableIdxList = items
21
+ .map((item, i) => (item.isStatic ? -1 : i))
22
+ .filter((i) => i !== -1);
23
+ const initial = [];
24
+ let rotatablePointer = 0;
25
+ for (let slot = 0; slot < count; slot++) {
26
+ if (slot < staticIdxList.length) {
27
+ initial.push(staticIdxList[slot]);
28
+ }
29
+ else {
30
+ initial.push((_a = rotatableIdxList[rotatablePointer++]) !== null && _a !== void 0 ? _a : 0);
31
+ }
32
+ }
33
+ return initial;
34
+ });
13
35
  const [hidden, setHidden] = useState(() => Array(count).fill(false));
14
36
  const nextIndexRef = useRef(count - 1);
37
+ // Держим актуальные slots в ref, чтобы не пересоздавать интервал при каждом изменении
38
+ const slotsRef = useRef(slots);
39
+ useEffect(() => {
40
+ slotsRef.current = slots;
41
+ }, [slots]);
15
42
  useEffect(() => {
16
43
  let timeout = null;
17
44
  const interval = setInterval(() => {
18
- const slotIndex = Math.floor(Math.random() * count);
45
+ // Выбираем только не-статичные слоты для замены
46
+ const rotatableSlotIndices = slotsRef.current
47
+ .map((itemIdx, slotIdx) => { var _a; return (((_a = items[itemIdx]) === null || _a === void 0 ? void 0 : _a.isStatic) ? -1 : slotIdx); })
48
+ .filter((i) => i !== -1);
49
+ if (rotatableSlotIndices.length === 0)
50
+ return;
51
+ const slotIndex = rotatableSlotIndices[Math.floor(Math.random() * rotatableSlotIndices.length)];
19
52
  setHidden((prev) => {
20
53
  const next = [...prev];
21
54
  next[slotIndex] = true;
@@ -24,7 +57,8 @@ export const LogoRotatorBlock = (props) => {
24
57
  timeout = setTimeout(() => {
25
58
  setSlots((prevSlots) => {
26
59
  const newSlots = [...prevSlots];
27
- const available = items.map((_, i) => i).filter((i) => !newSlots.includes(i));
60
+ // Доступные для показа только ротируемые, не отображаемые сейчас
61
+ const available = rotatableIndices.filter((i) => !newSlots.includes(i));
28
62
  if (available.length > 0) {
29
63
  const newValue = available[nextIndexRef.current % available.length];
30
64
  nextIndexRef.current++;
@@ -45,11 +79,15 @@ export const LogoRotatorBlock = (props) => {
45
79
  clearTimeout(timeout);
46
80
  }
47
81
  };
48
- }, [count, items]);
82
+ }, [count, items, rotatableIndices]);
49
83
  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
+ const titleProps = !title || typeof title === 'string'
85
+ ? { text: title, textSize: 'l' }
86
+ : title;
87
+ const hasTitle = Boolean(title);
50
88
  return (React.createElement(AnimateBlock, { className: b({ theme }), animate: animated },
51
89
  React.createElement("div", { className: b('root') },
52
- title && React.createElement("div", { className: b('title') }, title),
90
+ hasTitle && (React.createElement(Title, { title: titleProps, className: b('title'), colSizes: { all: 12 } })),
53
91
  rowMode ? (React.createElement("div", { className: b('row-items') }, slots.map((slot, index) => (React.createElement(Link, { key: index, href: items[slot].url, className: b('row-item', { hidden: hidden[index] }) },
54
92
  React.createElement(ImageBase, { src: items[slot].src, className: b('image'), alt: "", "aria-hidden": "true" })))))) : (React.createElement(Grid, { className: b('items') },
55
93
  React.createElement(Row, { className: b('row') }, renderItems))))));