@qrvey/utils 1.15.0-13 → 1.15.0-15

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.
@@ -40,9 +40,46 @@ export declare const getFixedPositionByDevice: (item: VemFixed, device: CanvasDe
40
40
  * @returns
41
41
  */
42
42
  export declare function findFixedAvailablePositions(canvasWidth: number, newElements: VemFixed[], elements: VemFixed[], device: CanvasDevice, startWithPositionY?: boolean, findRightToLeft?: boolean, canvasHeight?: number): VemFixed[];
43
+ /**
44
+ * Adjusts the `width` of a responsive element to fit within the specified canvas width and updates its position.
45
+ * @param element - The fixed element to adjust.
46
+ * @param canvasWidth - The width of the canvas in grid columns.
47
+ * @param canvasDevice - The target device type (e.g., desktop, tablet, mobile).
48
+ * @returns - The updated responsive element with an adjusted `width`.
49
+ */
50
+ export declare function calculateWidth(element: VemFixed, canvasWidth: number, canvasDevice: CanvasDevice): VemFixed;
43
51
  /**
44
52
  * @param elements elements to calculate
45
53
  * @param device current device
46
54
  * @returns height
47
55
  */
48
56
  export declare const getFixedGridElementsBottomLimit: (elements: VemFixed[], device: CanvasDevice) => number;
57
+ /**
58
+ * Calculates distances of elements from a given reference point on the canvas device.
59
+ * @param elements - Array of `VemFixed` elements to calculate distances for.
60
+ * @param device - Canvas device providing the coordinates of the elements.
61
+ * @param referencePoint - The reference point to calculate distances from.
62
+ * @param referencePoint.x
63
+ * @param referencePoint.y
64
+ * @returns An array of objects containing the original elements and their calculated distances from the reference point.
65
+ */
66
+ export declare const calculateDistancesToReferencePoint: (elements: VemFixed[], device: CanvasDevice, referencePoint: {
67
+ x: number;
68
+ y: number;
69
+ }) => {
70
+ distance: number;
71
+ element: VemFixed;
72
+ }[];
73
+ /**
74
+ * Sorts elements based on their distance from a reference point on the canvas.
75
+ * @param elements - Array of `VemFixed` elements to be sorted.
76
+ * @param device - Canvas device providing the coordinates of the elements.
77
+ * @param referencePoint - The reference point to calculate distances from.
78
+ * @param referencePoint.x
79
+ * @param referencePoint.y
80
+ * @returns An array of `VemFixed` elements sorted by their distance from the reference point (0, 0).
81
+ */
82
+ export declare const sortElementsFromReferencePoint: (elements: VemFixed<unknown>[], device: CanvasDevice, referencePoint: {
83
+ x: number;
84
+ y: number;
85
+ }) => VemFixed<unknown>[];
@@ -1,7 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getFixedGridElementsBottomLimit = exports.findFixedAvailablePositions = exports.getFixedPositionByDevice = exports.findAvailablePosition = exports.updateFixedPosition = void 0;
3
+ exports.sortElementsFromReferencePoint = exports.calculateDistancesToReferencePoint = exports.getFixedGridElementsBottomLimit = exports.calculateWidth = exports.findFixedAvailablePositions = exports.getFixedPositionByDevice = exports.findAvailablePosition = exports.updateFixedPosition = void 0;
4
+ const IVemPosition_1 = require("../interfaces/IVemPosition");
5
+ const general_1 = require("../utils/general");
4
6
  const overlap_1 = require("../utils/overlap");
7
+ const position_1 = require("../utils/position");
5
8
  const SPACE_DELTA = 10;
6
9
  /**
7
10
  * update the position for a specific device
@@ -96,14 +99,29 @@ function findFixedAvailablePositions(canvasWidth, newElements, elements, device,
96
99
  const initialY = startWithPositionY
97
100
  ? nElement.position.fixed[device].y
98
101
  : 0;
99
- const availablePosition = findAvailablePosition(canvasWidth, nElement, processedElements, device, { initialY, findRightToLeft, canvasHeight });
100
- const newElemWithPosition = updateFixedPosition(nElement, availablePosition, device);
102
+ const newElement = calculateWidth(nElement, canvasWidth, device);
103
+ const availablePosition = findAvailablePosition(canvasWidth, newElement, processedElements, device, { initialY, findRightToLeft, canvasHeight });
104
+ const newElemWithPosition = updateFixedPosition(newElement, availablePosition, device);
101
105
  resultElems.push(newElemWithPosition);
102
106
  processedElements.push(newElemWithPosition);
103
107
  });
104
108
  return resultElems;
105
109
  }
106
110
  exports.findFixedAvailablePositions = findFixedAvailablePositions;
111
+ /**
112
+ * Adjusts the `width` of a responsive element to fit within the specified canvas width and updates its position.
113
+ * @param element - The fixed element to adjust.
114
+ * @param canvasWidth - The width of the canvas in grid columns.
115
+ * @param canvasDevice - The target device type (e.g., desktop, tablet, mobile).
116
+ * @returns - The updated responsive element with an adjusted `width`.
117
+ */
118
+ function calculateWidth(element, canvasWidth, canvasDevice) {
119
+ const currentPosition = element.position.fixed[canvasDevice];
120
+ const fixedWidth = Math.min(currentPosition.width, canvasWidth);
121
+ const position = Object.assign(Object.assign({}, currentPosition), { width: fixedWidth });
122
+ return (0, position_1.setElementPosition)(element, IVemPosition_1.VemPositionType.FIXED, canvasDevice, position);
123
+ }
124
+ exports.calculateWidth = calculateWidth;
107
125
  const getFixedGridElementY = (element, device, allowNegative = false) => {
108
126
  var _a;
109
127
  const position = element.position.fixed[device];
@@ -129,3 +147,42 @@ const getFixedGridElementsBottomLimit = (elements, device) => {
129
147
  getFixedGridElementHeight(element, device)));
130
148
  };
131
149
  exports.getFixedGridElementsBottomLimit = getFixedGridElementsBottomLimit;
150
+ /**
151
+ * Calculates distances of elements from a given reference point on the canvas device.
152
+ * @param elements - Array of `VemFixed` elements to calculate distances for.
153
+ * @param device - Canvas device providing the coordinates of the elements.
154
+ * @param referencePoint - The reference point to calculate distances from.
155
+ * @param referencePoint.x
156
+ * @param referencePoint.y
157
+ * @returns An array of objects containing the original elements and their calculated distances from the reference point.
158
+ */
159
+ const calculateDistancesToReferencePoint = (elements, device, referencePoint) => {
160
+ return elements.map((element) => {
161
+ const elementPosition = (0, exports.getFixedPositionByDevice)(element, device);
162
+ if (!elementPosition) {
163
+ throw new Error(`Position for device ${device} is undefined for element with Id ${element.elementId}.`);
164
+ }
165
+ const distance = Math.pow(referencePoint.x - elementPosition.x, 2) +
166
+ Math.pow(referencePoint.y - elementPosition.y, 2);
167
+ return {
168
+ distance,
169
+ element,
170
+ };
171
+ });
172
+ };
173
+ exports.calculateDistancesToReferencePoint = calculateDistancesToReferencePoint;
174
+ /**
175
+ * Sorts elements based on their distance from a reference point on the canvas.
176
+ * @param elements - Array of `VemFixed` elements to be sorted.
177
+ * @param device - Canvas device providing the coordinates of the elements.
178
+ * @param referencePoint - The reference point to calculate distances from.
179
+ * @param referencePoint.x
180
+ * @param referencePoint.y
181
+ * @returns An array of `VemFixed` elements sorted by their distance from the reference point (0, 0).
182
+ */
183
+ const sortElementsFromReferencePoint = (elements, device, referencePoint) => {
184
+ const calculatedElements = (0, exports.calculateDistancesToReferencePoint)(elements, device, referencePoint);
185
+ const sortedElements = [...calculatedElements].sort(general_1.sortByDistanceFunction);
186
+ return sortedElements.map((element) => element.element);
187
+ };
188
+ exports.sortElementsFromReferencePoint = sortElementsFromReferencePoint;
@@ -1,13 +1,19 @@
1
1
  import { CanvasDevice, Vem } from "../interfaces";
2
+ interface RecalculateOptions {
3
+ canvasHeight?: number;
4
+ sort?: CanvasDevice;
5
+ }
2
6
  /**
3
7
  * Recalculates the positions of elements on a canvas based on the canvas type.
4
8
  * @param elements - The list of elements to be recalculated. Each element has properties based on its type.
5
9
  * @param canvasWidth - The width of the canvas in pixels.
6
10
  * @param canvasType - The type of canvas (e.g., "fixed") that determines how positions are recalculated.
7
11
  * @param device - The device type (e.g., desktop, tablet, mobile) for determining element positions.
12
+ * @param canvasHeight - variable for the canvas with header component
13
+ * @param options
8
14
  * @returns - A list of elements with updated positions if the canvas type is "fixed" or "responsive".
9
15
  */
10
- export declare function recalculateElements(elements: Vem[], canvasWidth: number, canvasType: string, device: CanvasDevice): Vem[];
16
+ export declare function recalculateElements(elements: Vem[], canvasWidth: number, canvasType: string, device: CanvasDevice, options?: RecalculateOptions): Vem[];
11
17
  /**
12
18
  * The calculation is delegated to a specific strategy based on the `canvasType`.
13
19
  * @param elements - The list of elements in the canvas.
@@ -17,3 +23,4 @@ export declare function recalculateElements(elements: Vem[], canvasWidth: number
17
23
  * @returns - The calculated canvas height based on the selected strategy. Returns an empty array if no strategy is found.
18
24
  */
19
25
  export declare function calculateCanvasHeight(elements: Vem[], canvasType: string, device: CanvasDevice, rowGap?: number): number;
26
+ export {};
@@ -6,13 +6,16 @@ const responsive_1 = require("./responsive");
6
6
  const interfaces_1 = require("../interfaces");
7
7
  const element_1 = require("../utils/element");
8
8
  const recalculateStrategies = {
9
- fixed: (elements, canvasWidth, device) => {
9
+ fixed: (elements, canvasWidth, device, options) => {
10
10
  const changedElements = (0, element_1.copyDesktopPositionToDevice)(elements, device, interfaces_1.VemPositionType.FIXED);
11
- return (0, fixed_1.findFixedAvailablePositions)(canvasWidth, changedElements, [], device);
11
+ // sort elements
12
+ const orderedElements = (0, fixed_1.sortElementsFromReferencePoint)(changedElements, options.sort, { x: 0, y: 0 });
13
+ return (0, fixed_1.findFixedAvailablePositions)(canvasWidth, orderedElements, [], device, false, false, options === null || options === void 0 ? void 0 : options.canvasHeight);
12
14
  },
13
- responsive: (elements, canvasWidth, device) => {
15
+ responsive: (elements, canvasWidth, device, options) => {
14
16
  const changedElements = (0, element_1.copyDesktopPositionToDevice)(elements, device, interfaces_1.VemPositionType.RESPONSIVE);
15
- return (0, responsive_1.findResponsiveAvailablePositions)(canvasWidth, changedElements, [], device);
17
+ const orderedElements = (0, responsive_1.sortResponsiveElements)(changedElements, options.sort);
18
+ return (0, responsive_1.findResponsiveAvailablePositions)(canvasWidth, orderedElements, [], device);
16
19
  },
17
20
  };
18
21
  const calculateCanvasHeightStrategies = {
@@ -29,14 +32,20 @@ const calculateCanvasHeightStrategies = {
29
32
  * @param canvasWidth - The width of the canvas in pixels.
30
33
  * @param canvasType - The type of canvas (e.g., "fixed") that determines how positions are recalculated.
31
34
  * @param device - The device type (e.g., desktop, tablet, mobile) for determining element positions.
35
+ * @param canvasHeight - variable for the canvas with header component
36
+ * @param options
32
37
  * @returns - A list of elements with updated positions if the canvas type is "fixed" or "responsive".
33
38
  */
34
- function recalculateElements(elements, canvasWidth, canvasType, device) {
39
+ function recalculateElements(elements, canvasWidth, canvasType, device, options) {
35
40
  const strategy = recalculateStrategies[canvasType];
36
41
  if (!strategy) {
37
42
  return [];
38
43
  }
39
- return strategy(elements, canvasWidth, device);
44
+ const defaultOptions = {
45
+ sort: interfaces_1.CanvasDevice.DESKTOP,
46
+ };
47
+ const calculatedOptions = Object.assign(Object.assign({}, defaultOptions), options);
48
+ return strategy(elements, canvasWidth, device, calculatedOptions);
40
49
  }
41
50
  exports.recalculateElements = recalculateElements;
42
51
  /**
@@ -39,3 +39,49 @@ export declare function findResponsiveAvailablePositions(canvasWidth: number, ne
39
39
  */
40
40
  export declare function calculateColSpan(element: VemResponsive, canvasWidth: number, canvasDevice: CanvasDevice): VemResponsive;
41
41
  export declare const getResponsiveGridElementsBottomLimit: (elements: VemResponsive[], device: CanvasDevice, rowGap: number) => number;
42
+ /**
43
+ * Calculates the distances of elements from a reference point and returns a list of objects
44
+ * containing the calculated distance and the corresponding element.
45
+ * @param elements - An array of `VemResponsive` objects. Each object represents an element with
46
+ * a `position` property that contains responsive positions for various devices.
47
+ * @param device - The specific device type (key of `CanvasDevice`) to determine the responsive position.
48
+ * @param referencePoint - An object representing the reference point with `x` and `y` coordinates.
49
+ * @param referencePoint.x
50
+ * @param referencePoint.y
51
+ * @returns - An array of objects, where each object contains:
52
+ * - `distance`: The squared Euclidean distance from the reference point.
53
+ * - `element`: The corresponding `VemResponsive` object.
54
+ */
55
+ export declare const calculateDistancesToReferencePoint: (elements: VemResponsive[], device: CanvasDevice, referencePoint: {
56
+ x: number;
57
+ y: number;
58
+ }) => {
59
+ distance: number;
60
+ element: VemResponsive;
61
+ }[];
62
+ /**
63
+ /**
64
+ Sorts objects containing a `distance` and `element` by distance in ascending order.
65
+ If two objects have the same distance, it resolves the tie by comparing the `colStart` property
66
+ of their responsive positions for the `DESKTOP` device.
67
+ * @param a - An object containing:
68
+ * - `distance`: The calculated distance from a reference point.
69
+ * - `element`: A `VemResponsive` object with responsive position data.
70
+ * @param b - Another object with the same structure as `a`.
71
+ * @param a.element
72
+ * @param a.distance
73
+ * @param _device - The device type (of type `CanvasDevice`). Currently unused in this function.
74
+ * @param b.distance
75
+ * @param b.element
76
+ * @returns - A negative number if `a` should come before `b`,
77
+ * a positive number if `a` should come after `b`,
78
+ * or 0 if they have the same distance and `colStart` values.
79
+ */
80
+ export declare const sortByDistanceInResponsiveFunction: (a: {
81
+ distance: number;
82
+ element: VemResponsive;
83
+ }, b: {
84
+ distance: number;
85
+ element: VemResponsive;
86
+ }, _device: CanvasDevice) => number;
87
+ export declare const sortResponsiveElements: (elements: VemResponsive<unknown>[], sortByDevice?: CanvasDevice) => VemResponsive<unknown>[];
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getResponsiveGridElementsBottomLimit = exports.calculateColSpan = exports.findResponsiveAvailablePositions = exports.updateResponsivePosition = exports.findAvailablePosition = void 0;
3
+ exports.sortResponsiveElements = exports.sortByDistanceInResponsiveFunction = exports.calculateDistancesToReferencePoint = exports.getResponsiveGridElementsBottomLimit = exports.calculateColSpan = exports.findResponsiveAvailablePositions = exports.updateResponsivePosition = exports.findAvailablePosition = void 0;
4
+ const ICanvasGrid_1 = require("../interfaces/ICanvasGrid");
4
5
  const IVemPosition_1 = require("../interfaces/IVemPosition");
5
6
  const overlap_1 = require("../utils/overlap");
6
7
  const position_1 = require("../utils/position");
@@ -100,3 +101,66 @@ const getResponsiveGridElementsBottomLimit = (elements, device, rowGap) => {
100
101
  return Math.max(...mappedElements);
101
102
  };
102
103
  exports.getResponsiveGridElementsBottomLimit = getResponsiveGridElementsBottomLimit;
104
+ /**
105
+ * Calculates the distances of elements from a reference point and returns a list of objects
106
+ * containing the calculated distance and the corresponding element.
107
+ * @param elements - An array of `VemResponsive` objects. Each object represents an element with
108
+ * a `position` property that contains responsive positions for various devices.
109
+ * @param device - The specific device type (key of `CanvasDevice`) to determine the responsive position.
110
+ * @param referencePoint - An object representing the reference point with `x` and `y` coordinates.
111
+ * @param referencePoint.x
112
+ * @param referencePoint.y
113
+ * @returns - An array of objects, where each object contains:
114
+ * - `distance`: The squared Euclidean distance from the reference point.
115
+ * - `element`: The corresponding `VemResponsive` object.
116
+ */
117
+ const calculateDistancesToReferencePoint = (elements, device, referencePoint) => {
118
+ return elements.map((element) => {
119
+ var _a, _b;
120
+ const position = (_b = (_a = element.position) === null || _a === void 0 ? void 0 : _a.responsive) === null || _b === void 0 ? void 0 : _b[device];
121
+ if (!position) {
122
+ throw new Error(`Position for device ${device} is undefined for element with Id ${element.elementId}.`);
123
+ }
124
+ const distance = Math.pow(referencePoint.x - position.colStart, 2) +
125
+ Math.pow(referencePoint.y - position.rowStart, 2);
126
+ return {
127
+ distance,
128
+ element,
129
+ };
130
+ });
131
+ };
132
+ exports.calculateDistancesToReferencePoint = calculateDistancesToReferencePoint;
133
+ /**
134
+ /**
135
+ Sorts objects containing a `distance` and `element` by distance in ascending order.
136
+ If two objects have the same distance, it resolves the tie by comparing the `colStart` property
137
+ of their responsive positions for the `DESKTOP` device.
138
+ * @param a - An object containing:
139
+ * - `distance`: The calculated distance from a reference point.
140
+ * - `element`: A `VemResponsive` object with responsive position data.
141
+ * @param b - Another object with the same structure as `a`.
142
+ * @param a.element
143
+ * @param a.distance
144
+ * @param _device - The device type (of type `CanvasDevice`). Currently unused in this function.
145
+ * @param b.distance
146
+ * @param b.element
147
+ * @returns - A negative number if `a` should come before `b`,
148
+ * a positive number if `a` should come after `b`,
149
+ * or 0 if they have the same distance and `colStart` values.
150
+ */
151
+ const sortByDistanceInResponsiveFunction = (a, b, _device) => {
152
+ if (a.distance === b.distance) {
153
+ return (a.element.position.responsive[ICanvasGrid_1.CanvasDevice.DESKTOP].colStart -
154
+ b.element.position.responsive[ICanvasGrid_1.CanvasDevice.DESKTOP].colStart);
155
+ }
156
+ return a.distance - b.distance;
157
+ };
158
+ exports.sortByDistanceInResponsiveFunction = sortByDistanceInResponsiveFunction;
159
+ const sortResponsiveElements = (elements, sortByDevice) => {
160
+ const sortedElements = (0, exports.calculateDistancesToReferencePoint)(elements, sortByDevice, {
161
+ x: 1,
162
+ y: 1,
163
+ }).sort((a, b) => (0, exports.sortByDistanceInResponsiveFunction)(a, b, sortByDevice));
164
+ return sortedElements.map((element) => element.element);
165
+ };
166
+ exports.sortResponsiveElements = sortResponsiveElements;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Compares two objects based on their `distance` property and determines their relative order.
3
+ * @param a - An object with a `distance` property (number).
4
+ * @param b - Another object with a `distance` property (number).
5
+ * @param a.distance
6
+ * @param b.distance
7
+ * @returns - A negative number if `a` has a smaller distance than `b`,
8
+ * a positive number if `a` has a larger distance than `b`,
9
+ * or 0 if both have equal distances.
10
+ */
11
+ export declare const sortByDistanceFunction: (a: {
12
+ distance: number;
13
+ }, b: {
14
+ distance: number;
15
+ }) => 0 | 1 | -1;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sortByDistanceFunction = void 0;
4
+ /**
5
+ * Compares two objects based on their `distance` property and determines their relative order.
6
+ * @param a - An object with a `distance` property (number).
7
+ * @param b - Another object with a `distance` property (number).
8
+ * @param a.distance
9
+ * @param b.distance
10
+ * @returns - A negative number if `a` has a smaller distance than `b`,
11
+ * a positive number if `a` has a larger distance than `b`,
12
+ * or 0 if both have equal distances.
13
+ */
14
+ const sortByDistanceFunction = (a, b) => {
15
+ if (a.distance === b.distance) {
16
+ return 0;
17
+ }
18
+ return a.distance < b.distance ? -1 : 1;
19
+ };
20
+ exports.sortByDistanceFunction = sortByDistanceFunction;
@@ -40,9 +40,46 @@ export declare const getFixedPositionByDevice: (item: VemFixed, device: CanvasDe
40
40
  * @returns
41
41
  */
42
42
  export declare function findFixedAvailablePositions(canvasWidth: number, newElements: VemFixed[], elements: VemFixed[], device: CanvasDevice, startWithPositionY?: boolean, findRightToLeft?: boolean, canvasHeight?: number): VemFixed[];
43
+ /**
44
+ * Adjusts the `width` of a responsive element to fit within the specified canvas width and updates its position.
45
+ * @param element - The fixed element to adjust.
46
+ * @param canvasWidth - The width of the canvas in grid columns.
47
+ * @param canvasDevice - The target device type (e.g., desktop, tablet, mobile).
48
+ * @returns - The updated responsive element with an adjusted `width`.
49
+ */
50
+ export declare function calculateWidth(element: VemFixed, canvasWidth: number, canvasDevice: CanvasDevice): VemFixed;
43
51
  /**
44
52
  * @param elements elements to calculate
45
53
  * @param device current device
46
54
  * @returns height
47
55
  */
48
56
  export declare const getFixedGridElementsBottomLimit: (elements: VemFixed[], device: CanvasDevice) => number;
57
+ /**
58
+ * Calculates distances of elements from a given reference point on the canvas device.
59
+ * @param elements - Array of `VemFixed` elements to calculate distances for.
60
+ * @param device - Canvas device providing the coordinates of the elements.
61
+ * @param referencePoint - The reference point to calculate distances from.
62
+ * @param referencePoint.x
63
+ * @param referencePoint.y
64
+ * @returns An array of objects containing the original elements and their calculated distances from the reference point.
65
+ */
66
+ export declare const calculateDistancesToReferencePoint: (elements: VemFixed[], device: CanvasDevice, referencePoint: {
67
+ x: number;
68
+ y: number;
69
+ }) => {
70
+ distance: number;
71
+ element: VemFixed;
72
+ }[];
73
+ /**
74
+ * Sorts elements based on their distance from a reference point on the canvas.
75
+ * @param elements - Array of `VemFixed` elements to be sorted.
76
+ * @param device - Canvas device providing the coordinates of the elements.
77
+ * @param referencePoint - The reference point to calculate distances from.
78
+ * @param referencePoint.x
79
+ * @param referencePoint.y
80
+ * @returns An array of `VemFixed` elements sorted by their distance from the reference point (0, 0).
81
+ */
82
+ export declare const sortElementsFromReferencePoint: (elements: VemFixed<unknown>[], device: CanvasDevice, referencePoint: {
83
+ x: number;
84
+ y: number;
85
+ }) => VemFixed<unknown>[];
@@ -1,4 +1,7 @@
1
+ import { VemPositionType } from "../interfaces/IVemPosition";
2
+ import { sortByDistanceFunction } from "../utils/general";
1
3
  import { OverlapIntervalTree } from "../utils/overlap";
4
+ import { setElementPosition } from "../utils/position";
2
5
  const SPACE_DELTA = 10;
3
6
  /**
4
7
  * update the position for a specific device
@@ -90,13 +93,27 @@ export function findFixedAvailablePositions(canvasWidth, newElements, elements,
90
93
  const initialY = startWithPositionY
91
94
  ? nElement.position.fixed[device].y
92
95
  : 0;
93
- const availablePosition = findAvailablePosition(canvasWidth, nElement, processedElements, device, { initialY, findRightToLeft, canvasHeight });
94
- const newElemWithPosition = updateFixedPosition(nElement, availablePosition, device);
96
+ const newElement = calculateWidth(nElement, canvasWidth, device);
97
+ const availablePosition = findAvailablePosition(canvasWidth, newElement, processedElements, device, { initialY, findRightToLeft, canvasHeight });
98
+ const newElemWithPosition = updateFixedPosition(newElement, availablePosition, device);
95
99
  resultElems.push(newElemWithPosition);
96
100
  processedElements.push(newElemWithPosition);
97
101
  });
98
102
  return resultElems;
99
103
  }
104
+ /**
105
+ * Adjusts the `width` of a responsive element to fit within the specified canvas width and updates its position.
106
+ * @param element - The fixed element to adjust.
107
+ * @param canvasWidth - The width of the canvas in grid columns.
108
+ * @param canvasDevice - The target device type (e.g., desktop, tablet, mobile).
109
+ * @returns - The updated responsive element with an adjusted `width`.
110
+ */
111
+ export function calculateWidth(element, canvasWidth, canvasDevice) {
112
+ const currentPosition = element.position.fixed[canvasDevice];
113
+ const fixedWidth = Math.min(currentPosition.width, canvasWidth);
114
+ const position = Object.assign(Object.assign({}, currentPosition), { width: fixedWidth });
115
+ return setElementPosition(element, VemPositionType.FIXED, canvasDevice, position);
116
+ }
100
117
  const getFixedGridElementY = (element, device, allowNegative = false) => {
101
118
  var _a;
102
119
  const position = element.position.fixed[device];
@@ -121,3 +138,40 @@ export const getFixedGridElementsBottomLimit = (elements, device) => {
121
138
  return Math.max(...elements.map((element) => getFixedGridElementY(element, device) +
122
139
  getFixedGridElementHeight(element, device)));
123
140
  };
141
+ /**
142
+ * Calculates distances of elements from a given reference point on the canvas device.
143
+ * @param elements - Array of `VemFixed` elements to calculate distances for.
144
+ * @param device - Canvas device providing the coordinates of the elements.
145
+ * @param referencePoint - The reference point to calculate distances from.
146
+ * @param referencePoint.x
147
+ * @param referencePoint.y
148
+ * @returns An array of objects containing the original elements and their calculated distances from the reference point.
149
+ */
150
+ export const calculateDistancesToReferencePoint = (elements, device, referencePoint) => {
151
+ return elements.map((element) => {
152
+ const elementPosition = getFixedPositionByDevice(element, device);
153
+ if (!elementPosition) {
154
+ throw new Error(`Position for device ${device} is undefined for element with Id ${element.elementId}.`);
155
+ }
156
+ const distance = Math.pow(referencePoint.x - elementPosition.x, 2) +
157
+ Math.pow(referencePoint.y - elementPosition.y, 2);
158
+ return {
159
+ distance,
160
+ element,
161
+ };
162
+ });
163
+ };
164
+ /**
165
+ * Sorts elements based on their distance from a reference point on the canvas.
166
+ * @param elements - Array of `VemFixed` elements to be sorted.
167
+ * @param device - Canvas device providing the coordinates of the elements.
168
+ * @param referencePoint - The reference point to calculate distances from.
169
+ * @param referencePoint.x
170
+ * @param referencePoint.y
171
+ * @returns An array of `VemFixed` elements sorted by their distance from the reference point (0, 0).
172
+ */
173
+ export const sortElementsFromReferencePoint = (elements, device, referencePoint) => {
174
+ const calculatedElements = calculateDistancesToReferencePoint(elements, device, referencePoint);
175
+ const sortedElements = [...calculatedElements].sort(sortByDistanceFunction);
176
+ return sortedElements.map((element) => element.element);
177
+ };
@@ -1,13 +1,19 @@
1
1
  import { CanvasDevice, Vem } from "../interfaces";
2
+ interface RecalculateOptions {
3
+ canvasHeight?: number;
4
+ sort?: CanvasDevice;
5
+ }
2
6
  /**
3
7
  * Recalculates the positions of elements on a canvas based on the canvas type.
4
8
  * @param elements - The list of elements to be recalculated. Each element has properties based on its type.
5
9
  * @param canvasWidth - The width of the canvas in pixels.
6
10
  * @param canvasType - The type of canvas (e.g., "fixed") that determines how positions are recalculated.
7
11
  * @param device - The device type (e.g., desktop, tablet, mobile) for determining element positions.
12
+ * @param canvasHeight - variable for the canvas with header component
13
+ * @param options
8
14
  * @returns - A list of elements with updated positions if the canvas type is "fixed" or "responsive".
9
15
  */
10
- export declare function recalculateElements(elements: Vem[], canvasWidth: number, canvasType: string, device: CanvasDevice): Vem[];
16
+ export declare function recalculateElements(elements: Vem[], canvasWidth: number, canvasType: string, device: CanvasDevice, options?: RecalculateOptions): Vem[];
11
17
  /**
12
18
  * The calculation is delegated to a specific strategy based on the `canvasType`.
13
19
  * @param elements - The list of elements in the canvas.
@@ -17,3 +23,4 @@ export declare function recalculateElements(elements: Vem[], canvasWidth: number
17
23
  * @returns - The calculated canvas height based on the selected strategy. Returns an empty array if no strategy is found.
18
24
  */
19
25
  export declare function calculateCanvasHeight(elements: Vem[], canvasType: string, device: CanvasDevice, rowGap?: number): number;
26
+ export {};
@@ -1,15 +1,18 @@
1
- import { findFixedAvailablePositions, getFixedGridElementsBottomLimit, } from "./fixed";
2
- import { findResponsiveAvailablePositions, getResponsiveGridElementsBottomLimit, } from "./responsive";
3
- import { VemPositionType, } from "../interfaces";
1
+ import { findFixedAvailablePositions, getFixedGridElementsBottomLimit, sortElementsFromReferencePoint, } from "./fixed";
2
+ import { findResponsiveAvailablePositions, getResponsiveGridElementsBottomLimit, sortResponsiveElements, } from "./responsive";
3
+ import { CanvasDevice, VemPositionType, } from "../interfaces";
4
4
  import { copyDesktopPositionToDevice } from "../utils/element";
5
5
  const recalculateStrategies = {
6
- fixed: (elements, canvasWidth, device) => {
6
+ fixed: (elements, canvasWidth, device, options) => {
7
7
  const changedElements = copyDesktopPositionToDevice(elements, device, VemPositionType.FIXED);
8
- return findFixedAvailablePositions(canvasWidth, changedElements, [], device);
8
+ // sort elements
9
+ const orderedElements = sortElementsFromReferencePoint(changedElements, options.sort, { x: 0, y: 0 });
10
+ return findFixedAvailablePositions(canvasWidth, orderedElements, [], device, false, false, options === null || options === void 0 ? void 0 : options.canvasHeight);
9
11
  },
10
- responsive: (elements, canvasWidth, device) => {
12
+ responsive: (elements, canvasWidth, device, options) => {
11
13
  const changedElements = copyDesktopPositionToDevice(elements, device, VemPositionType.RESPONSIVE);
12
- return findResponsiveAvailablePositions(canvasWidth, changedElements, [], device);
14
+ const orderedElements = sortResponsiveElements(changedElements, options.sort);
15
+ return findResponsiveAvailablePositions(canvasWidth, orderedElements, [], device);
13
16
  },
14
17
  };
15
18
  const calculateCanvasHeightStrategies = {
@@ -26,14 +29,20 @@ const calculateCanvasHeightStrategies = {
26
29
  * @param canvasWidth - The width of the canvas in pixels.
27
30
  * @param canvasType - The type of canvas (e.g., "fixed") that determines how positions are recalculated.
28
31
  * @param device - The device type (e.g., desktop, tablet, mobile) for determining element positions.
32
+ * @param canvasHeight - variable for the canvas with header component
33
+ * @param options
29
34
  * @returns - A list of elements with updated positions if the canvas type is "fixed" or "responsive".
30
35
  */
31
- export function recalculateElements(elements, canvasWidth, canvasType, device) {
36
+ export function recalculateElements(elements, canvasWidth, canvasType, device, options) {
32
37
  const strategy = recalculateStrategies[canvasType];
33
38
  if (!strategy) {
34
39
  return [];
35
40
  }
36
- return strategy(elements, canvasWidth, device);
41
+ const defaultOptions = {
42
+ sort: CanvasDevice.DESKTOP,
43
+ };
44
+ const calculatedOptions = Object.assign(Object.assign({}, defaultOptions), options);
45
+ return strategy(elements, canvasWidth, device, calculatedOptions);
37
46
  }
38
47
  /**
39
48
  * The calculation is delegated to a specific strategy based on the `canvasType`.
@@ -39,3 +39,49 @@ export declare function findResponsiveAvailablePositions(canvasWidth: number, ne
39
39
  */
40
40
  export declare function calculateColSpan(element: VemResponsive, canvasWidth: number, canvasDevice: CanvasDevice): VemResponsive;
41
41
  export declare const getResponsiveGridElementsBottomLimit: (elements: VemResponsive[], device: CanvasDevice, rowGap: number) => number;
42
+ /**
43
+ * Calculates the distances of elements from a reference point and returns a list of objects
44
+ * containing the calculated distance and the corresponding element.
45
+ * @param elements - An array of `VemResponsive` objects. Each object represents an element with
46
+ * a `position` property that contains responsive positions for various devices.
47
+ * @param device - The specific device type (key of `CanvasDevice`) to determine the responsive position.
48
+ * @param referencePoint - An object representing the reference point with `x` and `y` coordinates.
49
+ * @param referencePoint.x
50
+ * @param referencePoint.y
51
+ * @returns - An array of objects, where each object contains:
52
+ * - `distance`: The squared Euclidean distance from the reference point.
53
+ * - `element`: The corresponding `VemResponsive` object.
54
+ */
55
+ export declare const calculateDistancesToReferencePoint: (elements: VemResponsive[], device: CanvasDevice, referencePoint: {
56
+ x: number;
57
+ y: number;
58
+ }) => {
59
+ distance: number;
60
+ element: VemResponsive;
61
+ }[];
62
+ /**
63
+ /**
64
+ Sorts objects containing a `distance` and `element` by distance in ascending order.
65
+ If two objects have the same distance, it resolves the tie by comparing the `colStart` property
66
+ of their responsive positions for the `DESKTOP` device.
67
+ * @param a - An object containing:
68
+ * - `distance`: The calculated distance from a reference point.
69
+ * - `element`: A `VemResponsive` object with responsive position data.
70
+ * @param b - Another object with the same structure as `a`.
71
+ * @param a.element
72
+ * @param a.distance
73
+ * @param _device - The device type (of type `CanvasDevice`). Currently unused in this function.
74
+ * @param b.distance
75
+ * @param b.element
76
+ * @returns - A negative number if `a` should come before `b`,
77
+ * a positive number if `a` should come after `b`,
78
+ * or 0 if they have the same distance and `colStart` values.
79
+ */
80
+ export declare const sortByDistanceInResponsiveFunction: (a: {
81
+ distance: number;
82
+ element: VemResponsive;
83
+ }, b: {
84
+ distance: number;
85
+ element: VemResponsive;
86
+ }, _device: CanvasDevice) => number;
87
+ export declare const sortResponsiveElements: (elements: VemResponsive<unknown>[], sortByDevice?: CanvasDevice) => VemResponsive<unknown>[];
@@ -1,3 +1,4 @@
1
+ import { CanvasDevice } from "../interfaces/ICanvasGrid";
1
2
  import { VemPositionType, } from "../interfaces/IVemPosition";
2
3
  import { OverlapIntervalTree } from "../utils/overlap";
3
4
  import { setElementPosition } from "../utils/position";
@@ -92,3 +93,63 @@ export const getResponsiveGridElementsBottomLimit = (elements, device, rowGap) =
92
93
  });
93
94
  return Math.max(...mappedElements);
94
95
  };
96
+ /**
97
+ * Calculates the distances of elements from a reference point and returns a list of objects
98
+ * containing the calculated distance and the corresponding element.
99
+ * @param elements - An array of `VemResponsive` objects. Each object represents an element with
100
+ * a `position` property that contains responsive positions for various devices.
101
+ * @param device - The specific device type (key of `CanvasDevice`) to determine the responsive position.
102
+ * @param referencePoint - An object representing the reference point with `x` and `y` coordinates.
103
+ * @param referencePoint.x
104
+ * @param referencePoint.y
105
+ * @returns - An array of objects, where each object contains:
106
+ * - `distance`: The squared Euclidean distance from the reference point.
107
+ * - `element`: The corresponding `VemResponsive` object.
108
+ */
109
+ export const calculateDistancesToReferencePoint = (elements, device, referencePoint) => {
110
+ return elements.map((element) => {
111
+ var _a, _b;
112
+ const position = (_b = (_a = element.position) === null || _a === void 0 ? void 0 : _a.responsive) === null || _b === void 0 ? void 0 : _b[device];
113
+ if (!position) {
114
+ throw new Error(`Position for device ${device} is undefined for element with Id ${element.elementId}.`);
115
+ }
116
+ const distance = Math.pow(referencePoint.x - position.colStart, 2) +
117
+ Math.pow(referencePoint.y - position.rowStart, 2);
118
+ return {
119
+ distance,
120
+ element,
121
+ };
122
+ });
123
+ };
124
+ /**
125
+ /**
126
+ Sorts objects containing a `distance` and `element` by distance in ascending order.
127
+ If two objects have the same distance, it resolves the tie by comparing the `colStart` property
128
+ of their responsive positions for the `DESKTOP` device.
129
+ * @param a - An object containing:
130
+ * - `distance`: The calculated distance from a reference point.
131
+ * - `element`: A `VemResponsive` object with responsive position data.
132
+ * @param b - Another object with the same structure as `a`.
133
+ * @param a.element
134
+ * @param a.distance
135
+ * @param _device - The device type (of type `CanvasDevice`). Currently unused in this function.
136
+ * @param b.distance
137
+ * @param b.element
138
+ * @returns - A negative number if `a` should come before `b`,
139
+ * a positive number if `a` should come after `b`,
140
+ * or 0 if they have the same distance and `colStart` values.
141
+ */
142
+ export const sortByDistanceInResponsiveFunction = (a, b, _device) => {
143
+ if (a.distance === b.distance) {
144
+ return (a.element.position.responsive[CanvasDevice.DESKTOP].colStart -
145
+ b.element.position.responsive[CanvasDevice.DESKTOP].colStart);
146
+ }
147
+ return a.distance - b.distance;
148
+ };
149
+ export const sortResponsiveElements = (elements, sortByDevice) => {
150
+ const sortedElements = calculateDistancesToReferencePoint(elements, sortByDevice, {
151
+ x: 1,
152
+ y: 1,
153
+ }).sort((a, b) => sortByDistanceInResponsiveFunction(a, b, sortByDevice));
154
+ return sortedElements.map((element) => element.element);
155
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Compares two objects based on their `distance` property and determines their relative order.
3
+ * @param a - An object with a `distance` property (number).
4
+ * @param b - Another object with a `distance` property (number).
5
+ * @param a.distance
6
+ * @param b.distance
7
+ * @returns - A negative number if `a` has a smaller distance than `b`,
8
+ * a positive number if `a` has a larger distance than `b`,
9
+ * or 0 if both have equal distances.
10
+ */
11
+ export declare const sortByDistanceFunction: (a: {
12
+ distance: number;
13
+ }, b: {
14
+ distance: number;
15
+ }) => 0 | 1 | -1;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Compares two objects based on their `distance` property and determines their relative order.
3
+ * @param a - An object with a `distance` property (number).
4
+ * @param b - Another object with a `distance` property (number).
5
+ * @param a.distance
6
+ * @param b.distance
7
+ * @returns - A negative number if `a` has a smaller distance than `b`,
8
+ * a positive number if `a` has a larger distance than `b`,
9
+ * or 0 if both have equal distances.
10
+ */
11
+ export const sortByDistanceFunction = (a, b) => {
12
+ if (a.distance === b.distance) {
13
+ return 0;
14
+ }
15
+ return a.distance < b.distance ? -1 : 1;
16
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qrvey/utils",
3
- "version": "1.15.0-13",
3
+ "version": "1.15.0-15",
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",