@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.
@@ -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 slotIndex = rotatableSlotIndices[Math.floor(Math.random() * rotatableSlotIndices.length)];
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
- next[slotIndex] = true;
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
- const available = rotatableIndices.filter((i) => !newSlots.includes(i));
65
- if (available.length > 0) {
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
- next[slotIndex] = false;
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];
@@ -185,6 +185,12 @@ export declare const LogoRotatorBlock: {
185
185
  count: {
186
186
  type: string;
187
187
  };
188
+ minRotateCount: {
189
+ type: string;
190
+ };
191
+ maxRotateCount: {
192
+ type: string;
193
+ };
188
194
  colSizes: {
189
195
  type: string;
190
196
  additionalProperties: {
@@ -29,6 +29,10 @@ exports.LogoRotatorBlock = {
29
29
  },
30
30
  }, count: {
31
31
  type: 'number',
32
+ }, minRotateCount: {
33
+ type: 'number',
34
+ }, maxRotateCount: {
35
+ type: 'number',
32
36
  }, colSizes: {
33
37
  type: 'object',
34
38
  additionalProperties: common_1.containerSizesObject,
@@ -130,6 +130,9 @@ export declare const MapBlock: {
130
130
  mediaOnly: {
131
131
  type: string;
132
132
  };
133
+ imageWidthAuto: {
134
+ type: string;
135
+ };
133
136
  disableShadow: {
134
137
  type: string;
135
138
  };
@@ -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
  */
@@ -27,6 +27,8 @@ exports.MediaBlockBaseProps = Object.assign(Object.assign(Object.assign(Object.a
27
27
  type: 'boolean',
28
28
  }, mediaOnly: {
29
29
  type: 'boolean',
30
+ }, imageWidthAuto: {
31
+ type: 'boolean',
30
32
  },
31
33
  /**
32
34
  * @deprecated use border='none' or border='line' instead
@@ -16,6 +16,9 @@ unpredictable css rules order in build */
16
16
  .pc-media-base__card img {
17
17
  width: 100%;
18
18
  }
19
+ .pc-media-base__card_imageWidthAuto img {
20
+ width: auto;
21
+ }
19
22
  .pc-media-base__card img,
20
23
  .pc-media-base__card video,
21
24
  .pc-media-base__card iframe,
@@ -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 slotIndex = rotatableSlotIndices[Math.floor(Math.random() * rotatableSlotIndices.length)];
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
- next[slotIndex] = true;
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
- const available = rotatableIndices.filter((i) => !newSlots.includes(i));
62
- if (available.length > 0) {
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
- next[slotIndex] = false;
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];
@@ -185,6 +185,12 @@ export declare const LogoRotatorBlock: {
185
185
  count: {
186
186
  type: string;
187
187
  };
188
+ minRotateCount: {
189
+ type: string;
190
+ };
191
+ maxRotateCount: {
192
+ type: string;
193
+ };
188
194
  colSizes: {
189
195
  type: string;
190
196
  additionalProperties: {
@@ -26,6 +26,10 @@ export const LogoRotatorBlock = {
26
26
  },
27
27
  }, count: {
28
28
  type: 'number',
29
+ }, minRotateCount: {
30
+ type: 'number',
31
+ }, maxRotateCount: {
32
+ type: 'number',
29
33
  }, colSizes: {
30
34
  type: 'object',
31
35
  additionalProperties: containerSizesObject,
@@ -130,6 +130,9 @@ export declare const MapBlock: {
130
130
  mediaOnly: {
131
131
  type: string;
132
132
  };
133
+ imageWidthAuto: {
134
+ type: string;
135
+ };
133
136
  disableShadow: {
134
137
  type: string;
135
138
  };
@@ -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
  */
@@ -23,6 +23,8 @@ export const MediaBlockBaseProps = Object.assign(Object.assign(Object.assign(Obj
23
23
  type: 'boolean',
24
24
  }, mediaOnly: {
25
25
  type: 'boolean',
26
+ }, imageWidthAuto: {
27
+ type: 'boolean',
26
28
  },
27
29
  /**
28
30
  * @deprecated use border='none' or border='line' instead
@@ -16,6 +16,9 @@ unpredictable css rules order in build */
16
16
  .pc-media-base__card img {
17
17
  width: 100%;
18
18
  }
19
+ .pc-media-base__card_imageWidthAuto img {
20
+ width: auto;
21
+ }
19
22
  .pc-media-base__card img,
20
23
  .pc-media-base__card video,
21
24
  .pc-media-base__card iframe,
@@ -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'> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doyourjob/gravity-ui-page-constructor",
3
- "version": "5.31.245",
3
+ "version": "5.31.247",
4
4
  "description": "Gravity UI Page Constructor",
5
5
  "license": "MIT",
6
6
  "repository": {