@qrvey/utils 1.15.0-23 → 1.15.0-25

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.
@@ -6,3 +6,4 @@ export * from "./isComplexColumn";
6
6
  export * from "./isCompoundColumn";
7
7
  export * from "./isDateColumn";
8
8
  export * from "./isNumericalColumn";
9
+ export * from "./isStringColumn";
@@ -22,3 +22,4 @@ __exportStar(require("./isComplexColumn"), exports);
22
22
  __exportStar(require("./isCompoundColumn"), exports);
23
23
  __exportStar(require("./isDateColumn"), exports);
24
24
  __exportStar(require("./isNumericalColumn"), exports);
25
+ __exportStar(require("./isStringColumn"), exports);
@@ -37,11 +37,22 @@ export declare const getFixedPositionByDevice: (item: VemFixed, device: CanvasDe
37
37
  * @param [startWithPositionY] - Whether to start the position search for each new element based on its initial Y-coordinate. Defaults to `false`.
38
38
  * @param [findRightToLeft] - Whether to search for positions from right to left. Defaults to `false`.
39
39
  * @param [canvasHeight] - The maximum height of the canvas in pixels. If not provided, the search height is unlimited.
40
- * @returns
40
+ * @returns List of elements with their recalculated positions.
41
41
  */
42
42
  export declare function findFixedAvailablePositions(canvasWidth: number, newElements: VemFixed[], elements: VemFixed[], device: CanvasDevice, startWithPositionY?: boolean, findRightToLeft?: boolean, canvasHeight?: number): VemFixed[];
43
43
  /**
44
- * Adjusts the `width` of a responsive element to fit within the specified canvas width and updates its position.
44
+ * Recalculates the positions of elements on the canvas, preserving the position of those
45
+ * that meet certain conditions (no overflow or overlap). Elements that do not meet these
46
+ * conditions are recalculated to find a new valid position.
47
+ * @param elements - List of elements to recalculate.
48
+ * @param device - The device on which the canvas is being rendered.
49
+ * @param resolution - The resolution of the canvas.
50
+ * @param [canvasHeight] - Optional height of the canvas.
51
+ * @returns - List of elements with their recalculated positions.
52
+ */
53
+ export declare const recalculatePreservingPositions: (elements: VemFixed[], device: CanvasDevice, resolution: number, canvasHeight?: number) => VemFixed[];
54
+ /**
55
+ * Adjusts the `width` of a fixed element to fit within the specified canvas width and updates its position.
45
56
  * @param element - The fixed element to adjust.
46
57
  * @param canvasWidth - The width of the canvas in grid columns.
47
58
  * @param canvasDevice - The target device type (e.g., desktop, tablet, mobile).
@@ -1,7 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sortElementsFromReferencePoint = exports.calculateDistancesToReferencePoint = exports.getFixedGridElementsBottomLimit = exports.calculateWidth = exports.findFixedAvailablePositions = exports.getFixedPositionByDevice = exports.findAvailablePosition = exports.updateFixedPosition = void 0;
3
+ exports.sortElementsFromReferencePoint = exports.calculateDistancesToReferencePoint = exports.getFixedGridElementsBottomLimit = exports.calculateWidth = exports.recalculatePreservingPositions = exports.findFixedAvailablePositions = exports.getFixedPositionByDevice = exports.findAvailablePosition = exports.updateFixedPosition = void 0;
4
+ /* eslint-disable @typescript-eslint/explicit-function-return-type */
5
+ const ICanvasGrid_1 = require("../interfaces/ICanvasGrid");
4
6
  const IVemPosition_1 = require("../interfaces/IVemPosition");
7
+ const fixed_position_1 = require("../utils/fixed.position");
5
8
  const general_1 = require("../utils/general");
6
9
  const overlap_1 = require("../utils/overlap");
7
10
  const position_1 = require("../utils/position");
@@ -90,7 +93,7 @@ const isValidPosition = (position) => {
90
93
  * @param [startWithPositionY] - Whether to start the position search for each new element based on its initial Y-coordinate. Defaults to `false`.
91
94
  * @param [findRightToLeft] - Whether to search for positions from right to left. Defaults to `false`.
92
95
  * @param [canvasHeight] - The maximum height of the canvas in pixels. If not provided, the search height is unlimited.
93
- * @returns
96
+ * @returns List of elements with their recalculated positions.
94
97
  */
95
98
  function findFixedAvailablePositions(canvasWidth, newElements, elements, device, startWithPositionY = false, findRightToLeft = false, canvasHeight) {
96
99
  const processedElements = elements.slice();
@@ -109,7 +112,50 @@ function findFixedAvailablePositions(canvasWidth, newElements, elements, device,
109
112
  }
110
113
  exports.findFixedAvailablePositions = findFixedAvailablePositions;
111
114
  /**
112
- * Adjusts the `width` of a responsive element to fit within the specified canvas width and updates its position.
115
+ * Recalculates the positions of elements on the canvas, preserving the position of those
116
+ * that meet certain conditions (no overflow or overlap). Elements that do not meet these
117
+ * conditions are recalculated to find a new valid position.
118
+ * @param elements - List of elements to recalculate.
119
+ * @param device - The device on which the canvas is being rendered.
120
+ * @param resolution - The resolution of the canvas.
121
+ * @param [canvasHeight] - Optional height of the canvas.
122
+ * @returns - List of elements with their recalculated positions.
123
+ */
124
+ const recalculatePreservingPositions = (elements, device, resolution, canvasHeight) => {
125
+ const keepElementPositions = getElementsWithKeepPosition([...elements], device, resolution, canvasHeight);
126
+ const elementIds = keepElementPositions.map((element) => element.elementId);
127
+ const elementsToCalculate = elements.filter((cElement) => !elementIds.includes(cElement.elementId));
128
+ const defaultElements = keepElementPositions.length
129
+ ? keepElementPositions
130
+ : [];
131
+ const currentElements = canvasHeight ? defaultElements : elements;
132
+ const newElements = findFixedAvailablePositions(resolution, elementsToCalculate, currentElements, device, false, false, canvasHeight);
133
+ return [...keepElementPositions, ...newElements];
134
+ };
135
+ exports.recalculatePreservingPositions = recalculatePreservingPositions;
136
+ /**
137
+ * Filters elements that should retain their current position on the canvas by checking
138
+ * that they do not have overflow (spilling outside the canvas) or overlap (colliding with other elements).
139
+ * @param elements - List of elements to check.
140
+ * @param device - The device on which the canvas is being rendered.
141
+ * @param resolution - The resolution of the canvas.
142
+ * @param [canvasHeight] - Optional height of the canvas.
143
+ * @returns - List of elements that can retain their current position.
144
+ */
145
+ const getElementsWithKeepPosition = (elements, device, resolution, canvasHeight) => {
146
+ const calculatedElements = elements.map((mElement) => {
147
+ const desktopPosition = (0, fixed_position_1.dxGetFixedGridItemDevice)(mElement, ICanvasGrid_1.CanvasDevice.DESKTOP);
148
+ return updateFixedPosition(mElement, desktopPosition, device);
149
+ });
150
+ return calculatedElements.filter((cElement) => {
151
+ const currentElements = calculatedElements.filter((fElement) => fElement.elementId !== cElement.elementId);
152
+ const overflow = (0, fixed_position_1.hasOverflow)(cElement, device, resolution, canvasHeight);
153
+ const overlap = (0, fixed_position_1.hasOverlap)(cElement, currentElements, device);
154
+ return !overflow && !overlap;
155
+ });
156
+ };
157
+ /**
158
+ * Adjusts the `width` of a fixed element to fit within the specified canvas width and updates its position.
113
159
  * @param element - The fixed element to adjust.
114
160
  * @param canvasWidth - The width of the canvas in grid columns.
115
161
  * @param canvasDevice - The target device type (e.g., desktop, tablet, mobile).
@@ -117,11 +163,19 @@ exports.findFixedAvailablePositions = findFixedAvailablePositions;
117
163
  */
118
164
  function calculateWidth(element, canvasWidth, canvasDevice) {
119
165
  const currentPosition = element.position.fixed[canvasDevice];
120
- const fixedWidth = Math.min(currentPosition.width, canvasWidth);
166
+ const fixedWidth = Math.min(currentPosition === null || currentPosition === void 0 ? void 0 : currentPosition.width, canvasWidth);
121
167
  const position = Object.assign(Object.assign({}, currentPosition), { width: fixedWidth });
122
168
  return (0, position_1.setElementPosition)(element, IVemPosition_1.VemPositionType.FIXED, canvasDevice, position);
123
169
  }
124
170
  exports.calculateWidth = calculateWidth;
171
+ /**
172
+ * Retrieves the Y-coordinate of a fixed grid element for a specific device.
173
+ * If `allowNegative` is false (default), the function ensures the Y-coordinate is non-negative.
174
+ * @param element - The element to retrieve the Y-coordinate from.
175
+ * @param device - The device for which the Y-coordinate is calculated.
176
+ * @param [allowNegative] - Whether to allow negative Y-coordinates.
177
+ * @returns - The Y-coordinate of the element.
178
+ */
125
179
  const getFixedGridElementY = (element, device, allowNegative = false) => {
126
180
  var _a;
127
181
  const position = element.position.fixed[device];
@@ -131,6 +185,12 @@ const getFixedGridElementY = (element, device, allowNegative = false) => {
131
185
  }
132
186
  return itemY;
133
187
  };
188
+ /**
189
+ * Retrieves the height of a fixed grid element for a specific device.
190
+ * @param element - The element to retrieve the height from.
191
+ * @param device - The device for which the height is calculated.
192
+ * @returns - The height of the element, or undefined if not defined.
193
+ */
134
194
  const getFixedGridElementHeight = (element, device) => {
135
195
  const position = element.position.fixed[device];
136
196
  return position === null || position === void 0 ? void 0 : position.height;
@@ -3,6 +3,7 @@ interface RecalculateOptions {
3
3
  canvasHeight?: number;
4
4
  sort?: CanvasDevice;
5
5
  allowCopy?: boolean;
6
+ keepPosition?: boolean;
6
7
  }
7
8
  /**
8
9
  * Recalculates the positions of elements on a canvas based on the canvas type.
@@ -18,7 +18,9 @@ const recalculateStrategies = {
18
18
  y: 0,
19
19
  })
20
20
  : changedElements;
21
- return (0, fixed_1.findFixedAvailablePositions)(canvasWidth, orderedElements, currentElements, device, false, false, options === null || options === void 0 ? void 0 : options.canvasHeight);
21
+ return options.canvasHeight
22
+ ? (0, fixed_1.recalculatePreservingPositions)(orderedElements, device, canvasWidth, options.canvasHeight)
23
+ : (0, fixed_1.findFixedAvailablePositions)(canvasWidth, orderedElements, currentElements, device, false, false, options === null || options === void 0 ? void 0 : options.canvasHeight);
22
24
  },
23
25
  responsive: (elements, currentElements, canvasWidth, device, options) => {
24
26
  const isSorted = !currentElements.length;
@@ -19,7 +19,7 @@ const copyDesktopPositionToDevice = (elements, newCanvasDevice, canvasType) => {
19
19
  var _a;
20
20
  if (!((_a = element.position[canvasType]) === null || _a === void 0 ? void 0 : _a[newCanvasDevice])) {
21
21
  const desktopViewPosition = element.position[canvasType][ICanvasGrid_1.CanvasDevice.DESKTOP];
22
- const newDevicePosition = Object.assign(Object.assign({}, desktopViewPosition), defaultPositionMap[canvasType]);
22
+ const newDevicePosition = Object.assign(Object.assign(Object.assign({}, desktopViewPosition), defaultPositionMap[canvasType]), { preCalculated: true });
23
23
  return (0, position_1.setElementPosition)(element, canvasType, newCanvasDevice, newDevicePosition);
24
24
  }
25
25
  return element;
@@ -0,0 +1,12 @@
1
+ import { CanvasDevice, VemFixed, VemPositionFixed } from "../interfaces";
2
+ export declare const hasOverflow: (element: VemFixed, device: CanvasDevice, resolution: number, canvasHeight?: number) => boolean;
3
+ export declare const hasOverlap: (element: VemFixed, elements: VemFixed[], device: CanvasDevice) => number;
4
+ export declare const itemXOverflow: (item: VemFixed, device: CanvasDevice, resolution: number) => boolean;
5
+ export declare const itemYOverflow: (item: VemFixed, device: CanvasDevice, canvasHeight: number) => boolean;
6
+ export declare const checkFixedGridItemsOverlap: (item: VemPositionFixed, itemToCompare: VemPositionFixed) => boolean;
7
+ export declare const dxGetFixedGridItemDevice: (element: VemFixed, device: CanvasDevice) => VemPositionFixed;
8
+ export declare const dxGetFixedGridItemX: (element: VemFixed, device: CanvasDevice, allowNegative?: boolean) => number;
9
+ export declare const dxGetFixedGridItemY: (element: VemFixed, device: CanvasDevice, allowNegative?: boolean) => number;
10
+ export declare const dxGetFixedGridItemZ: (element: VemFixed, device: CanvasDevice) => number;
11
+ export declare const dxGetFixedGridItemHeight: (element: VemFixed, device: CanvasDevice) => number;
12
+ export declare const dxGetFixedGridItemWidth: (element: VemFixed, device: CanvasDevice) => number;
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dxGetFixedGridItemWidth = exports.dxGetFixedGridItemHeight = exports.dxGetFixedGridItemZ = exports.dxGetFixedGridItemY = exports.dxGetFixedGridItemX = exports.dxGetFixedGridItemDevice = exports.checkFixedGridItemsOverlap = exports.itemYOverflow = exports.itemXOverflow = exports.hasOverlap = exports.hasOverflow = void 0;
4
+ const hasOverflow = (element, device, resolution, canvasHeight) => {
5
+ const hasXOverflow = (0, exports.itemXOverflow)(element, device, resolution);
6
+ const hasYOverflow = canvasHeight
7
+ ? (0, exports.itemYOverflow)(element, device, canvasHeight)
8
+ : false;
9
+ return hasXOverflow || hasYOverflow;
10
+ };
11
+ exports.hasOverflow = hasOverflow;
12
+ const hasOverlap = (element, elements, device) => {
13
+ const elementPosition = element.position.fixed[device];
14
+ if (!elementPosition)
15
+ return;
16
+ const overlappingElements = elements.filter((cElement) => (0, exports.checkFixedGridItemsOverlap)(elementPosition, cElement.position.fixed[device]));
17
+ return overlappingElements.length;
18
+ };
19
+ exports.hasOverlap = hasOverlap;
20
+ const itemXOverflow = (item, device, resolution) => {
21
+ const fixedPosition = item.position.fixed;
22
+ return (!!fixedPosition[device] &&
23
+ fixedPosition[device].x + fixedPosition[device].width > resolution);
24
+ };
25
+ exports.itemXOverflow = itemXOverflow;
26
+ const itemYOverflow = (item, device, canvasHeight) => {
27
+ const fixedPosition = item.position.fixed;
28
+ return (!!fixedPosition[device] &&
29
+ fixedPosition[device].y + fixedPosition[device].height > canvasHeight);
30
+ };
31
+ exports.itemYOverflow = itemYOverflow;
32
+ const checkFixedGridItemsOverlap = (item, itemToCompare) => {
33
+ return !(item.x + item.width < itemToCompare.x ||
34
+ item.x > itemToCompare.x + itemToCompare.width ||
35
+ item.y + item.height < itemToCompare.y ||
36
+ item.y > itemToCompare.y + itemToCompare.height);
37
+ };
38
+ exports.checkFixedGridItemsOverlap = checkFixedGridItemsOverlap;
39
+ const dxGetFixedGridItemDevice = (element, device) => {
40
+ return {
41
+ x: (0, exports.dxGetFixedGridItemX)(element, device),
42
+ y: (0, exports.dxGetFixedGridItemY)(element, device),
43
+ z: (0, exports.dxGetFixedGridItemZ)(element, device),
44
+ height: (0, exports.dxGetFixedGridItemHeight)(element, device),
45
+ width: (0, exports.dxGetFixedGridItemWidth)(element, device),
46
+ };
47
+ };
48
+ exports.dxGetFixedGridItemDevice = dxGetFixedGridItemDevice;
49
+ const dxGetFixedGridItemX = (element, device, allowNegative = false) => {
50
+ var _a;
51
+ const position = element.position.fixed[device];
52
+ const itemX = (_a = position === null || position === void 0 ? void 0 : position.x) !== null && _a !== void 0 ? _a : 0;
53
+ if (!allowNegative) {
54
+ return itemX >= 0 ? itemX : 0;
55
+ }
56
+ return itemX;
57
+ };
58
+ exports.dxGetFixedGridItemX = dxGetFixedGridItemX;
59
+ const dxGetFixedGridItemY = (element, device, allowNegative = false) => {
60
+ var _a;
61
+ const position = element.position.fixed[device];
62
+ const itemY = (_a = position === null || position === void 0 ? void 0 : position.y) !== null && _a !== void 0 ? _a : 0;
63
+ if (!allowNegative) {
64
+ return itemY >= 0 ? itemY : 0;
65
+ }
66
+ return itemY;
67
+ };
68
+ exports.dxGetFixedGridItemY = dxGetFixedGridItemY;
69
+ const dxGetFixedGridItemZ = (element, device) => {
70
+ var _a;
71
+ const position = element.position.fixed[device];
72
+ return (_a = position === null || position === void 0 ? void 0 : position.z) !== null && _a !== void 0 ? _a : 1;
73
+ };
74
+ exports.dxGetFixedGridItemZ = dxGetFixedGridItemZ;
75
+ const dxGetFixedGridItemHeight = (element, device) => {
76
+ var _a;
77
+ const position = element.position.fixed[device];
78
+ return (_a = position === null || position === void 0 ? void 0 : position.height) !== null && _a !== void 0 ? _a : 400;
79
+ };
80
+ exports.dxGetFixedGridItemHeight = dxGetFixedGridItemHeight;
81
+ const dxGetFixedGridItemWidth = (element, device) => {
82
+ var _a;
83
+ const position = element.position.fixed[device];
84
+ return (_a = position === null || position === void 0 ? void 0 : position.width) !== null && _a !== void 0 ? _a : 400;
85
+ };
86
+ exports.dxGetFixedGridItemWidth = dxGetFixedGridItemWidth;
@@ -6,3 +6,4 @@ export * from "./isComplexColumn";
6
6
  export * from "./isCompoundColumn";
7
7
  export * from "./isDateColumn";
8
8
  export * from "./isNumericalColumn";
9
+ export * from "./isStringColumn";
@@ -6,3 +6,4 @@ export * from "./isComplexColumn";
6
6
  export * from "./isCompoundColumn";
7
7
  export * from "./isDateColumn";
8
8
  export * from "./isNumericalColumn";
9
+ export * from "./isStringColumn";
@@ -37,11 +37,22 @@ export declare const getFixedPositionByDevice: (item: VemFixed, device: CanvasDe
37
37
  * @param [startWithPositionY] - Whether to start the position search for each new element based on its initial Y-coordinate. Defaults to `false`.
38
38
  * @param [findRightToLeft] - Whether to search for positions from right to left. Defaults to `false`.
39
39
  * @param [canvasHeight] - The maximum height of the canvas in pixels. If not provided, the search height is unlimited.
40
- * @returns
40
+ * @returns List of elements with their recalculated positions.
41
41
  */
42
42
  export declare function findFixedAvailablePositions(canvasWidth: number, newElements: VemFixed[], elements: VemFixed[], device: CanvasDevice, startWithPositionY?: boolean, findRightToLeft?: boolean, canvasHeight?: number): VemFixed[];
43
43
  /**
44
- * Adjusts the `width` of a responsive element to fit within the specified canvas width and updates its position.
44
+ * Recalculates the positions of elements on the canvas, preserving the position of those
45
+ * that meet certain conditions (no overflow or overlap). Elements that do not meet these
46
+ * conditions are recalculated to find a new valid position.
47
+ * @param elements - List of elements to recalculate.
48
+ * @param device - The device on which the canvas is being rendered.
49
+ * @param resolution - The resolution of the canvas.
50
+ * @param [canvasHeight] - Optional height of the canvas.
51
+ * @returns - List of elements with their recalculated positions.
52
+ */
53
+ export declare const recalculatePreservingPositions: (elements: VemFixed[], device: CanvasDevice, resolution: number, canvasHeight?: number) => VemFixed[];
54
+ /**
55
+ * Adjusts the `width` of a fixed element to fit within the specified canvas width and updates its position.
45
56
  * @param element - The fixed element to adjust.
46
57
  * @param canvasWidth - The width of the canvas in grid columns.
47
58
  * @param canvasDevice - The target device type (e.g., desktop, tablet, mobile).
@@ -1,4 +1,7 @@
1
+ /* eslint-disable @typescript-eslint/explicit-function-return-type */
2
+ import { CanvasDevice } from "../interfaces/ICanvasGrid";
1
3
  import { VemPositionType } from "../interfaces/IVemPosition";
4
+ import { dxGetFixedGridItemDevice, hasOverflow, hasOverlap, } from "../utils/fixed.position";
2
5
  import { sortByDistanceFunction } from "../utils/general";
3
6
  import { OverlapIntervalTree } from "../utils/overlap";
4
7
  import { setElementPosition } from "../utils/position";
@@ -84,7 +87,7 @@ const isValidPosition = (position) => {
84
87
  * @param [startWithPositionY] - Whether to start the position search for each new element based on its initial Y-coordinate. Defaults to `false`.
85
88
  * @param [findRightToLeft] - Whether to search for positions from right to left. Defaults to `false`.
86
89
  * @param [canvasHeight] - The maximum height of the canvas in pixels. If not provided, the search height is unlimited.
87
- * @returns
90
+ * @returns List of elements with their recalculated positions.
88
91
  */
89
92
  export function findFixedAvailablePositions(canvasWidth, newElements, elements, device, startWithPositionY = false, findRightToLeft = false, canvasHeight) {
90
93
  const processedElements = elements.slice();
@@ -102,7 +105,49 @@ export function findFixedAvailablePositions(canvasWidth, newElements, elements,
102
105
  return resultElems;
103
106
  }
104
107
  /**
105
- * Adjusts the `width` of a responsive element to fit within the specified canvas width and updates its position.
108
+ * Recalculates the positions of elements on the canvas, preserving the position of those
109
+ * that meet certain conditions (no overflow or overlap). Elements that do not meet these
110
+ * conditions are recalculated to find a new valid position.
111
+ * @param elements - List of elements to recalculate.
112
+ * @param device - The device on which the canvas is being rendered.
113
+ * @param resolution - The resolution of the canvas.
114
+ * @param [canvasHeight] - Optional height of the canvas.
115
+ * @returns - List of elements with their recalculated positions.
116
+ */
117
+ export const recalculatePreservingPositions = (elements, device, resolution, canvasHeight) => {
118
+ const keepElementPositions = getElementsWithKeepPosition([...elements], device, resolution, canvasHeight);
119
+ const elementIds = keepElementPositions.map((element) => element.elementId);
120
+ const elementsToCalculate = elements.filter((cElement) => !elementIds.includes(cElement.elementId));
121
+ const defaultElements = keepElementPositions.length
122
+ ? keepElementPositions
123
+ : [];
124
+ const currentElements = canvasHeight ? defaultElements : elements;
125
+ const newElements = findFixedAvailablePositions(resolution, elementsToCalculate, currentElements, device, false, false, canvasHeight);
126
+ return [...keepElementPositions, ...newElements];
127
+ };
128
+ /**
129
+ * Filters elements that should retain their current position on the canvas by checking
130
+ * that they do not have overflow (spilling outside the canvas) or overlap (colliding with other elements).
131
+ * @param elements - List of elements to check.
132
+ * @param device - The device on which the canvas is being rendered.
133
+ * @param resolution - The resolution of the canvas.
134
+ * @param [canvasHeight] - Optional height of the canvas.
135
+ * @returns - List of elements that can retain their current position.
136
+ */
137
+ const getElementsWithKeepPosition = (elements, device, resolution, canvasHeight) => {
138
+ const calculatedElements = elements.map((mElement) => {
139
+ const desktopPosition = dxGetFixedGridItemDevice(mElement, CanvasDevice.DESKTOP);
140
+ return updateFixedPosition(mElement, desktopPosition, device);
141
+ });
142
+ return calculatedElements.filter((cElement) => {
143
+ const currentElements = calculatedElements.filter((fElement) => fElement.elementId !== cElement.elementId);
144
+ const overflow = hasOverflow(cElement, device, resolution, canvasHeight);
145
+ const overlap = hasOverlap(cElement, currentElements, device);
146
+ return !overflow && !overlap;
147
+ });
148
+ };
149
+ /**
150
+ * Adjusts the `width` of a fixed element to fit within the specified canvas width and updates its position.
106
151
  * @param element - The fixed element to adjust.
107
152
  * @param canvasWidth - The width of the canvas in grid columns.
108
153
  * @param canvasDevice - The target device type (e.g., desktop, tablet, mobile).
@@ -110,10 +155,18 @@ export function findFixedAvailablePositions(canvasWidth, newElements, elements,
110
155
  */
111
156
  export function calculateWidth(element, canvasWidth, canvasDevice) {
112
157
  const currentPosition = element.position.fixed[canvasDevice];
113
- const fixedWidth = Math.min(currentPosition.width, canvasWidth);
158
+ const fixedWidth = Math.min(currentPosition === null || currentPosition === void 0 ? void 0 : currentPosition.width, canvasWidth);
114
159
  const position = Object.assign(Object.assign({}, currentPosition), { width: fixedWidth });
115
160
  return setElementPosition(element, VemPositionType.FIXED, canvasDevice, position);
116
161
  }
162
+ /**
163
+ * Retrieves the Y-coordinate of a fixed grid element for a specific device.
164
+ * If `allowNegative` is false (default), the function ensures the Y-coordinate is non-negative.
165
+ * @param element - The element to retrieve the Y-coordinate from.
166
+ * @param device - The device for which the Y-coordinate is calculated.
167
+ * @param [allowNegative] - Whether to allow negative Y-coordinates.
168
+ * @returns - The Y-coordinate of the element.
169
+ */
117
170
  const getFixedGridElementY = (element, device, allowNegative = false) => {
118
171
  var _a;
119
172
  const position = element.position.fixed[device];
@@ -123,6 +176,12 @@ const getFixedGridElementY = (element, device, allowNegative = false) => {
123
176
  }
124
177
  return itemY;
125
178
  };
179
+ /**
180
+ * Retrieves the height of a fixed grid element for a specific device.
181
+ * @param element - The element to retrieve the height from.
182
+ * @param device - The device for which the height is calculated.
183
+ * @returns - The height of the element, or undefined if not defined.
184
+ */
126
185
  const getFixedGridElementHeight = (element, device) => {
127
186
  const position = element.position.fixed[device];
128
187
  return position === null || position === void 0 ? void 0 : position.height;
@@ -3,6 +3,7 @@ interface RecalculateOptions {
3
3
  canvasHeight?: number;
4
4
  sort?: CanvasDevice;
5
5
  allowCopy?: boolean;
6
+ keepPosition?: boolean;
6
7
  }
7
8
  /**
8
9
  * Recalculates the positions of elements on a canvas based on the canvas type.
@@ -1,4 +1,4 @@
1
- import { findFixedAvailablePositions, getFixedGridElementsBottomLimit, sortElementsFromReferencePoint, } from "./fixed";
1
+ import { findFixedAvailablePositions, getFixedGridElementsBottomLimit, recalculatePreservingPositions, sortElementsFromReferencePoint, } from "./fixed";
2
2
  import { findResponsiveAvailablePositions, getResponsiveGridElementsBottomLimit, sortResponsiveElements, } from "./responsive";
3
3
  import { CanvasDevice, VemPositionType, } from "../interfaces";
4
4
  import { copyDesktopPositionToDevice } from "../utils/element";
@@ -15,7 +15,9 @@ const recalculateStrategies = {
15
15
  y: 0,
16
16
  })
17
17
  : changedElements;
18
- return findFixedAvailablePositions(canvasWidth, orderedElements, currentElements, device, false, false, options === null || options === void 0 ? void 0 : options.canvasHeight);
18
+ return options.canvasHeight
19
+ ? recalculatePreservingPositions(orderedElements, device, canvasWidth, options.canvasHeight)
20
+ : findFixedAvailablePositions(canvasWidth, orderedElements, currentElements, device, false, false, options === null || options === void 0 ? void 0 : options.canvasHeight);
19
21
  },
20
22
  responsive: (elements, currentElements, canvasWidth, device, options) => {
21
23
  const isSorted = !currentElements.length;
@@ -16,7 +16,7 @@ export const copyDesktopPositionToDevice = (elements, newCanvasDevice, canvasTyp
16
16
  var _a;
17
17
  if (!((_a = element.position[canvasType]) === null || _a === void 0 ? void 0 : _a[newCanvasDevice])) {
18
18
  const desktopViewPosition = element.position[canvasType][CanvasDevice.DESKTOP];
19
- const newDevicePosition = Object.assign(Object.assign({}, desktopViewPosition), defaultPositionMap[canvasType]);
19
+ const newDevicePosition = Object.assign(Object.assign(Object.assign({}, desktopViewPosition), defaultPositionMap[canvasType]), { preCalculated: true });
20
20
  return setElementPosition(element, canvasType, newCanvasDevice, newDevicePosition);
21
21
  }
22
22
  return element;
@@ -0,0 +1,12 @@
1
+ import { CanvasDevice, VemFixed, VemPositionFixed } from "../interfaces";
2
+ export declare const hasOverflow: (element: VemFixed, device: CanvasDevice, resolution: number, canvasHeight?: number) => boolean;
3
+ export declare const hasOverlap: (element: VemFixed, elements: VemFixed[], device: CanvasDevice) => number;
4
+ export declare const itemXOverflow: (item: VemFixed, device: CanvasDevice, resolution: number) => boolean;
5
+ export declare const itemYOverflow: (item: VemFixed, device: CanvasDevice, canvasHeight: number) => boolean;
6
+ export declare const checkFixedGridItemsOverlap: (item: VemPositionFixed, itemToCompare: VemPositionFixed) => boolean;
7
+ export declare const dxGetFixedGridItemDevice: (element: VemFixed, device: CanvasDevice) => VemPositionFixed;
8
+ export declare const dxGetFixedGridItemX: (element: VemFixed, device: CanvasDevice, allowNegative?: boolean) => number;
9
+ export declare const dxGetFixedGridItemY: (element: VemFixed, device: CanvasDevice, allowNegative?: boolean) => number;
10
+ export declare const dxGetFixedGridItemZ: (element: VemFixed, device: CanvasDevice) => number;
11
+ export declare const dxGetFixedGridItemHeight: (element: VemFixed, device: CanvasDevice) => number;
12
+ export declare const dxGetFixedGridItemWidth: (element: VemFixed, device: CanvasDevice) => number;
@@ -0,0 +1,72 @@
1
+ export const hasOverflow = (element, device, resolution, canvasHeight) => {
2
+ const hasXOverflow = itemXOverflow(element, device, resolution);
3
+ const hasYOverflow = canvasHeight
4
+ ? itemYOverflow(element, device, canvasHeight)
5
+ : false;
6
+ return hasXOverflow || hasYOverflow;
7
+ };
8
+ export const hasOverlap = (element, elements, device) => {
9
+ const elementPosition = element.position.fixed[device];
10
+ if (!elementPosition)
11
+ return;
12
+ const overlappingElements = elements.filter((cElement) => checkFixedGridItemsOverlap(elementPosition, cElement.position.fixed[device]));
13
+ return overlappingElements.length;
14
+ };
15
+ export const itemXOverflow = (item, device, resolution) => {
16
+ const fixedPosition = item.position.fixed;
17
+ return (!!fixedPosition[device] &&
18
+ fixedPosition[device].x + fixedPosition[device].width > resolution);
19
+ };
20
+ export const itemYOverflow = (item, device, canvasHeight) => {
21
+ const fixedPosition = item.position.fixed;
22
+ return (!!fixedPosition[device] &&
23
+ fixedPosition[device].y + fixedPosition[device].height > canvasHeight);
24
+ };
25
+ export const checkFixedGridItemsOverlap = (item, itemToCompare) => {
26
+ return !(item.x + item.width < itemToCompare.x ||
27
+ item.x > itemToCompare.x + itemToCompare.width ||
28
+ item.y + item.height < itemToCompare.y ||
29
+ item.y > itemToCompare.y + itemToCompare.height);
30
+ };
31
+ export const dxGetFixedGridItemDevice = (element, device) => {
32
+ return {
33
+ x: dxGetFixedGridItemX(element, device),
34
+ y: dxGetFixedGridItemY(element, device),
35
+ z: dxGetFixedGridItemZ(element, device),
36
+ height: dxGetFixedGridItemHeight(element, device),
37
+ width: dxGetFixedGridItemWidth(element, device),
38
+ };
39
+ };
40
+ export const dxGetFixedGridItemX = (element, device, allowNegative = false) => {
41
+ var _a;
42
+ const position = element.position.fixed[device];
43
+ const itemX = (_a = position === null || position === void 0 ? void 0 : position.x) !== null && _a !== void 0 ? _a : 0;
44
+ if (!allowNegative) {
45
+ return itemX >= 0 ? itemX : 0;
46
+ }
47
+ return itemX;
48
+ };
49
+ export const dxGetFixedGridItemY = (element, device, allowNegative = false) => {
50
+ var _a;
51
+ const position = element.position.fixed[device];
52
+ const itemY = (_a = position === null || position === void 0 ? void 0 : position.y) !== null && _a !== void 0 ? _a : 0;
53
+ if (!allowNegative) {
54
+ return itemY >= 0 ? itemY : 0;
55
+ }
56
+ return itemY;
57
+ };
58
+ export const dxGetFixedGridItemZ = (element, device) => {
59
+ var _a;
60
+ const position = element.position.fixed[device];
61
+ return (_a = position === null || position === void 0 ? void 0 : position.z) !== null && _a !== void 0 ? _a : 1;
62
+ };
63
+ export const dxGetFixedGridItemHeight = (element, device) => {
64
+ var _a;
65
+ const position = element.position.fixed[device];
66
+ return (_a = position === null || position === void 0 ? void 0 : position.height) !== null && _a !== void 0 ? _a : 400;
67
+ };
68
+ export const dxGetFixedGridItemWidth = (element, device) => {
69
+ var _a;
70
+ const position = element.position.fixed[device];
71
+ return (_a = position === null || position === void 0 ? void 0 : position.width) !== null && _a !== void 0 ? _a : 400;
72
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qrvey/utils",
3
- "version": "1.15.0-23",
3
+ "version": "1.15.0-25",
4
4
  "description": "Helper, Utils for all Qrvey Projects",
5
5
  "homepage": "https://bitbucket.org/qrvey/qrvey_utils/wiki/Home",
6
6
  "main": "dist/index.js",