zuljaman-banner-components 1.0.22 → 1.0.24
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 +71 -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 +332 -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 +51 -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
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* useAutoPositioning hook - Main Orchestrator
|
|
4
|
+
*
|
|
5
|
+
* This is the main hook that orchestrates all auto-positioning functionality.
|
|
6
|
+
* It composes several sub-hooks for better organization and maintainability.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.useAutoPositioning = useAutoPositioning;
|
|
43
|
+
const react_1 = __importStar(require("react"));
|
|
44
|
+
const styleConfig_1 = require("../../../../styleConfig");
|
|
45
|
+
const debugPositions_1 = require("./debugPositions");
|
|
46
|
+
const useAnchorEdgeLocking_1 = require("./useAnchorEdgeLocking");
|
|
47
|
+
const useHeightCompensation_1 = require("./useHeightCompensation");
|
|
48
|
+
const useChainPositioning_1 = require("./useChainPositioning");
|
|
49
|
+
/**
|
|
50
|
+
* Main hook that orchestrates auto-positioning functionality.
|
|
51
|
+
*/
|
|
52
|
+
function useAutoPositioning({ logoRef, copyRefs, bannerContainerRef, copies, sizeMultiplier, creationMode, completedLines, manualLines, lineGaps, setCompletedLines, setManualLines, setLineGaps, config, autoPositioningOverride, logoTranslateX, logoTranslateY, logoRotation, logoWidth, bannerStyle, onApplyAutoPositioning, onCopyPositionChange, onConnectionsDeleted, exposeDebugFunctions, areElementsOverlapping, areVerticallyAligned, configKey, }) {
|
|
53
|
+
// ============================================
|
|
54
|
+
// STATE
|
|
55
|
+
// ============================================
|
|
56
|
+
const [autoOffsets, setAutoOffsets] = (0, react_1.useState)({});
|
|
57
|
+
const [recalcTrigger, setRecalcTrigger] = (0, react_1.useState)(0);
|
|
58
|
+
const [anchorCompensation, setAnchorCompensation] = (0, react_1.useState)(0);
|
|
59
|
+
const [lineRecalcTrigger, setLineRecalcTrigger] = (0, react_1.useState)(0);
|
|
60
|
+
// Anchor edge-locking state
|
|
61
|
+
const [anchorEdgeConfig, setAnchorEdgeConfig] = (0, react_1.useState)(null);
|
|
62
|
+
const [targetHeights, setTargetHeights] = (0, react_1.useState)({});
|
|
63
|
+
// Refs for tracking previous state
|
|
64
|
+
const prevCompletedLinesRef = (0, react_1.useRef)(new Map());
|
|
65
|
+
const prevElementsInChainsRef = (0, react_1.useRef)(new Set());
|
|
66
|
+
const initialPositioningDoneRef = (0, react_1.useRef)(false);
|
|
67
|
+
// Flag to indicate configKey reset is in progress (prevents CHAIN-POS from resetting positions)
|
|
68
|
+
const configKeyResetInProgressRef = (0, react_1.useRef)(false);
|
|
69
|
+
// ============================================
|
|
70
|
+
// CONFIG KEY RESET
|
|
71
|
+
// ============================================
|
|
72
|
+
// Reset ALL state when configKey changes (style/substyle change)
|
|
73
|
+
// This ensures the library self-resets without requiring consumer to use key prop
|
|
74
|
+
// IMPORTANT: useLayoutEffect ensures reset happens BEFORE next paint (sync)
|
|
75
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
76
|
+
if (!configKey)
|
|
77
|
+
return; // Skip if configKey not provided (backward compat)
|
|
78
|
+
console.log('🔧 AUTO-POS useLayoutEffect - configKey reset:', configKey);
|
|
79
|
+
// Set flag to prevent CHAIN-POS from resetting positions during configKey change
|
|
80
|
+
configKeyResetInProgressRef.current = true;
|
|
81
|
+
// Reset all useState values
|
|
82
|
+
setAutoOffsets({});
|
|
83
|
+
setRecalcTrigger(0);
|
|
84
|
+
setAnchorCompensation(0);
|
|
85
|
+
setLineRecalcTrigger(0);
|
|
86
|
+
setAnchorEdgeConfig(null);
|
|
87
|
+
setTargetHeights({});
|
|
88
|
+
// Reset all refs
|
|
89
|
+
prevCompletedLinesRef.current = new Map();
|
|
90
|
+
prevElementsInChainsRef.current = new Set();
|
|
91
|
+
initialPositioningDoneRef.current = false;
|
|
92
|
+
console.log('🔧 AUTO-POS useLayoutEffect - reset completado');
|
|
93
|
+
// Clear flag after microtask to allow ANCHOR-LOCK to position elements first
|
|
94
|
+
queueMicrotask(() => {
|
|
95
|
+
configKeyResetInProgressRef.current = false;
|
|
96
|
+
});
|
|
97
|
+
}, [configKey]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
98
|
+
// ^ Intentionally only depend on configKey - we want to reset when config changes
|
|
99
|
+
// Get style configuration
|
|
100
|
+
const styleConfig = (0, styleConfig_1.getStyleConfig)(bannerStyle);
|
|
101
|
+
// ============================================
|
|
102
|
+
// MEMOIZED VALUES
|
|
103
|
+
// ============================================
|
|
104
|
+
// Helper to check if an element exists
|
|
105
|
+
const elementExists = react_1.default.useCallback((elementId) => {
|
|
106
|
+
if (elementId === 'logo')
|
|
107
|
+
return true;
|
|
108
|
+
if (elementId.startsWith('copy-')) {
|
|
109
|
+
const styleSlotStr = elementId.replace('copy-', '');
|
|
110
|
+
const styleSlot = parseInt(styleSlotStr, 10);
|
|
111
|
+
if (isNaN(styleSlot))
|
|
112
|
+
return false;
|
|
113
|
+
return copies.some(c => c.styleSlot === styleSlot) || styleSlot < copies.length;
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
}, [copies]);
|
|
117
|
+
// Derive effective auto-positioning config
|
|
118
|
+
const derivedAutoConfig = (0, react_1.useMemo)(() => {
|
|
119
|
+
let baseConfig;
|
|
120
|
+
if (creationMode) {
|
|
121
|
+
if (completedLines.size > 0) {
|
|
122
|
+
const links = [];
|
|
123
|
+
completedLines.forEach((toId, fromId) => {
|
|
124
|
+
const lineKey = `${fromId}->${toId}`;
|
|
125
|
+
const gapRem = lineGaps.get(lineKey);
|
|
126
|
+
links.push({
|
|
127
|
+
fromElement: fromId,
|
|
128
|
+
toElement: toId,
|
|
129
|
+
direction: 'down',
|
|
130
|
+
gapRem,
|
|
131
|
+
});
|
|
132
|
+
// Debug logs removed - were causing 800+ logs per session
|
|
133
|
+
// if (gapRem !== undefined) {
|
|
134
|
+
// console.log(`🔗 Link ${lineKey} using preserved gapRem: ${gapRem.toFixed(2)}`);
|
|
135
|
+
// }
|
|
136
|
+
});
|
|
137
|
+
baseConfig = { enabled: true, links };
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
baseConfig = undefined;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
baseConfig = config.autoPositioningConfig;
|
|
145
|
+
}
|
|
146
|
+
// Filter out links that reference non-existent elements
|
|
147
|
+
if (baseConfig === null || baseConfig === void 0 ? void 0 : baseConfig.links) {
|
|
148
|
+
const validLinks = baseConfig.links.filter(link => {
|
|
149
|
+
const fromExists = elementExists(link.fromElement);
|
|
150
|
+
const toExists = elementExists(link.toElement);
|
|
151
|
+
return fromExists && toExists;
|
|
152
|
+
});
|
|
153
|
+
if (validLinks.length !== baseConfig.links.length) {
|
|
154
|
+
return { ...baseConfig, links: validLinks };
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return baseConfig;
|
|
158
|
+
}, [creationMode, completedLines, lineGaps, config.autoPositioningConfig, elementExists]);
|
|
159
|
+
// Derive active links (unified Map for both modes)
|
|
160
|
+
const activeLinks = (0, react_1.useMemo)(() => {
|
|
161
|
+
var _a;
|
|
162
|
+
if (creationMode) {
|
|
163
|
+
return completedLines;
|
|
164
|
+
}
|
|
165
|
+
else if ((derivedAutoConfig === null || derivedAutoConfig === void 0 ? void 0 : derivedAutoConfig.enabled) && ((_a = derivedAutoConfig === null || derivedAutoConfig === void 0 ? void 0 : derivedAutoConfig.links) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
166
|
+
const linksMap = new Map();
|
|
167
|
+
derivedAutoConfig.links.forEach(link => {
|
|
168
|
+
linksMap.set(link.fromElement, link.toElement);
|
|
169
|
+
});
|
|
170
|
+
return linksMap;
|
|
171
|
+
}
|
|
172
|
+
return new Map();
|
|
173
|
+
}, [creationMode, completedLines, derivedAutoConfig]);
|
|
174
|
+
const hasActiveLinks = activeLinks.size > 0;
|
|
175
|
+
// ============================================
|
|
176
|
+
// BASIC EFFECTS
|
|
177
|
+
// ============================================
|
|
178
|
+
// Reset initial positioning flag when config changes
|
|
179
|
+
(0, react_1.useEffect)(() => {
|
|
180
|
+
initialPositioningDoneRef.current = false;
|
|
181
|
+
}, [derivedAutoConfig]);
|
|
182
|
+
// Trigger recalculation when style changes
|
|
183
|
+
(0, react_1.useEffect)(() => {
|
|
184
|
+
setRecalcTrigger(prev => prev + 1);
|
|
185
|
+
}, [bannerStyle]);
|
|
186
|
+
// Trigger line recalculation after text changes
|
|
187
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
188
|
+
if (!creationMode)
|
|
189
|
+
return;
|
|
190
|
+
requestAnimationFrame(() => {
|
|
191
|
+
requestAnimationFrame(() => {
|
|
192
|
+
setLineRecalcTrigger(prev => prev + 1);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
}, [copies.map(c => c.text).join('|'), anchorCompensation, recalcTrigger, creationMode]);
|
|
196
|
+
// Reset state when config changes
|
|
197
|
+
(0, react_1.useEffect)(() => {
|
|
198
|
+
console.log('📏 AUTO-POS - config changed, reseteando autoOffsets a {}');
|
|
199
|
+
setAutoOffsets({});
|
|
200
|
+
setAnchorCompensation(0);
|
|
201
|
+
}, [config]);
|
|
202
|
+
// ============================================
|
|
203
|
+
// DEBUG & APPLY FUNCTIONS
|
|
204
|
+
// ============================================
|
|
205
|
+
const debugPositions = react_1.default.useCallback(() => {
|
|
206
|
+
return (0, debugPositions_1.createDebugPositions)({
|
|
207
|
+
completedLines,
|
|
208
|
+
copies,
|
|
209
|
+
logoTranslateX,
|
|
210
|
+
logoTranslateY,
|
|
211
|
+
logoWidth,
|
|
212
|
+
config,
|
|
213
|
+
sizeMultiplier,
|
|
214
|
+
logoRef,
|
|
215
|
+
copyRefs,
|
|
216
|
+
bannerContainerRef,
|
|
217
|
+
})();
|
|
218
|
+
}, [completedLines, copies, logoTranslateX, logoTranslateY, logoWidth, config, sizeMultiplier, logoRef, copyRefs, bannerContainerRef]);
|
|
219
|
+
const applyAutoPositioningConfig = react_1.default.useCallback(() => {
|
|
220
|
+
const generatedConfig = debugPositions();
|
|
221
|
+
if (!generatedConfig)
|
|
222
|
+
return;
|
|
223
|
+
if (onApplyAutoPositioning && generatedConfig.autoPositioningConfig) {
|
|
224
|
+
onApplyAutoPositioning({
|
|
225
|
+
config: generatedConfig.autoPositioningConfig,
|
|
226
|
+
gapRem: generatedConfig.gapRem,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
setAutoOffsets(prev => {
|
|
230
|
+
console.log('📏 AUTO-POS applyAutoPositioningConfig - prev autoOffsets:', prev);
|
|
231
|
+
const preserved = {};
|
|
232
|
+
const prevElements = prevElementsInChainsRef.current;
|
|
233
|
+
Object.entries(prev).forEach(([key, value]) => {
|
|
234
|
+
const keyNum = Number(key);
|
|
235
|
+
let copy = copies === null || copies === void 0 ? void 0 : copies.find(c => c.styleSlot === keyNum);
|
|
236
|
+
if (!copy && copies && keyNum >= 0 && keyNum < copies.length) {
|
|
237
|
+
copy = copies[keyNum];
|
|
238
|
+
}
|
|
239
|
+
if (copy) {
|
|
240
|
+
const copyStyleSlot = copy.styleSlot !== undefined ? copy.styleSlot : keyNum;
|
|
241
|
+
const elementId = `copy-${copyStyleSlot}`;
|
|
242
|
+
if (prevElements.has(elementId)) {
|
|
243
|
+
preserved[keyNum] = value;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
console.log('📏 AUTO-POS applyAutoPositioningConfig - preserved autoOffsets:', preserved);
|
|
248
|
+
return preserved;
|
|
249
|
+
});
|
|
250
|
+
setAnchorCompensation(0);
|
|
251
|
+
setRecalcTrigger(prev => prev + 1);
|
|
252
|
+
}, [debugPositions, onApplyAutoPositioning, copies]);
|
|
253
|
+
// Expose debug functions
|
|
254
|
+
(0, react_1.useEffect)(() => {
|
|
255
|
+
if (exposeDebugFunctions) {
|
|
256
|
+
window.__debugBannerPositions = debugPositions;
|
|
257
|
+
window.__applyAutoPositioning = applyAutoPositioningConfig;
|
|
258
|
+
}
|
|
259
|
+
}, [debugPositions, exposeDebugFunctions, applyAutoPositioningConfig]);
|
|
260
|
+
// ============================================
|
|
261
|
+
// SUB-HOOKS
|
|
262
|
+
// ============================================
|
|
263
|
+
// Anchor edge locking and initial positioning
|
|
264
|
+
(0, useAnchorEdgeLocking_1.useAnchorEdgeLocking)({
|
|
265
|
+
activeLinks,
|
|
266
|
+
copies,
|
|
267
|
+
sizeMultiplier,
|
|
268
|
+
creationMode,
|
|
269
|
+
logoRef,
|
|
270
|
+
copyRefs,
|
|
271
|
+
bannerContainerRef,
|
|
272
|
+
derivedAutoConfig,
|
|
273
|
+
config,
|
|
274
|
+
onCopyPositionChange,
|
|
275
|
+
anchorEdgeConfig,
|
|
276
|
+
setAnchorEdgeConfig,
|
|
277
|
+
targetHeights,
|
|
278
|
+
setTargetHeights,
|
|
279
|
+
initialPositioningDoneRef,
|
|
280
|
+
});
|
|
281
|
+
// Height compensation for anchor and targets
|
|
282
|
+
(0, useHeightCompensation_1.useHeightCompensation)({
|
|
283
|
+
anchorEdgeConfig,
|
|
284
|
+
setAnchorEdgeConfig,
|
|
285
|
+
targetHeights,
|
|
286
|
+
setTargetHeights,
|
|
287
|
+
activeLinks,
|
|
288
|
+
hasActiveLinks,
|
|
289
|
+
copies,
|
|
290
|
+
sizeMultiplier,
|
|
291
|
+
creationMode,
|
|
292
|
+
logoRef,
|
|
293
|
+
copyRefs,
|
|
294
|
+
bannerContainerRef,
|
|
295
|
+
derivedAutoConfig,
|
|
296
|
+
config,
|
|
297
|
+
lineGaps,
|
|
298
|
+
onCopyPositionChange,
|
|
299
|
+
});
|
|
300
|
+
// Chain positioning and link lifecycle
|
|
301
|
+
(0, useChainPositioning_1.useChainPositioning)({
|
|
302
|
+
completedLines,
|
|
303
|
+
manualLines,
|
|
304
|
+
lineGaps,
|
|
305
|
+
setCompletedLines,
|
|
306
|
+
setLineGaps,
|
|
307
|
+
copies,
|
|
308
|
+
creationMode,
|
|
309
|
+
autoOffsets,
|
|
310
|
+
setAutoOffsets,
|
|
311
|
+
setAnchorCompensation,
|
|
312
|
+
onCopyPositionChange,
|
|
313
|
+
onConnectionsDeleted,
|
|
314
|
+
applyAutoPositioningConfig,
|
|
315
|
+
prevCompletedLinesRef,
|
|
316
|
+
prevElementsInChainsRef,
|
|
317
|
+
areElementsOverlapping,
|
|
318
|
+
areVerticallyAligned,
|
|
319
|
+
configKeyResetInProgressRef,
|
|
320
|
+
});
|
|
321
|
+
// ============================================
|
|
322
|
+
// RETURN
|
|
323
|
+
// ============================================
|
|
324
|
+
return {
|
|
325
|
+
autoOffsets,
|
|
326
|
+
anchorCompensation,
|
|
327
|
+
lineRecalcTrigger,
|
|
328
|
+
derivedAutoConfig,
|
|
329
|
+
debugPositions,
|
|
330
|
+
applyAutoPositioningConfig,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useChainPositioning hook
|
|
3
|
+
*
|
|
4
|
+
* Handles chain management: auto-apply positioning when links change,
|
|
5
|
+
* cleanup when links are deleted, and line validation.
|
|
6
|
+
*/
|
|
7
|
+
import type { CopyConfig } from '../../../../types';
|
|
8
|
+
/**
|
|
9
|
+
* Parameters for useChainPositioning hook.
|
|
10
|
+
*/
|
|
11
|
+
export interface UseChainPositioningParams {
|
|
12
|
+
/** Map of completed proximity lines (fromId → toId) */
|
|
13
|
+
completedLines: Map<string, string>;
|
|
14
|
+
/** Set of manually created line keys */
|
|
15
|
+
manualLines: Set<string>;
|
|
16
|
+
/** Map of line gaps (lineKey → gapRem) */
|
|
17
|
+
lineGaps: Map<string, number>;
|
|
18
|
+
/** Setter for completed lines */
|
|
19
|
+
setCompletedLines: React.Dispatch<React.SetStateAction<Map<string, string>>>;
|
|
20
|
+
/** Setter for line gaps */
|
|
21
|
+
setLineGaps: React.Dispatch<React.SetStateAction<Map<string, number>>>;
|
|
22
|
+
/** Array of copy configurations */
|
|
23
|
+
copies: CopyConfig[];
|
|
24
|
+
/** Whether in creation mode */
|
|
25
|
+
creationMode: boolean;
|
|
26
|
+
/** Record of auto-positioning offsets (styleSlot → offset) */
|
|
27
|
+
autoOffsets: Record<number, number>;
|
|
28
|
+
/** Setter for auto offsets */
|
|
29
|
+
setAutoOffsets: React.Dispatch<React.SetStateAction<Record<number, number>>>;
|
|
30
|
+
/** Setter for anchor compensation */
|
|
31
|
+
setAnchorCompensation: React.Dispatch<React.SetStateAction<number>>;
|
|
32
|
+
/** Callback to update copy position */
|
|
33
|
+
onCopyPositionChange?: (index: number, pos: {
|
|
34
|
+
x: number;
|
|
35
|
+
y: number;
|
|
36
|
+
}) => void;
|
|
37
|
+
/** Callback when connections are deleted */
|
|
38
|
+
onConnectionsDeleted?: () => void;
|
|
39
|
+
/** Function to apply auto-positioning configuration */
|
|
40
|
+
applyAutoPositioningConfig: () => void;
|
|
41
|
+
/** Ref to track previous completed lines state */
|
|
42
|
+
prevCompletedLinesRef: React.MutableRefObject<Map<string, string>>;
|
|
43
|
+
/** Ref to track previous elements in chains */
|
|
44
|
+
prevElementsInChainsRef: React.MutableRefObject<Set<string>>;
|
|
45
|
+
/** Function to check if two elements are overlapping */
|
|
46
|
+
areElementsOverlapping: (id1: string, id2: string) => boolean;
|
|
47
|
+
/** Function to check if two elements are vertically aligned */
|
|
48
|
+
areVerticallyAligned: (id1: string, id2: string) => boolean;
|
|
49
|
+
/** Ref to track if configKey reset is in progress (skip resetting positions) */
|
|
50
|
+
configKeyResetInProgressRef?: React.MutableRefObject<boolean>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Hook that manages chain positioning and link lifecycle.
|
|
54
|
+
*
|
|
55
|
+
* Responsibilities:
|
|
56
|
+
* - Auto-apply positioning when new links are created
|
|
57
|
+
* - Handle link deletion and cleanup
|
|
58
|
+
* - Validate manual lines
|
|
59
|
+
*/
|
|
60
|
+
export declare function useChainPositioning({ completedLines, manualLines, lineGaps, setCompletedLines, setLineGaps, copies, creationMode, autoOffsets, setAutoOffsets, setAnchorCompensation, onCopyPositionChange, onConnectionsDeleted, applyAutoPositioningConfig, prevCompletedLinesRef, prevElementsInChainsRef, areElementsOverlapping, areVerticallyAligned, configKeyResetInProgressRef, }: UseChainPositioningParams): void;
|
|
61
|
+
//# sourceMappingURL=useChainPositioning.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChainPositioning.d.ts","sourceRoot":"","sources":["../../../../../src/components/BannerRenderer/hooks/useAutoPositioning/useChainPositioning.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,uDAAuD;IACvD,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,wCAAwC;IACxC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,0CAA0C;IAC1C,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,iCAAiC;IACjC,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7E,2BAA2B;IAC3B,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACvE,mCAAmC;IACnC,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,+BAA+B;IAC/B,YAAY,EAAE,OAAO,CAAC;IACtB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,8BAA8B;IAC9B,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7E,qCAAqC;IACrC,qBAAqB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;IACpE,uCAAuC;IACvC,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9E,4CAA4C;IAC5C,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,uDAAuD;IACvD,0BAA0B,EAAE,MAAM,IAAI,CAAC;IACvC,kDAAkD;IAClD,qBAAqB,EAAE,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnE,+CAA+C;IAC/C,uBAAuB,EAAE,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,wDAAwD;IACxD,sBAAsB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9D,+DAA+D;IAC/D,oBAAoB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5D,gFAAgF;IAChF,2BAA2B,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;CAC/D;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,cAAc,EACd,WAAW,EACX,QAAQ,EACR,iBAAiB,EACjB,WAAW,EACX,MAAM,EACN,YAAY,EACZ,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,oBAAoB,EACpB,2BAA2B,GAC5B,EAAE,yBAAyB,GAAG,IAAI,CAyMlC"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* useChainPositioning hook
|
|
4
|
+
*
|
|
5
|
+
* Handles chain management: auto-apply positioning when links change,
|
|
6
|
+
* cleanup when links are deleted, and line validation.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.useChainPositioning = useChainPositioning;
|
|
10
|
+
const react_1 = require("react");
|
|
11
|
+
const positioningUtils_1 = require("../../../styles/utils/positioningUtils");
|
|
12
|
+
/**
|
|
13
|
+
* Hook that manages chain positioning and link lifecycle.
|
|
14
|
+
*
|
|
15
|
+
* Responsibilities:
|
|
16
|
+
* - Auto-apply positioning when new links are created
|
|
17
|
+
* - Handle link deletion and cleanup
|
|
18
|
+
* - Validate manual lines
|
|
19
|
+
*/
|
|
20
|
+
function useChainPositioning({ completedLines, manualLines, lineGaps, setCompletedLines, setLineGaps, copies, creationMode, autoOffsets, setAutoOffsets, setAnchorCompensation, onCopyPositionChange, onConnectionsDeleted, applyAutoPositioningConfig, prevCompletedLinesRef, prevElementsInChainsRef, areElementsOverlapping, areVerticallyAligned, configKeyResetInProgressRef, }) {
|
|
21
|
+
// Auto-apply positioning when new proximity lines are created
|
|
22
|
+
(0, react_1.useEffect)(() => {
|
|
23
|
+
if (!creationMode) {
|
|
24
|
+
prevCompletedLinesRef.current = completedLines;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const prev = prevCompletedLinesRef.current;
|
|
28
|
+
if ((0, positioningUtils_1.mapsAreEqual)(prev, completedLines)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const newLines = Array.from(completedLines.entries()).filter(([from, to]) => {
|
|
32
|
+
const prevTarget = prev.get(from);
|
|
33
|
+
return prevTarget !== to;
|
|
34
|
+
});
|
|
35
|
+
const deletedLines = Array.from(prev.entries()).filter(([from, prevTo]) => {
|
|
36
|
+
const currentTarget = completedLines.get(from);
|
|
37
|
+
return currentTarget !== prevTo;
|
|
38
|
+
});
|
|
39
|
+
// Build current elements in chains set
|
|
40
|
+
const elementsInChains = new Set();
|
|
41
|
+
completedLines.forEach((to, from) => {
|
|
42
|
+
elementsInChains.add(from);
|
|
43
|
+
elementsInChains.add(to);
|
|
44
|
+
});
|
|
45
|
+
const previousElementsInChains = prevElementsInChainsRef.current;
|
|
46
|
+
// Check if there are NEW elements in the chain
|
|
47
|
+
const hasNewElementsInChain = Array.from(elementsInChains).some(elementId => !previousElementsInChains.has(elementId));
|
|
48
|
+
// If new elements joined the chain OR new lines were created, apply auto-positioning
|
|
49
|
+
if (hasNewElementsInChain || newLines.length > 0) {
|
|
50
|
+
// Identify which elements are TARGETs
|
|
51
|
+
const targetElements = new Set();
|
|
52
|
+
completedLines.forEach((toId) => {
|
|
53
|
+
targetElements.add(toId);
|
|
54
|
+
});
|
|
55
|
+
// Reset translateY only for TARGET elements that JUST joined the chain
|
|
56
|
+
elementsInChains.forEach(elementId => {
|
|
57
|
+
const isNewToChain = !previousElementsInChains.has(elementId);
|
|
58
|
+
const isTarget = targetElements.has(elementId);
|
|
59
|
+
// Skip resetting y to 0 if configKey reset is in progress
|
|
60
|
+
// This prevents race condition where CHAIN-POS resets positions after ANCHOR-LOCK calculated them
|
|
61
|
+
if (isNewToChain && isTarget && elementId !== 'logo' && onCopyPositionChange && !(configKeyResetInProgressRef === null || configKeyResetInProgressRef === void 0 ? void 0 : configKeyResetInProgressRef.current)) {
|
|
62
|
+
const copyIndex = (0, positioningUtils_1.getCopyIndexFromElementId)(elementId, copies || []);
|
|
63
|
+
if (copyIndex !== undefined && copyIndex >= 0 && copyIndex < ((copies === null || copies === void 0 ? void 0 : copies.length) || 0)) {
|
|
64
|
+
const copy = copies[copyIndex];
|
|
65
|
+
console.log('⛓️ CHAIN-POS newToChain - copyIndex:', copyIndex, 'reseteando y a 0');
|
|
66
|
+
onCopyPositionChange(copyIndex, {
|
|
67
|
+
x: copy.translateX || 0,
|
|
68
|
+
y: 0,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
applyAutoPositioningConfig();
|
|
74
|
+
}
|
|
75
|
+
// ALWAYS update the ref to track current chain members
|
|
76
|
+
prevElementsInChainsRef.current = new Set(elementsInChains);
|
|
77
|
+
// If lines were deleted, remove auto-positioning
|
|
78
|
+
if (deletedLines.length > 0) {
|
|
79
|
+
const targetElements = new Set(deletedLines.map(([, to]) => to));
|
|
80
|
+
targetElements.forEach(targetElementName => {
|
|
81
|
+
let styleSlot;
|
|
82
|
+
const match = targetElementName.match(/^copy-(\d+)$/);
|
|
83
|
+
if (match) {
|
|
84
|
+
styleSlot = parseInt(match[1], 10);
|
|
85
|
+
}
|
|
86
|
+
if (styleSlot !== undefined) {
|
|
87
|
+
let copyIndex = copies.findIndex(c => c.styleSlot === styleSlot);
|
|
88
|
+
if (copyIndex === -1) {
|
|
89
|
+
copyIndex = styleSlot;
|
|
90
|
+
}
|
|
91
|
+
if (copyIndex >= 0 && copyIndex < copies.length) {
|
|
92
|
+
const copy = copies[copyIndex];
|
|
93
|
+
const offsetKey = copy.styleSlot !== undefined ? copy.styleSlot : copyIndex;
|
|
94
|
+
const currentAutoOffset = autoOffsets[offsetKey];
|
|
95
|
+
if (currentAutoOffset !== undefined && onCopyPositionChange) {
|
|
96
|
+
const currentTranslateY = copy.translateY || 0;
|
|
97
|
+
const newTranslateY = currentTranslateY + currentAutoOffset;
|
|
98
|
+
console.log('⛓️ CHAIN-POS deleted line - copyIndex:', copyIndex, 'newTranslateY:', newTranslateY);
|
|
99
|
+
onCopyPositionChange(copyIndex, {
|
|
100
|
+
x: copy.translateX || 0,
|
|
101
|
+
y: newTranslateY,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
// Build set of elements still in chains
|
|
108
|
+
const remainingElementsInChains = new Set();
|
|
109
|
+
completedLines.forEach((to, from) => {
|
|
110
|
+
remainingElementsInChains.add(from);
|
|
111
|
+
remainingElementsInChains.add(to);
|
|
112
|
+
});
|
|
113
|
+
setAutoOffsets(prev => {
|
|
114
|
+
const result = {};
|
|
115
|
+
Object.entries(prev).forEach(([key, value]) => {
|
|
116
|
+
const keyNum = Number(key);
|
|
117
|
+
let copy = copies === null || copies === void 0 ? void 0 : copies.find(c => c.styleSlot === keyNum);
|
|
118
|
+
if (!copy && copies && keyNum >= 0 && keyNum < copies.length) {
|
|
119
|
+
copy = copies[keyNum];
|
|
120
|
+
}
|
|
121
|
+
if (copy) {
|
|
122
|
+
const elementId = `copy-${copy.id}`;
|
|
123
|
+
if (remainingElementsInChains.has(elementId)) {
|
|
124
|
+
result[keyNum] = value;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
return result;
|
|
129
|
+
});
|
|
130
|
+
setAnchorCompensation(0);
|
|
131
|
+
// Clean up gaps for deleted lines (only manual lines)
|
|
132
|
+
setLineGaps(prevGaps => {
|
|
133
|
+
const newGaps = new Map(prevGaps);
|
|
134
|
+
deletedLines.forEach(([from, to]) => {
|
|
135
|
+
const lineKey = `${from}->${to}`;
|
|
136
|
+
const isManualLine = manualLines.has(lineKey);
|
|
137
|
+
if (isManualLine) {
|
|
138
|
+
newGaps.delete(lineKey);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
return newGaps;
|
|
142
|
+
});
|
|
143
|
+
if (onConnectionsDeleted) {
|
|
144
|
+
onConnectionsDeleted();
|
|
145
|
+
}
|
|
146
|
+
prevElementsInChainsRef.current = remainingElementsInChains;
|
|
147
|
+
}
|
|
148
|
+
prevCompletedLinesRef.current = new Map(completedLines);
|
|
149
|
+
}, [completedLines, creationMode, applyAutoPositioningConfig, copies, autoOffsets, onCopyPositionChange, onConnectionsDeleted, setLineGaps, manualLines, prevCompletedLinesRef, prevElementsInChainsRef, setAutoOffsets, setAnchorCompensation]);
|
|
150
|
+
// Validate and remove invalid lines automatically
|
|
151
|
+
(0, react_1.useEffect)(() => {
|
|
152
|
+
if (!creationMode)
|
|
153
|
+
return;
|
|
154
|
+
setCompletedLines(prev => {
|
|
155
|
+
const validLines = new Map();
|
|
156
|
+
let removedCount = 0;
|
|
157
|
+
prev.forEach((targetId, sourceId) => {
|
|
158
|
+
const lineKey = `${sourceId}->${targetId}`;
|
|
159
|
+
const isManualLine = manualLines.has(lineKey);
|
|
160
|
+
if (!isManualLine) {
|
|
161
|
+
validLines.set(sourceId, targetId);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const isOverlapping = areElementsOverlapping(sourceId, targetId);
|
|
165
|
+
const isAligned = areVerticallyAligned(sourceId, targetId);
|
|
166
|
+
if (!isOverlapping && isAligned) {
|
|
167
|
+
validLines.set(sourceId, targetId);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
removedCount++;
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
if (removedCount > 0) {
|
|
174
|
+
return validLines;
|
|
175
|
+
}
|
|
176
|
+
return prev;
|
|
177
|
+
});
|
|
178
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
179
|
+
}, [creationMode, manualLines, setCompletedLines]);
|
|
180
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useHeightCompensation hook
|
|
3
|
+
*
|
|
4
|
+
* Handles height compensation for anchor and target elements when their text changes.
|
|
5
|
+
* Maintains edge-locking by adjusting positions when element heights change.
|
|
6
|
+
*/
|
|
7
|
+
import type { CopyConfig } from '../../../../types';
|
|
8
|
+
import type { SubstyleConfig, AutoPositioningConfig } from '../../../styles/types/substyleTypes';
|
|
9
|
+
import type { AnchorEdgeState } from './useAnchorEdgeLocking';
|
|
10
|
+
/**
|
|
11
|
+
* Parameters for useHeightCompensation hook.
|
|
12
|
+
*/
|
|
13
|
+
export interface UseHeightCompensationParams {
|
|
14
|
+
/** Current anchor edge configuration */
|
|
15
|
+
anchorEdgeConfig: AnchorEdgeState | null;
|
|
16
|
+
/** Setter for anchor edge configuration */
|
|
17
|
+
setAnchorEdgeConfig: React.Dispatch<React.SetStateAction<AnchorEdgeState | null>>;
|
|
18
|
+
/** Record of target element heights (elementId → height) */
|
|
19
|
+
targetHeights: Record<string, number>;
|
|
20
|
+
/** Setter for target heights */
|
|
21
|
+
setTargetHeights: React.Dispatch<React.SetStateAction<Record<string, number>>>;
|
|
22
|
+
/** Map of active links (fromId → toId) */
|
|
23
|
+
activeLinks: Map<string, string>;
|
|
24
|
+
/** Whether there are any active links */
|
|
25
|
+
hasActiveLinks: boolean;
|
|
26
|
+
/** Array of copy configurations */
|
|
27
|
+
copies: CopyConfig[];
|
|
28
|
+
/** Current size multiplier for scaling */
|
|
29
|
+
sizeMultiplier: number;
|
|
30
|
+
/** Whether in creation mode */
|
|
31
|
+
creationMode: boolean;
|
|
32
|
+
/** Reference to the logo element */
|
|
33
|
+
logoRef: React.RefObject<HTMLDivElement | null>;
|
|
34
|
+
/** References to copy elements */
|
|
35
|
+
copyRefs: React.MutableRefObject<(HTMLDivElement | null)[]>;
|
|
36
|
+
/** Reference to the banner container */
|
|
37
|
+
bannerContainerRef: React.RefObject<HTMLDivElement | null>;
|
|
38
|
+
/** Derived auto-positioning configuration */
|
|
39
|
+
derivedAutoConfig: AutoPositioningConfig | undefined;
|
|
40
|
+
/** Substyle configuration */
|
|
41
|
+
config: SubstyleConfig;
|
|
42
|
+
/** Map of line gaps (lineKey → gapRem) */
|
|
43
|
+
lineGaps: Map<string, number>;
|
|
44
|
+
/** Callback to update copy position */
|
|
45
|
+
onCopyPositionChange?: (index: number, pos: {
|
|
46
|
+
x: number;
|
|
47
|
+
y: number;
|
|
48
|
+
}) => void;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Hook that manages height compensation for anchor and target elements.
|
|
52
|
+
*
|
|
53
|
+
* Responsibilities:
|
|
54
|
+
* - Adjust anchor position when its height changes (edge-locking)
|
|
55
|
+
* - Adjust target positions when anchor grows
|
|
56
|
+
* - Adjust target positions when they grow (self-compensation)
|
|
57
|
+
* - Move subsequent elements in chain when any element grows
|
|
58
|
+
*/
|
|
59
|
+
export declare function useHeightCompensation({ anchorEdgeConfig, setAnchorEdgeConfig, targetHeights, setTargetHeights, activeLinks, hasActiveLinks, copies, sizeMultiplier, creationMode, logoRef, copyRefs, bannerContainerRef, derivedAutoConfig, config, lineGaps, onCopyPositionChange, }: UseHeightCompensationParams): void;
|
|
60
|
+
//# sourceMappingURL=useHeightCompensation.d.ts.map
|
package/dist/components/BannerRenderer/hooks/useAutoPositioning/useHeightCompensation.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHeightCompensation.d.ts","sourceRoot":"","sources":["../../../../../src/components/BannerRenderer/hooks/useAutoPositioning/useHeightCompensation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AASjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,wCAAwC;IACxC,gBAAgB,EAAE,eAAe,GAAG,IAAI,CAAC;IACzC,2CAA2C;IAC3C,mBAAmB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAClF,4DAA4D;IAC5D,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,gCAAgC;IAChC,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC/E,0CAA0C;IAC1C,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,yCAAyC;IACzC,cAAc,EAAE,OAAO,CAAC;IACxB,mCAAmC;IACnC,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,0CAA0C;IAC1C,cAAc,EAAE,MAAM,CAAC;IACvB,+BAA+B;IAC/B,YAAY,EAAE,OAAO,CAAC;IACtB,oCAAoC;IACpC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAChD,kCAAkC;IAClC,QAAQ,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5D,wCAAwC;IACxC,kBAAkB,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC3D,6CAA6C;IAC7C,iBAAiB,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACrD,6BAA6B;IAC7B,MAAM,EAAE,cAAc,CAAC;IACvB,0CAA0C;IAC1C,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,uCAAuC;IACvC,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,MAAM,EACN,cAAc,EACd,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,MAAM,EACN,QAAQ,EACR,oBAAoB,GACrB,EAAE,2BAA2B,GAAG,IAAI,CA4LpC"}
|