zuljaman-banner-components 1.0.23 → 1.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.
- package/README.md +228 -131
- package/dist/components/BannerRenderer/BannerRenderer.d.ts +8 -0
- package/dist/components/BannerRenderer/BannerRenderer.d.ts.map +1 -0
- package/dist/components/BannerRenderer/BannerRenderer.js +325 -0
- package/dist/components/BannerRenderer/components/CopyElement.d.ts +62 -0
- package/dist/components/BannerRenderer/components/CopyElement.d.ts.map +1 -0
- package/dist/components/BannerRenderer/components/CopyElement.js +220 -0
- package/dist/components/BannerRenderer/components/InteractiveLines.d.ts +26 -0
- package/dist/components/BannerRenderer/components/InteractiveLines.d.ts.map +1 -0
- package/dist/components/BannerRenderer/components/InteractiveLines.js +172 -0
- package/dist/components/BannerRenderer/components/LogoElement.d.ts +55 -0
- package/dist/components/BannerRenderer/components/LogoElement.d.ts.map +1 -0
- package/dist/components/BannerRenderer/components/LogoElement.js +53 -0
- package/dist/components/BannerRenderer/components/VisualGuides.d.ts +43 -0
- package/dist/components/BannerRenderer/components/VisualGuides.d.ts.map +1 -0
- package/dist/components/BannerRenderer/components/VisualGuides.js +110 -0
- package/dist/components/BannerRenderer/components/index.d.ts +12 -0
- package/dist/components/BannerRenderer/components/index.d.ts.map +1 -0
- package/dist/components/BannerRenderer/components/index.js +14 -0
- package/dist/components/BannerRenderer/constants.d.ts +15 -0
- package/dist/components/BannerRenderer/constants.d.ts.map +1 -0
- package/dist/components/BannerRenderer/constants.js +36 -0
- package/dist/components/BannerRenderer/hooks/index.d.ts +14 -0
- package/dist/components/BannerRenderer/hooks/index.d.ts.map +1 -0
- package/dist/components/BannerRenderer/hooks/index.js +16 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/debugPositions.d.ts +30 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/debugPositions.d.ts.map +1 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/debugPositions.js +87 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/index.d.ts +13 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/index.d.ts.map +1 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/index.js +21 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/useAnchorEdgeLocking.d.ts +73 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/useAnchorEdgeLocking.d.ts.map +1 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/useAnchorEdgeLocking.js +151 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/useAutoPositioningMain.d.ts +66 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/useAutoPositioningMain.d.ts.map +1 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/useAutoPositioningMain.js +335 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/useChainPositioning.d.ts +61 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/useChainPositioning.d.ts.map +1 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/useChainPositioning.js +180 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/useHeightCompensation.d.ts +60 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/useHeightCompensation.d.ts.map +1 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning/useHeightCompensation.js +178 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning.d.ts +8 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning.d.ts.map +1 -0
- package/dist/components/BannerRenderer/hooks/useAutoPositioning.js +12 -0
- package/dist/components/BannerRenderer/hooks/useDragSnap.d.ts +30 -0
- package/dist/components/BannerRenderer/hooks/useDragSnap.d.ts.map +1 -0
- package/dist/components/BannerRenderer/hooks/useDragSnap.js +90 -0
- package/dist/components/BannerRenderer/hooks/useElementRefs.d.ts +22 -0
- package/dist/components/BannerRenderer/hooks/useElementRefs.d.ts.map +1 -0
- package/dist/components/BannerRenderer/hooks/useElementRefs.js +70 -0
- package/dist/components/BannerRenderer/hooks/useLineDrawing.d.ts +40 -0
- package/dist/components/BannerRenderer/hooks/useLineDrawing.d.ts.map +1 -0
- package/dist/components/BannerRenderer/hooks/useLineDrawing.js +198 -0
- package/dist/components/BannerRenderer/hooks/useProximityDetection.d.ts +43 -0
- package/dist/components/BannerRenderer/hooks/useProximityDetection.d.ts.map +1 -0
- package/dist/components/BannerRenderer/hooks/useProximityDetection.js +491 -0
- package/dist/components/BannerRenderer/index.d.ts +6 -0
- package/dist/components/BannerRenderer/index.d.ts.map +1 -0
- package/dist/components/BannerRenderer/index.js +8 -0
- package/dist/components/{BannerRenderer.d.ts → BannerRenderer/types.d.ts} +29 -8
- package/dist/components/BannerRenderer/types.d.ts.map +1 -0
- package/dist/components/BannerRenderer/types.js +5 -0
- package/dist/components/BannerRenderer/utils/alignmentUtils.d.ts +38 -0
- package/dist/components/BannerRenderer/utils/alignmentUtils.d.ts.map +1 -0
- package/dist/components/BannerRenderer/utils/alignmentUtils.js +138 -0
- package/dist/components/BannerRenderer/utils/elementCheckUtils.d.ts +22 -0
- package/dist/components/BannerRenderer/utils/elementCheckUtils.d.ts.map +1 -0
- package/dist/components/BannerRenderer/utils/elementCheckUtils.js +37 -0
- package/dist/components/BannerRenderer/utils/elementIdUtils.d.ts +25 -0
- package/dist/components/BannerRenderer/utils/elementIdUtils.d.ts.map +1 -0
- package/dist/components/BannerRenderer/utils/elementIdUtils.js +56 -0
- package/dist/components/BannerRenderer/utils/fontUtils.d.ts +12 -0
- package/dist/components/BannerRenderer/utils/fontUtils.d.ts.map +1 -0
- package/dist/components/BannerRenderer/utils/fontUtils.js +26 -0
- package/dist/components/BannerRenderer/utils/graphUtils.d.ts +54 -0
- package/dist/components/BannerRenderer/utils/graphUtils.d.ts.map +1 -0
- package/dist/components/BannerRenderer/utils/graphUtils.js +138 -0
- package/dist/components/BannerRenderer/utils/index.d.ts +12 -0
- package/dist/components/BannerRenderer/utils/index.d.ts.map +1 -0
- package/dist/components/BannerRenderer/utils/index.js +27 -0
- package/dist/components/BannerRenderer/utils/snapUtils.d.ts +38 -0
- package/dist/components/BannerRenderer/utils/snapUtils.d.ts.map +1 -0
- package/dist/components/BannerRenderer/utils/snapUtils.js +109 -0
- package/dist/components/BannerVisor.d.ts.map +1 -1
- package/dist/components/BannerVisor.js +8 -1
- package/dist/components/index.js +1 -1
- package/dist/components/shared/DraggableElement.d.ts +11 -0
- package/dist/components/shared/DraggableElement.d.ts.map +1 -1
- package/dist/components/shared/DraggableElement.js +47 -51
- package/dist/components/styles/Style1/substyleConfig.d.ts.map +1 -1
- package/dist/components/styles/Style1/substyleConfig.js +53 -54
- package/dist/components/styles/Style2/substyleConfig.js +78 -78
- package/dist/components/styles/Style3/substyleConfig.d.ts.map +1 -1
- package/dist/components/styles/Style3/substyleConfig.js +40 -37
- package/dist/components/styles/Style4/substyleConfig.js +57 -57
- package/dist/components/styles/types/substyleTypes.d.ts +32 -15
- package/dist/components/styles/types/substyleTypes.d.ts.map +1 -1
- package/dist/components/styles/utils/chainValidation.d.ts +41 -0
- package/dist/components/styles/utils/chainValidation.d.ts.map +1 -0
- package/dist/components/styles/utils/chainValidation.js +148 -0
- package/dist/components/styles/utils/positioningUtils.d.ts +207 -11
- package/dist/components/styles/utils/positioningUtils.d.ts.map +1 -1
- package/dist/components/styles/utils/positioningUtils.js +520 -19
- package/dist/constants/characterLimits.d.ts +4 -16
- package/dist/constants/characterLimits.d.ts.map +1 -1
- package/dist/constants/characterLimits.js +28 -26
- package/dist/constants/styleConfigs.js +6 -6
- package/dist/styleConfig.d.ts +4 -4
- package/dist/styleConfig.d.ts.map +1 -1
- package/dist/styleConfig.js +8 -16
- package/dist/types.d.ts +42 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/components/BannerRenderer.d.ts.map +0 -1
- package/dist/components/BannerRenderer.js +0 -559
|
@@ -5,8 +5,28 @@
|
|
|
5
5
|
* Adapted for absolute positioning system (x, y coordinates from center)
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.
|
|
8
|
+
exports.calculateSingleLinkOffset = exports.calculateDownOffset = exports.calculateUpOffset = void 0;
|
|
9
|
+
exports.getElementRef = getElementRef;
|
|
10
|
+
exports.getCopyIndexFromElementId = getCopyIndexFromElementId;
|
|
11
|
+
exports.hasElementCenterOrigin = hasElementCenterOrigin;
|
|
12
|
+
exports.checkElementEdgeProximity = checkElementEdgeProximity;
|
|
13
|
+
exports.calculateChainedOffsets = calculateChainedOffsets;
|
|
14
|
+
exports.detectNearestEdge = detectNearestEdge;
|
|
15
|
+
exports.calculateGapToEdge = calculateGapToEdge;
|
|
16
|
+
exports.orderChainFromAnchor = orderChainFromAnchor;
|
|
17
|
+
exports.getSubsequentElementsInChain = getSubsequentElementsInChain;
|
|
18
|
+
exports.calculateAbsoluteChainPositions = calculateAbsoluteChainPositions;
|
|
19
|
+
exports.calculateTargetPositionsFromAnchor = calculateTargetPositionsFromAnchor;
|
|
20
|
+
exports.getCopyData = getCopyData;
|
|
21
|
+
exports.calculateAnchorHeightCompensation = calculateAnchorHeightCompensation;
|
|
22
|
+
exports.calculateTargetCompensationForAnchorGrowth = calculateTargetCompensationForAnchorGrowth;
|
|
23
|
+
exports.calculateTargetSelfCompensation = calculateTargetSelfCompensation;
|
|
24
|
+
exports.calculateSubsequentCompensation = calculateSubsequentCompensation;
|
|
25
|
+
exports.captureAnchorEdgeConfig = captureAnchorEdgeConfig;
|
|
26
|
+
exports.measureElementHeights = measureElementHeights;
|
|
27
|
+
exports.mapsAreEqual = mapsAreEqual;
|
|
9
28
|
const defaults_1 = require("../../../constants/defaults");
|
|
29
|
+
const chainValidation_1 = require("./chainValidation");
|
|
10
30
|
/**
|
|
11
31
|
* Calculate auto-positioning offset for 'up' direction
|
|
12
32
|
* Target element will be positioned above the anchor with a gap
|
|
@@ -14,14 +34,17 @@ const defaults_1 = require("../../../constants/defaults");
|
|
|
14
34
|
* @param anchorHeight - Height of anchor element in pixels
|
|
15
35
|
* @param targetHeight - Height of target element in pixels
|
|
16
36
|
* @param anchorHasCenterOrigin - Whether anchor is positioned from center (true) or top-left (false)
|
|
37
|
+
* @param fixAnchorBottomEdge - If true, anchor's bottom edge position is fixed (grows upward)
|
|
17
38
|
* @returns Offset in pixels (negative value to move up)
|
|
18
39
|
*/
|
|
19
|
-
const calculateUpOffset = (gapRem, anchorHeight, targetHeight, anchorHasCenterOrigin) => {
|
|
40
|
+
const calculateUpOffset = (gapRem, anchorHeight, targetHeight, anchorHasCenterOrigin, fixAnchorBottomEdge = false) => {
|
|
20
41
|
const gapPixels = gapRem * defaults_1.REM_TO_PIXELS;
|
|
21
42
|
// Target always has centerOrigin=true (positioned from center)
|
|
22
43
|
const targetOffset = targetHeight / 2;
|
|
23
44
|
if (anchorHasCenterOrigin) {
|
|
24
45
|
// Anchor positioned from center: offset from center to center
|
|
46
|
+
// This calculation is the same regardless of edge fixing
|
|
47
|
+
// Edge fixing is handled by adjusting the anchor's position, not the offset
|
|
25
48
|
return -((anchorHeight / 2) + gapPixels + targetOffset);
|
|
26
49
|
}
|
|
27
50
|
else {
|
|
@@ -37,14 +60,17 @@ exports.calculateUpOffset = calculateUpOffset;
|
|
|
37
60
|
* @param anchorHeight - Height of anchor element in pixels
|
|
38
61
|
* @param targetHeight - Height of target element in pixels
|
|
39
62
|
* @param anchorHasCenterOrigin - Whether anchor is positioned from center (true) or top-left (false)
|
|
63
|
+
* @param fixAnchorTopEdge - If true, anchor's top edge position is fixed (grows downward)
|
|
40
64
|
* @returns Offset in pixels (positive value to move down)
|
|
41
65
|
*/
|
|
42
|
-
const calculateDownOffset = (gapRem, anchorHeight, targetHeight, anchorHasCenterOrigin) => {
|
|
66
|
+
const calculateDownOffset = (gapRem, anchorHeight, targetHeight, anchorHasCenterOrigin, fixAnchorTopEdge = false) => {
|
|
43
67
|
const gapPixels = gapRem * defaults_1.REM_TO_PIXELS;
|
|
44
68
|
// Target always has centerOrigin=true (positioned from center)
|
|
45
69
|
const targetOffset = targetHeight / 2;
|
|
46
70
|
if (anchorHasCenterOrigin) {
|
|
47
71
|
// Anchor positioned from center: offset from center to center
|
|
72
|
+
// This calculation is the same regardless of edge fixing
|
|
73
|
+
// Edge fixing is handled by adjusting the anchor's position, not the offset
|
|
48
74
|
return (anchorHeight / 2) + gapPixels + targetOffset;
|
|
49
75
|
}
|
|
50
76
|
else {
|
|
@@ -54,26 +80,501 @@ const calculateDownOffset = (gapRem, anchorHeight, targetHeight, anchorHasCenter
|
|
|
54
80
|
};
|
|
55
81
|
exports.calculateDownOffset = calculateDownOffset;
|
|
56
82
|
/**
|
|
57
|
-
* Calculate
|
|
58
|
-
* Works with absolute positioning system where elements have x, y coordinates from center
|
|
59
|
-
* @param config - Substyle configuration
|
|
60
|
-
* @param autoConfig - Auto-positioning configuration
|
|
61
|
-
* @param anchorHeight - Height of anchor element in pixels
|
|
62
|
-
* @param targetHeight - Height of target element in pixels
|
|
63
|
-
* @param anchorHasCenterOrigin - Whether anchor is positioned from center (true) or top-left (false)
|
|
64
|
-
* @returns Offset in pixels (Y-axis only for now)
|
|
83
|
+
* Calculate offset for a single link in the chain
|
|
65
84
|
*/
|
|
66
|
-
const
|
|
67
|
-
var _a;
|
|
68
|
-
const { direction } = autoConfig;
|
|
69
|
-
const gapRem = (_a = config.gapRem) !== null && _a !== void 0 ? _a : 0;
|
|
85
|
+
const calculateSingleLinkOffset = (direction, gapRem, fromHeight, toHeight, fromHasCenterOrigin, fromIsAtBottomEdge) => {
|
|
70
86
|
if (direction === 'up') {
|
|
71
|
-
return (0, exports.calculateUpOffset)(gapRem,
|
|
87
|
+
return (0, exports.calculateUpOffset)(gapRem, fromHeight, toHeight, fromHasCenterOrigin, fromIsAtBottomEdge);
|
|
72
88
|
}
|
|
73
89
|
else if (direction === 'down') {
|
|
74
|
-
|
|
90
|
+
const fromIsAtTopEdge = !fromIsAtBottomEdge;
|
|
91
|
+
return (0, exports.calculateDownOffset)(gapRem, fromHeight, toHeight, fromHasCenterOrigin, fromIsAtTopEdge);
|
|
75
92
|
}
|
|
76
|
-
// Note: left/right
|
|
93
|
+
// Note: left/right would need X-axis offset (not implemented yet)
|
|
77
94
|
return 0;
|
|
78
95
|
};
|
|
79
|
-
exports.
|
|
96
|
+
exports.calculateSingleLinkOffset = calculateSingleLinkOffset;
|
|
97
|
+
/**
|
|
98
|
+
* Get element ref from element ID
|
|
99
|
+
* Supports both copy-{uuid} and copy-{N} (styleSlot) formats
|
|
100
|
+
*/
|
|
101
|
+
function getElementRef(elementId, refs, copies) {
|
|
102
|
+
if (elementId === 'logo') {
|
|
103
|
+
return refs.logo;
|
|
104
|
+
}
|
|
105
|
+
else if (elementId.startsWith('copy-')) {
|
|
106
|
+
const suffix = elementId.substring(5); // Remove 'copy-' prefix
|
|
107
|
+
// Check if it's copy-N format (just a number = styleSlot)
|
|
108
|
+
if (/^\d+$/.test(suffix)) {
|
|
109
|
+
const styleSlotIndex = parseInt(suffix, 10);
|
|
110
|
+
// First try: find copy by styleSlot
|
|
111
|
+
const copy = copies.find(c => c.styleSlot === styleSlotIndex);
|
|
112
|
+
if (copy) {
|
|
113
|
+
const copyIndex = copies.indexOf(copy);
|
|
114
|
+
if (copyIndex < refs.copies.length) {
|
|
115
|
+
return refs.copies[copyIndex];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Fallback: use direct array index
|
|
119
|
+
if (styleSlotIndex < copies.length && styleSlotIndex < refs.copies.length) {
|
|
120
|
+
return refs.copies[styleSlotIndex];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// It's a UUID format - find by id
|
|
125
|
+
const copyIndex = copies.findIndex(c => c.id === suffix);
|
|
126
|
+
if (copyIndex !== -1 && copyIndex < refs.copies.length) {
|
|
127
|
+
return refs.copies[copyIndex];
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Get copy index from element ID
|
|
136
|
+
*/
|
|
137
|
+
function getCopyIndexFromElementId(elementId, copies) {
|
|
138
|
+
if (elementId === 'logo') {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
else if (elementId.startsWith('copy-')) {
|
|
142
|
+
// DYNAMIC: Handle 'copy-N' format where N is the styleSlot
|
|
143
|
+
const styleSlotIndex = parseInt(elementId.replace('copy-', ''));
|
|
144
|
+
const copyIndex = copies.findIndex(c => c.styleSlot === styleSlotIndex);
|
|
145
|
+
// FIX: Return the array index, not the styleSlot
|
|
146
|
+
// onCopyPositionChange expects the array index to update the correct copy
|
|
147
|
+
return copyIndex !== -1 ? copyIndex : styleSlotIndex;
|
|
148
|
+
}
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Check if element has center origin (all copies do, logo doesn't)
|
|
153
|
+
*/
|
|
154
|
+
function hasElementCenterOrigin(elementId) {
|
|
155
|
+
return elementId !== 'logo';
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Check if element is closest to bottom edge (for compensation)
|
|
159
|
+
*/
|
|
160
|
+
function checkElementEdgeProximity(elementId, elementRef, bannerContainerRef, sizeMultiplier) {
|
|
161
|
+
if (!bannerContainerRef)
|
|
162
|
+
return false;
|
|
163
|
+
const bannerBounds = bannerContainerRef.getBoundingClientRect();
|
|
164
|
+
const elementBounds = elementRef.getBoundingClientRect();
|
|
165
|
+
const bannerHeight = bannerBounds.height / sizeMultiplier;
|
|
166
|
+
// Calculate element's Y position relative to banner center
|
|
167
|
+
const elementCenterY = (elementBounds.top + elementBounds.height / 2 - bannerBounds.top - bannerBounds.height / 2) / sizeMultiplier;
|
|
168
|
+
// Calculate distance to top and bottom edges
|
|
169
|
+
const distToTop = Math.abs(elementCenterY + bannerHeight / 2);
|
|
170
|
+
const distToBottom = Math.abs(elementCenterY - bannerHeight / 2);
|
|
171
|
+
// Element is closest to bottom if distance to bottom < distance to top
|
|
172
|
+
return distToBottom < distToTop;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Calculate offsets for all elements in a positioning chain
|
|
176
|
+
* Supports cascading offsets where each element's position depends on its parent
|
|
177
|
+
*
|
|
178
|
+
* @param config - Substyle configuration
|
|
179
|
+
* @param links - Array of positioning links defining the chain
|
|
180
|
+
* @param copies - Array of copy configurations
|
|
181
|
+
* @param refs - Object containing refs to logo and copy elements
|
|
182
|
+
* @param sizeMultiplier - Canvas scaling factor
|
|
183
|
+
* @param elementCompensations - Record of height-based compensations per element
|
|
184
|
+
* @param bannerContainerRef - Ref to banner container for edge detection
|
|
185
|
+
* @returns Record mapping copy index to Y offset in pixels
|
|
186
|
+
*/
|
|
187
|
+
function calculateChainedOffsets(config, links, copies, refs, sizeMultiplier, elementCompensations, bannerContainerRef) {
|
|
188
|
+
var _a, _b;
|
|
189
|
+
console.log('📊 calculateChainedOffsets START', { links, copiesCount: copies.length });
|
|
190
|
+
// Validate configuration
|
|
191
|
+
const validation = (0, chainValidation_1.validateChainConfiguration)(links);
|
|
192
|
+
if (!validation.valid) {
|
|
193
|
+
console.log('❌ Chain validation FAILED:', validation.error);
|
|
194
|
+
return {};
|
|
195
|
+
}
|
|
196
|
+
console.log('✅ Chain validation passed');
|
|
197
|
+
// Build graph and get calculation order
|
|
198
|
+
const graph = (0, chainValidation_1.buildDependencyGraph)(links);
|
|
199
|
+
const calculationOrder = (0, chainValidation_1.topologicalSort)(graph);
|
|
200
|
+
console.log('📋 Calculation order:', calculationOrder);
|
|
201
|
+
// Track accumulated offsets for cascading
|
|
202
|
+
const accumulatedOffsets = {};
|
|
203
|
+
const offsets = {};
|
|
204
|
+
// Process each element in topological order
|
|
205
|
+
for (const elementId of calculationOrder) {
|
|
206
|
+
// Find incoming link (the link where this element is the "to")
|
|
207
|
+
const incomingLink = (0, chainValidation_1.findIncomingLink)(links, elementId);
|
|
208
|
+
if (!incomingLink) {
|
|
209
|
+
// This is a root/anchor element - no offset
|
|
210
|
+
console.log(`🔗 ${elementId}: ROOT/ANCHOR (no incoming link)`);
|
|
211
|
+
accumulatedOffsets[elementId] = 0;
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
// Get refs for from and to elements
|
|
215
|
+
const fromRef = getElementRef(incomingLink.fromElement, refs, copies);
|
|
216
|
+
const toRef = getElementRef(elementId, refs, copies);
|
|
217
|
+
console.log(`🔗 ${elementId}: fromRef=${!!fromRef}, toRef=${!!toRef}`);
|
|
218
|
+
if (!fromRef || !toRef) {
|
|
219
|
+
console.log(`⚠️ ${elementId}: SKIPPED - missing ref`);
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
// Measure heights
|
|
223
|
+
const fromHeight = fromRef.getBoundingClientRect().height / sizeMultiplier;
|
|
224
|
+
const toHeight = toRef.getBoundingClientRect().height / sizeMultiplier;
|
|
225
|
+
// Get gap (link-specific or global)
|
|
226
|
+
const gapRem = (_b = (_a = incomingLink.gapRem) !== null && _a !== void 0 ? _a : config.gapRem) !== null && _b !== void 0 ? _b : 0;
|
|
227
|
+
// Check element properties
|
|
228
|
+
const fromHasCenterOrigin = hasElementCenterOrigin(incomingLink.fromElement);
|
|
229
|
+
const fromIsAtBottomEdge = checkElementEdgeProximity(incomingLink.fromElement, fromRef, bannerContainerRef, sizeMultiplier);
|
|
230
|
+
// Calculate base offset for this link
|
|
231
|
+
const baseOffset = (0, exports.calculateSingleLinkOffset)(incomingLink.direction, gapRem, fromHeight, toHeight, fromHasCenterOrigin, fromIsAtBottomEdge);
|
|
232
|
+
// Get accumulated offset of from element (cascading)
|
|
233
|
+
const fromAccumulatedOffset = accumulatedOffsets[incomingLink.fromElement] || 0;
|
|
234
|
+
// Get ANCHOR's compensation - needed for correct initial offset calculation
|
|
235
|
+
// This makes totalOffset = originalBaseOffset (before height change)
|
|
236
|
+
const fromCompensation = elementCompensations[incomingLink.fromElement] || 0;
|
|
237
|
+
// Total offset = base + cascade + anchor compensation
|
|
238
|
+
// The compensation neutralizes the height increase in baseOffset
|
|
239
|
+
const totalOffset = baseOffset + fromAccumulatedOffset + fromCompensation;
|
|
240
|
+
console.log(`📐 ${elementId}: baseOffset=${baseOffset.toFixed(2)}, fromAccum=${fromAccumulatedOffset.toFixed(2)}, fromComp=${fromCompensation.toFixed(2)}, TOTAL=${totalOffset.toFixed(2)}`);
|
|
241
|
+
// Store accumulated offset for this element
|
|
242
|
+
accumulatedOffsets[elementId] = totalOffset;
|
|
243
|
+
// Map to copy index for state storage
|
|
244
|
+
const copyIndex = getCopyIndexFromElementId(elementId, copies);
|
|
245
|
+
console.log(`📌 ${elementId}: copyIndex=${copyIndex}`);
|
|
246
|
+
if (copyIndex !== undefined) {
|
|
247
|
+
offsets[copyIndex] = totalOffset;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
console.log('📊 calculateChainedOffsets RESULT:', offsets);
|
|
251
|
+
return offsets;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Detect which edge (top or bottom) the element is closest to
|
|
255
|
+
*/
|
|
256
|
+
function detectNearestEdge(element, container, sizeMultiplier) {
|
|
257
|
+
const containerBounds = container.getBoundingClientRect();
|
|
258
|
+
const elementBounds = element.getBoundingClientRect();
|
|
259
|
+
const containerHeight = containerBounds.height / sizeMultiplier;
|
|
260
|
+
const elementCenterY = (elementBounds.top + elementBounds.height / 2 - containerBounds.top) / sizeMultiplier;
|
|
261
|
+
const distToTop = elementCenterY;
|
|
262
|
+
const distToBottom = containerHeight - elementCenterY;
|
|
263
|
+
const edge = distToBottom < distToTop ? 'bottom' : 'top';
|
|
264
|
+
// Debug log - uncomment for troubleshooting
|
|
265
|
+
// console.log(`🔍 detectNearestEdge: containerHeight=${containerHeight.toFixed(2)}, elementCenterY=${elementCenterY.toFixed(2)}, distToTop=${distToTop.toFixed(2)}, distToBottom=${distToBottom.toFixed(2)}, edge=${edge}`);
|
|
266
|
+
return edge;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Calculate the gap from an element's edge to the container's edge
|
|
270
|
+
*/
|
|
271
|
+
function calculateGapToEdge(element, edge, container, sizeMultiplier) {
|
|
272
|
+
const containerBounds = container.getBoundingClientRect();
|
|
273
|
+
const elementBounds = element.getBoundingClientRect();
|
|
274
|
+
const containerHeight = containerBounds.height / sizeMultiplier;
|
|
275
|
+
const elementTop = (elementBounds.top - containerBounds.top) / sizeMultiplier;
|
|
276
|
+
const elementBottom = (elementBounds.bottom - containerBounds.top) / sizeMultiplier;
|
|
277
|
+
if (edge === 'bottom') {
|
|
278
|
+
// Gap from element's bottom edge to container's bottom edge
|
|
279
|
+
return containerHeight - elementBottom;
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
// Gap from element's top edge to container's top edge
|
|
283
|
+
return elementTop;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Order targets in chain from anchor to last element
|
|
288
|
+
*/
|
|
289
|
+
function orderChainFromAnchor(anchorId, links) {
|
|
290
|
+
const ordered = [];
|
|
291
|
+
let currentId = anchorId;
|
|
292
|
+
while (true) {
|
|
293
|
+
const nextLink = links.find(l => l.from === currentId);
|
|
294
|
+
if (!nextLink)
|
|
295
|
+
break;
|
|
296
|
+
ordered.push(nextLink.to);
|
|
297
|
+
currentId = nextLink.to;
|
|
298
|
+
}
|
|
299
|
+
return ordered;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Get all elements that come AFTER a given element in the chain
|
|
303
|
+
* Useful for determining which elements need to move when an element's height changes
|
|
304
|
+
*/
|
|
305
|
+
function getSubsequentElementsInChain(elementId, links) {
|
|
306
|
+
const subsequent = [];
|
|
307
|
+
let currentId = elementId;
|
|
308
|
+
while (true) {
|
|
309
|
+
const nextLink = links.find(l => l.from === currentId);
|
|
310
|
+
if (!nextLink)
|
|
311
|
+
break;
|
|
312
|
+
subsequent.push(nextLink.to);
|
|
313
|
+
currentId = nextLink.to;
|
|
314
|
+
}
|
|
315
|
+
return subsequent;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Calculate absolute Y positions for all elements in a chain
|
|
319
|
+
* based on the anchor's fixed edge position
|
|
320
|
+
*/
|
|
321
|
+
function calculateAbsoluteChainPositions(bannerHeight, chainConfig, elementHeights) {
|
|
322
|
+
var _a;
|
|
323
|
+
const positions = {};
|
|
324
|
+
const { anchorId, anchorEdge, anchorGapToEdge, links } = chainConfig;
|
|
325
|
+
const anchorHeight = elementHeights[anchorId] || 0;
|
|
326
|
+
// Debug log - uncomment for troubleshooting
|
|
327
|
+
// console.log(`🎯 calculateAbsoluteChainPositions: anchorId=${anchorId}, edge=${anchorEdge}, gapToEdge=${anchorGapToEdge.toFixed(2)}, anchorHeight=${anchorHeight.toFixed(2)}`);
|
|
328
|
+
// 1. Calculate anchor's center Y position (relative to banner center, where 0 = center)
|
|
329
|
+
let anchorCenterY;
|
|
330
|
+
if (anchorEdge === 'bottom') {
|
|
331
|
+
// ANCHOR's bottom edge stays at: (bannerHeight/2) - anchorGapToEdge
|
|
332
|
+
// ANCHOR's center is at: bottomEdge - anchorHeight/2
|
|
333
|
+
// In center-origin coords: (bannerHeight/2 - anchorGapToEdge - anchorHeight/2) - bannerHeight/2
|
|
334
|
+
// = -anchorGapToEdge - anchorHeight/2
|
|
335
|
+
// But we need to express as offset from banner center for the y coordinate
|
|
336
|
+
// Actually, y=0 is banner center, y>0 is down
|
|
337
|
+
// Bottom edge of banner is at y = bannerHeight/2 (not scaled, in banner coords)
|
|
338
|
+
// ANCHOR bottom should be at: bannerHeight/2 - anchorGapToEdge (from center)
|
|
339
|
+
// ANCHOR center should be at: bannerHeight/2 - anchorGapToEdge - anchorHeight/2
|
|
340
|
+
anchorCenterY = (bannerHeight / 2) - anchorGapToEdge - (anchorHeight / 2);
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
// ANCHOR's top edge stays at: -(bannerHeight/2) + anchorGapToEdge
|
|
344
|
+
// ANCHOR's center is at: topEdge + anchorHeight/2
|
|
345
|
+
anchorCenterY = -(bannerHeight / 2) + anchorGapToEdge + (anchorHeight / 2);
|
|
346
|
+
}
|
|
347
|
+
positions[anchorId] = anchorCenterY;
|
|
348
|
+
console.log(`📍 ANCHOR ${anchorId}: centerY=${anchorCenterY.toFixed(2)}`);
|
|
349
|
+
// 2. Calculate positions for targets (grow in opposite direction from edge)
|
|
350
|
+
const direction = anchorEdge === 'bottom' ? -1 : 1; // -1 = up, 1 = down
|
|
351
|
+
const orderedTargets = orderChainFromAnchor(anchorId, links);
|
|
352
|
+
let prevElementId = anchorId;
|
|
353
|
+
let prevCenterY = anchorCenterY;
|
|
354
|
+
for (const targetId of orderedTargets) {
|
|
355
|
+
const link = links.find(l => l.from === prevElementId && l.to === targetId);
|
|
356
|
+
const gapPx = ((_a = link === null || link === void 0 ? void 0 : link.gapRem) !== null && _a !== void 0 ? _a : 0) * defaults_1.REM_TO_PIXELS;
|
|
357
|
+
const prevHeight = elementHeights[prevElementId] || 0;
|
|
358
|
+
const targetHeight = elementHeights[targetId] || 0;
|
|
359
|
+
// Target center = prev center + direction * (prev half height + gap + target half height)
|
|
360
|
+
const targetCenterY = prevCenterY + direction * ((prevHeight / 2) + gapPx + (targetHeight / 2));
|
|
361
|
+
positions[targetId] = targetCenterY;
|
|
362
|
+
// Debug log - uncomment for troubleshooting
|
|
363
|
+
// console.log(`📍 TARGET ${targetId}: centerY=${targetCenterY.toFixed(2)} (gap=${gapPx.toFixed(2)}, prevHeight=${prevHeight.toFixed(2)}, targetHeight=${targetHeight.toFixed(2)})`);
|
|
364
|
+
prevElementId = targetId;
|
|
365
|
+
prevCenterY = targetCenterY;
|
|
366
|
+
}
|
|
367
|
+
return positions;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Calculate target positions based on CURRENT anchor position from DOM
|
|
371
|
+
* This avoids the issue where recalculating anchorCenterY from anchorGapToEdge
|
|
372
|
+
* can produce different results than the actual DOM position
|
|
373
|
+
*/
|
|
374
|
+
function calculateTargetPositionsFromAnchor(anchorRef, bannerContainerRef, sizeMultiplier, links, elementHeights, anchorId) {
|
|
375
|
+
var _a;
|
|
376
|
+
const positions = {};
|
|
377
|
+
// Get ANCHOR's current center Y directly from DOM (relative to banner center)
|
|
378
|
+
const bannerBounds = bannerContainerRef.getBoundingClientRect();
|
|
379
|
+
const anchorBounds = anchorRef.getBoundingClientRect();
|
|
380
|
+
const bannerCenterY = bannerBounds.top + bannerBounds.height / 2;
|
|
381
|
+
const anchorCenterY = ((anchorBounds.top + anchorBounds.height / 2) - bannerCenterY) / sizeMultiplier;
|
|
382
|
+
positions[anchorId] = anchorCenterY;
|
|
383
|
+
console.log(`📍 ANCHOR ${anchorId}: centerY=${anchorCenterY.toFixed(2)} (from DOM)`);
|
|
384
|
+
// Detect direction based on anchor's position relative to banner center
|
|
385
|
+
// If anchor is below center (positive Y), targets grow UP (negative direction)
|
|
386
|
+
// If anchor is above center (negative Y), targets grow DOWN (positive direction)
|
|
387
|
+
const direction = anchorCenterY > 0 ? -1 : 1;
|
|
388
|
+
// Order targets and calculate their positions
|
|
389
|
+
const orderedTargets = orderChainFromAnchor(anchorId, links);
|
|
390
|
+
let prevElementId = anchorId;
|
|
391
|
+
let prevCenterY = anchorCenterY;
|
|
392
|
+
for (const targetId of orderedTargets) {
|
|
393
|
+
const link = links.find(l => l.from === prevElementId && l.to === targetId);
|
|
394
|
+
const gapPx = ((_a = link === null || link === void 0 ? void 0 : link.gapRem) !== null && _a !== void 0 ? _a : 0) * defaults_1.REM_TO_PIXELS;
|
|
395
|
+
const prevHeight = elementHeights[prevElementId] || 0;
|
|
396
|
+
const targetHeight = elementHeights[targetId] || 0;
|
|
397
|
+
// Target center = prev center + direction * (prev half height + gap + target half height)
|
|
398
|
+
const targetCenterY = prevCenterY + direction * ((prevHeight / 2) + gapPx + (targetHeight / 2));
|
|
399
|
+
positions[targetId] = targetCenterY;
|
|
400
|
+
// Debug log - uncomment for troubleshooting
|
|
401
|
+
// console.log(`📍 TARGET ${targetId}: centerY=${targetCenterY.toFixed(2)} (gap=${gapPx.toFixed(2)}, direction=${direction})`);
|
|
402
|
+
prevElementId = targetId;
|
|
403
|
+
prevCenterY = targetCenterY;
|
|
404
|
+
}
|
|
405
|
+
return positions;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Get copy/logo data for positioning calculations
|
|
409
|
+
* Extracts position and dimension data from a copy or logo element
|
|
410
|
+
*
|
|
411
|
+
* @param elementName - Element identifier ('logo' or 'copy-N')
|
|
412
|
+
* @param copies - Array of copy configurations
|
|
413
|
+
* @param config - Substyle configuration containing base positions
|
|
414
|
+
* @param logoTranslateX - Logo X translation
|
|
415
|
+
* @param logoTranslateY - Logo Y translation
|
|
416
|
+
* @param logoWidth - Optional logo width
|
|
417
|
+
* @returns Position and dimension data, or null if element not found
|
|
418
|
+
*/
|
|
419
|
+
function getCopyData(elementName, copies, config, logoTranslateX, logoTranslateY, logoWidth) {
|
|
420
|
+
var _a, _b, _c;
|
|
421
|
+
if (elementName === 'logo') {
|
|
422
|
+
return {
|
|
423
|
+
x: logoTranslateX,
|
|
424
|
+
y: logoTranslateY,
|
|
425
|
+
width: logoWidth || 0,
|
|
426
|
+
element: 'logo'
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
const copyMatch = elementName.match(/^copy-(\d+)$/);
|
|
430
|
+
if (copyMatch) {
|
|
431
|
+
const styleSlotIndex = parseInt(copyMatch[1], 10);
|
|
432
|
+
const copy = copies.find(c => c.styleSlot === styleSlotIndex) || copies[styleSlotIndex];
|
|
433
|
+
if (!copy) {
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
const copyConfig = (_a = config.copies) === null || _a === void 0 ? void 0 : _a[styleSlotIndex];
|
|
437
|
+
const baseX = (_b = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.x) !== null && _b !== void 0 ? _b : 0;
|
|
438
|
+
const baseY = (_c = copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.y) !== null && _c !== void 0 ? _c : 0;
|
|
439
|
+
return {
|
|
440
|
+
x: baseX + (copy.translateX || 0),
|
|
441
|
+
y: baseY + (copy.translateY || 0),
|
|
442
|
+
width: copy.width || (copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.width) || 0,
|
|
443
|
+
alignment: copy.align || (copyConfig === null || copyConfig === void 0 ? void 0 : copyConfig.alignment),
|
|
444
|
+
element: elementName
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
449
|
+
// ============================================================================
|
|
450
|
+
// Height Compensation Functions
|
|
451
|
+
// ============================================================================
|
|
452
|
+
/**
|
|
453
|
+
* Calculate compensation needed to keep an anchor's edge fixed when its height changes.
|
|
454
|
+
*
|
|
455
|
+
* With centerOrigin=true, when height increases the element grows equally up and down from center.
|
|
456
|
+
* The center stays fixed by CSS, so we need to move the element to keep the desired edge fixed.
|
|
457
|
+
*
|
|
458
|
+
* @param edge - Which edge should stay fixed ('top' or 'bottom')
|
|
459
|
+
* @param heightDelta - Change in height (positive = grew, negative = shrunk)
|
|
460
|
+
* @returns Compensation in pixels (add to current translateY)
|
|
461
|
+
*
|
|
462
|
+
* @example
|
|
463
|
+
* // If edge is 'bottom' and element grew by 20px:
|
|
464
|
+
* // Bottom edge moved DOWN by 10px, so move center UP (-10px) to keep bottom fixed
|
|
465
|
+
* calculateAnchorHeightCompensation('bottom', 20) // returns -10
|
|
466
|
+
*/
|
|
467
|
+
function calculateAnchorHeightCompensation(edge, heightDelta) {
|
|
468
|
+
// If edge is 'bottom': bottom edge moves DOWN by heightDelta/2, move center UP to compensate
|
|
469
|
+
// If edge is 'top': top edge moves UP by heightDelta/2, move center DOWN to compensate
|
|
470
|
+
return edge === 'bottom' ? -heightDelta / 2 : heightDelta / 2;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Calculate compensation for target elements when anchor height changes.
|
|
474
|
+
*
|
|
475
|
+
* When anchor grows, its edge toward the target moves, plus the anchor itself moves.
|
|
476
|
+
* Target must move by the full height delta to maintain the gap.
|
|
477
|
+
*
|
|
478
|
+
* @param edge - Anchor's fixed edge ('top' or 'bottom')
|
|
479
|
+
* @param heightDelta - Change in anchor height (positive = grew, negative = shrunk)
|
|
480
|
+
* @returns Compensation in pixels (add to current translateY)
|
|
481
|
+
*
|
|
482
|
+
* @example
|
|
483
|
+
* // If anchor edge is 'bottom' and anchor grew by 20px:
|
|
484
|
+
* // Target (above anchor) must move UP by 20px to maintain gap
|
|
485
|
+
* calculateTargetCompensationForAnchorGrowth('bottom', 20) // returns -20
|
|
486
|
+
*/
|
|
487
|
+
function calculateTargetCompensationForAnchorGrowth(edge, heightDelta) {
|
|
488
|
+
// If edge='bottom': anchor grows UP, target is above, target must move UP
|
|
489
|
+
// If edge='top': anchor grows DOWN, target is below, target must move DOWN
|
|
490
|
+
return edge === 'bottom' ? -heightDelta : heightDelta;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Calculate self-compensation for a target element when its own height changes.
|
|
494
|
+
*
|
|
495
|
+
* Target uses the same direction as anchor - it keeps the same edge fixed.
|
|
496
|
+
*
|
|
497
|
+
* @param edge - The fixed edge inherited from anchor ('top' or 'bottom')
|
|
498
|
+
* @param heightDelta - Change in target height (positive = grew, negative = shrunk)
|
|
499
|
+
* @returns Compensation in pixels (add to current translateY)
|
|
500
|
+
*/
|
|
501
|
+
function calculateTargetSelfCompensation(edge, heightDelta) {
|
|
502
|
+
// Same logic as anchor - keep the same edge fixed
|
|
503
|
+
return edge === 'bottom' ? -heightDelta / 2 : heightDelta / 2;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Calculate compensation for subsequent elements when a target's height changes.
|
|
507
|
+
*
|
|
508
|
+
* Elements after the growing target need to move by the full height delta
|
|
509
|
+
* to maintain their gaps with the target.
|
|
510
|
+
*
|
|
511
|
+
* @param edge - The fixed edge inherited from anchor ('top' or 'bottom')
|
|
512
|
+
* @param heightDelta - Change in target height (positive = grew, negative = shrunk)
|
|
513
|
+
* @returns Compensation in pixels (add to current translateY)
|
|
514
|
+
*/
|
|
515
|
+
function calculateSubsequentCompensation(edge, heightDelta) {
|
|
516
|
+
// Subsequent elements need to move by full heightDelta
|
|
517
|
+
return edge === 'bottom' ? -heightDelta : heightDelta;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Capture the initial configuration for edge-locking an anchor element.
|
|
521
|
+
*
|
|
522
|
+
* @param anchorRef - Reference to the anchor DOM element
|
|
523
|
+
* @param bannerContainerRef - Reference to the banner container
|
|
524
|
+
* @param sizeMultiplier - Current size multiplier for scaling
|
|
525
|
+
* @returns Configuration object for edge-locking, or null if refs are invalid
|
|
526
|
+
*/
|
|
527
|
+
function captureAnchorEdgeConfig(anchorId, anchorRef, bannerContainerRef, sizeMultiplier) {
|
|
528
|
+
const edge = detectNearestEdge(anchorRef, bannerContainerRef, sizeMultiplier);
|
|
529
|
+
const gapToEdge = calculateGapToEdge(anchorRef, edge, bannerContainerRef, sizeMultiplier);
|
|
530
|
+
const initialHeight = anchorRef.getBoundingClientRect().height / sizeMultiplier;
|
|
531
|
+
return {
|
|
532
|
+
anchorId,
|
|
533
|
+
edge,
|
|
534
|
+
gapToEdge,
|
|
535
|
+
initialHeight,
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Measure the heights of multiple elements.
|
|
540
|
+
*
|
|
541
|
+
* @param elementIds - Set of element IDs to measure
|
|
542
|
+
* @param refs - Object containing logo and copies refs
|
|
543
|
+
* @param copies - Array of copy configurations
|
|
544
|
+
* @param sizeMultiplier - Current size multiplier for scaling
|
|
545
|
+
* @returns Record mapping element ID to scaled height
|
|
546
|
+
*/
|
|
547
|
+
function measureElementHeights(elementIds, refs, copies, sizeMultiplier) {
|
|
548
|
+
const heights = {};
|
|
549
|
+
elementIds.forEach(elementId => {
|
|
550
|
+
const ref = getElementRef(elementId, refs, copies);
|
|
551
|
+
if (ref) {
|
|
552
|
+
heights[elementId] = ref.getBoundingClientRect().height / sizeMultiplier;
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
return heights;
|
|
556
|
+
}
|
|
557
|
+
// ============================================================================
|
|
558
|
+
// Generic Utilities
|
|
559
|
+
// ============================================================================
|
|
560
|
+
/**
|
|
561
|
+
* Compare two Maps for equality.
|
|
562
|
+
*
|
|
563
|
+
* @param map1 - First map to compare
|
|
564
|
+
* @param map2 - Second map to compare
|
|
565
|
+
* @returns True if maps have same keys and values
|
|
566
|
+
*
|
|
567
|
+
* @example
|
|
568
|
+
* const map1 = new Map([['a', '1'], ['b', '2']]);
|
|
569
|
+
* const map2 = new Map([['a', '1'], ['b', '2']]);
|
|
570
|
+
* mapsAreEqual(map1, map2) // returns true
|
|
571
|
+
*/
|
|
572
|
+
function mapsAreEqual(map1, map2) {
|
|
573
|
+
if (map1.size !== map2.size)
|
|
574
|
+
return false;
|
|
575
|
+
for (const [key, value] of map1) {
|
|
576
|
+
if (map2.get(key) !== value)
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
return true;
|
|
580
|
+
}
|
|
@@ -3,26 +3,14 @@
|
|
|
3
3
|
* Based on maxLengthThreshold values used in font size calculations
|
|
4
4
|
*/
|
|
5
5
|
export interface StyleCharacterLimits {
|
|
6
|
-
|
|
7
|
-
copy2?: number;
|
|
6
|
+
limits: number[];
|
|
8
7
|
copyCount: number;
|
|
9
8
|
}
|
|
10
9
|
export interface BannerConfig {
|
|
11
|
-
|
|
10
|
+
copies: {
|
|
12
11
|
supported: true;
|
|
13
|
-
|
|
14
|
-
isOptional: boolean;
|
|
15
|
-
};
|
|
16
|
-
copy2?: {
|
|
17
|
-
supported: boolean;
|
|
18
|
-
characterLimit?: number;
|
|
19
|
-
isOptional?: boolean;
|
|
20
|
-
};
|
|
21
|
-
fontSize_01: {
|
|
22
|
-
supported: true;
|
|
23
|
-
};
|
|
24
|
-
fontSize_02?: {
|
|
25
|
-
supported: boolean;
|
|
12
|
+
characterLimits: number[];
|
|
13
|
+
isOptional: boolean[];
|
|
26
14
|
};
|
|
27
15
|
logoUrl: {
|
|
28
16
|
supported: true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"characterLimits.d.ts","sourceRoot":"","sources":["../../src/constants/characterLimits.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,oBAAoB;IACnC,
|
|
1
|
+
{"version":3,"file":"characterLimits.d.ts","sourceRoot":"","sources":["../../src/constants/characterLimits.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE;QACN,SAAS,EAAE,IAAI,CAAC;QAChB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,UAAU,EAAE,OAAO,EAAE,CAAC;KACvB,CAAC;IACF,OAAO,EAAE;QAAE,SAAS,EAAE,IAAI,CAAA;KAAE,CAAC;IAC7B,kBAAkB,EAAE;QAAE,SAAS,EAAE,IAAI,CAAA;KAAE,CAAC;IACxC,0BAA0B,EAAE;QAAE,SAAS,EAAE,IAAI,CAAA;KAAE,CAAC;IAChD,yBAAyB,EAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;IAClD,kBAAkB,EAAE;QAAE,SAAS,EAAE,IAAI,CAAA;KAAE,CAAC;CACzC;AAED,MAAM,WAAW,qBAAqB;IACpC,CAAC,WAAW,EAAE,MAAM,GAAG;QACrB,CAAC,cAAc,EAAE,MAAM,GAAG,oBAAoB,CAAC;KAChD,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,CAAC,WAAW,EAAE,MAAM,GAAG;QACrB,CAAC,cAAc,EAAE,MAAM,GAAG,YAAY,CAAC;KACxC,CAAC;CACH;AAED;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,EAAE,qBAqB1C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,aAAa,MAAM,EACnB,gBAAgB,MAAM,KACrB,oBAAoB,GAAG,IAEzB,CAAC;AA8BF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,eAyBnC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC1B,aAAa,MAAM,EACnB,gBAAgB,MAAM,KACrB,YAAY,GAAG,IAEjB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,GAAG,SAAS,EAAE,OAAO,MAAM,KAAG,OAItE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,MAAM,EAE3C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,aAAa,MAAM,KAAG,MAAM,EAIjE,CAAC"}
|