@flowtomic/logic 0.1.0 → 0.1.1
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/dist/hooks/useAnimatedIndicator/index.d.ts +3 -0
- package/dist/hooks/useAnimatedIndicator/index.d.ts.map +1 -0
- package/dist/hooks/useAnimatedIndicator/index.js +1 -0
- package/dist/hooks/useAnimatedIndicator/useAnimatedIndicator.d.ts +94 -0
- package/dist/hooks/useAnimatedIndicator/useAnimatedIndicator.d.ts.map +1 -0
- package/dist/hooks/useAnimatedIndicator/useAnimatedIndicator.js +228 -0
- package/dist/hooks/useGenealogy/index.d.ts +3 -0
- package/dist/hooks/useGenealogy/index.d.ts.map +1 -0
- package/dist/hooks/useGenealogy/index.js +1 -0
- package/dist/hooks/useGenealogy/useGenealogy.d.ts +96 -0
- package/dist/hooks/useGenealogy/useGenealogy.d.ts.map +1 -0
- package/dist/hooks/useGenealogy/useGenealogy.js +335 -0
- package/dist/hooks/useMoblile/index.js +1 -868
- package/dist/hooks/useProjectProgress/index.d.ts +3 -0
- package/dist/hooks/useProjectProgress/index.d.ts.map +1 -0
- package/dist/hooks/useProjectProgress/index.js +1 -0
- package/dist/hooks/useProjectProgress/useProjectProgress.d.ts +103 -0
- package/dist/hooks/useProjectProgress/useProjectProgress.d.ts.map +1 -0
- package/dist/hooks/useProjectProgress/useProjectProgress.js +124 -0
- package/dist/hooks/useProjectStats/index.d.ts +3 -0
- package/dist/hooks/useProjectStats/index.d.ts.map +1 -0
- package/dist/hooks/useProjectStats/index.js +1 -0
- package/dist/hooks/useProjectStats/useProjectStats.d.ts +130 -0
- package/dist/hooks/useProjectStats/useProjectStats.d.ts.map +1 -0
- package/dist/hooks/useProjectStats/useProjectStats.js +87 -0
- package/dist/hooks/useResizable/index.d.ts +1 -1
- package/dist/hooks/useResizable/index.d.ts.map +1 -1
- package/dist/hooks/useStatCard/useStatCard.d.ts +44 -5
- package/dist/hooks/useStatCard/useStatCard.d.ts.map +1 -1
- package/dist/hooks/useStatCard/useStatCard.js +81 -20
- package/dist/hooks/useTimeTracker/index.d.ts +3 -0
- package/dist/hooks/useTimeTracker/index.d.ts.map +1 -0
- package/dist/hooks/useTimeTracker/index.js +1 -0
- package/dist/hooks/useTimeTracker/useTimeTracker.d.ts +106 -0
- package/dist/hooks/useTimeTracker/useTimeTracker.d.ts.map +1 -0
- package/dist/hooks/useTimeTracker/useTimeTracker.js +143 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAnimatedIndicator/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useAnimatedIndicator } from "./useAnimatedIndicator";
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useAnimatedIndicator - Headless UI Hook
|
|
3
|
+
*
|
|
4
|
+
* Hook reutilizável para animação de indicador que se move entre elementos
|
|
5
|
+
* Fornece apenas: lógica, estado e cálculos de posição
|
|
6
|
+
* NÃO fornece: markup, styles ou implementações pré-construídas
|
|
7
|
+
*
|
|
8
|
+
* Padrão Headless UI: você controla o markup e styles
|
|
9
|
+
*/
|
|
10
|
+
export interface IndicatorStyle {
|
|
11
|
+
left: number;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
top: number;
|
|
15
|
+
opacity: number;
|
|
16
|
+
}
|
|
17
|
+
export interface UseAnimatedIndicatorOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Container que contém os elementos
|
|
20
|
+
*/
|
|
21
|
+
containerRef: React.RefObject<HTMLElement>;
|
|
22
|
+
/**
|
|
23
|
+
* Seletor CSS para encontrar o elemento ativo (ex: '[data-state="active"]')
|
|
24
|
+
* @default '[data-state="active"]'
|
|
25
|
+
*/
|
|
26
|
+
activeSelector?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Callback para obter o valor/identificador do elemento
|
|
29
|
+
* Se não fornecido, usa o atributo 'data-value' ou busca no Map
|
|
30
|
+
*/
|
|
31
|
+
getElementValue?: (element: HTMLElement) => string;
|
|
32
|
+
/**
|
|
33
|
+
* Se deve atualizar automaticamente quando o container é redimensionado
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
updateOnResize?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface UseAnimatedIndicatorReturn {
|
|
39
|
+
/**
|
|
40
|
+
* Estilo do indicador (posição e dimensões)
|
|
41
|
+
*/
|
|
42
|
+
indicatorStyle: IndicatorStyle;
|
|
43
|
+
/**
|
|
44
|
+
* Registra um elemento para rastreamento
|
|
45
|
+
*/
|
|
46
|
+
registerElement: (element: HTMLElement | null, value: string) => void;
|
|
47
|
+
/**
|
|
48
|
+
* Remove um elemento do rastreamento
|
|
49
|
+
*/
|
|
50
|
+
unregisterElement: (value: string) => void;
|
|
51
|
+
/**
|
|
52
|
+
* Força atualização do indicador
|
|
53
|
+
*/
|
|
54
|
+
updateIndicator: () => void;
|
|
55
|
+
/**
|
|
56
|
+
* Valor do elemento ativo
|
|
57
|
+
*/
|
|
58
|
+
activeValue: string | undefined;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Hook headless para animação de indicador
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```tsx
|
|
65
|
+
* const containerRef = useRef<HTMLDivElement>(null);
|
|
66
|
+
* const { indicatorStyle, registerElement, unregisterElement } = useAnimatedIndicator({
|
|
67
|
+
* containerRef,
|
|
68
|
+
* activeSelector: '[data-state="active"]',
|
|
69
|
+
* });
|
|
70
|
+
*
|
|
71
|
+
* return (
|
|
72
|
+
* <div ref={containerRef}>
|
|
73
|
+
* {items.map((item) => (
|
|
74
|
+
* <button
|
|
75
|
+
* ref={(el) => registerElement(el, item.id)}
|
|
76
|
+
* data-state={isActive ? "active" : "inactive"}
|
|
77
|
+
* >
|
|
78
|
+
* {item.label}
|
|
79
|
+
* </button>
|
|
80
|
+
* ))}
|
|
81
|
+
* <motion.div
|
|
82
|
+
* style={{
|
|
83
|
+
* left: `${indicatorStyle.left}px`,
|
|
84
|
+
* top: `${indicatorStyle.top}px`,
|
|
85
|
+
* width: indicatorStyle.width,
|
|
86
|
+
* height: indicatorStyle.height,
|
|
87
|
+
* }}
|
|
88
|
+
* />
|
|
89
|
+
* </div>
|
|
90
|
+
* );
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export declare function useAnimatedIndicator(options: UseAnimatedIndicatorOptions): UseAnimatedIndicatorReturn;
|
|
94
|
+
//# sourceMappingURL=useAnimatedIndicator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAnimatedIndicator.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAnimatedIndicator/useAnimatedIndicator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC3C;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,MAAM,CAAC;IACnD;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B;;OAEG;IACH,eAAe,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtE;;OAEG;IACH,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C;;OAEG;IACH,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B;;OAEG;IACH,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,2BAA2B,GACnC,0BAA0B,CA+N5B"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useAnimatedIndicator - Headless UI Hook
|
|
3
|
+
*
|
|
4
|
+
* Hook reutilizável para animação de indicador que se move entre elementos
|
|
5
|
+
* Fornece apenas: lógica, estado e cálculos de posição
|
|
6
|
+
* NÃO fornece: markup, styles ou implementações pré-construídas
|
|
7
|
+
*
|
|
8
|
+
* Padrão Headless UI: você controla o markup e styles
|
|
9
|
+
*/
|
|
10
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
11
|
+
/**
|
|
12
|
+
* Hook headless para animação de indicador
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* const containerRef = useRef<HTMLDivElement>(null);
|
|
17
|
+
* const { indicatorStyle, registerElement, unregisterElement } = useAnimatedIndicator({
|
|
18
|
+
* containerRef,
|
|
19
|
+
* activeSelector: '[data-state="active"]',
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* return (
|
|
23
|
+
* <div ref={containerRef}>
|
|
24
|
+
* {items.map((item) => (
|
|
25
|
+
* <button
|
|
26
|
+
* ref={(el) => registerElement(el, item.id)}
|
|
27
|
+
* data-state={isActive ? "active" : "inactive"}
|
|
28
|
+
* >
|
|
29
|
+
* {item.label}
|
|
30
|
+
* </button>
|
|
31
|
+
* ))}
|
|
32
|
+
* <motion.div
|
|
33
|
+
* style={{
|
|
34
|
+
* left: `${indicatorStyle.left}px`,
|
|
35
|
+
* top: `${indicatorStyle.top}px`,
|
|
36
|
+
* width: indicatorStyle.width,
|
|
37
|
+
* height: indicatorStyle.height,
|
|
38
|
+
* }}
|
|
39
|
+
* />
|
|
40
|
+
* </div>
|
|
41
|
+
* );
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export function useAnimatedIndicator(options) {
|
|
45
|
+
const { containerRef, activeSelector = '[data-state="active"]', getElementValue, updateOnResize = true, } = options;
|
|
46
|
+
const elementsRef = useRef(new Map());
|
|
47
|
+
const updateTimeoutRef = useRef(null);
|
|
48
|
+
const activeValueRef = useRef(undefined);
|
|
49
|
+
const [indicatorStyle, setIndicatorStyle] = useState({
|
|
50
|
+
left: 0,
|
|
51
|
+
width: 0,
|
|
52
|
+
height: 0,
|
|
53
|
+
top: 0,
|
|
54
|
+
opacity: 0,
|
|
55
|
+
});
|
|
56
|
+
const [activeValue, setActiveValue] = useState();
|
|
57
|
+
// Sincronizar ref com state
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
activeValueRef.current = activeValue;
|
|
60
|
+
}, [activeValue]);
|
|
61
|
+
const updateIndicator = useCallback(() => {
|
|
62
|
+
const currentActiveValue = activeValueRef.current;
|
|
63
|
+
if (!currentActiveValue) {
|
|
64
|
+
setIndicatorStyle((prev) => {
|
|
65
|
+
if (prev.opacity === 0)
|
|
66
|
+
return prev;
|
|
67
|
+
return { left: 0, width: 0, height: 0, top: 0, opacity: 0 };
|
|
68
|
+
});
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const activeElement = elementsRef.current.get(currentActiveValue);
|
|
72
|
+
const container = containerRef.current;
|
|
73
|
+
if (activeElement && container) {
|
|
74
|
+
const elementRect = activeElement.getBoundingClientRect();
|
|
75
|
+
const containerRect = container.getBoundingClientRect();
|
|
76
|
+
// Calcular posição relativa ao container
|
|
77
|
+
const left = elementRect.left - containerRect.left;
|
|
78
|
+
const width = elementRect.width;
|
|
79
|
+
const height = elementRect.height;
|
|
80
|
+
const top = elementRect.top - containerRect.top;
|
|
81
|
+
setIndicatorStyle((prev) => {
|
|
82
|
+
// Evitar atualização se os valores não mudaram
|
|
83
|
+
if (prev.left === left &&
|
|
84
|
+
prev.width === width &&
|
|
85
|
+
prev.height === height &&
|
|
86
|
+
prev.top === top &&
|
|
87
|
+
prev.opacity === 1) {
|
|
88
|
+
return prev;
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
left,
|
|
92
|
+
width,
|
|
93
|
+
height,
|
|
94
|
+
top,
|
|
95
|
+
opacity: 1,
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}, [containerRef]);
|
|
100
|
+
// Função para agendar atualização (debounce) - estável
|
|
101
|
+
const scheduleUpdateRef = useRef(undefined);
|
|
102
|
+
// Atualizar a função no ref sempre que updateIndicator mudar
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
scheduleUpdateRef.current = () => {
|
|
105
|
+
if (updateTimeoutRef.current !== null) {
|
|
106
|
+
cancelAnimationFrame(updateTimeoutRef.current);
|
|
107
|
+
}
|
|
108
|
+
updateTimeoutRef.current = requestAnimationFrame(() => {
|
|
109
|
+
updateIndicator();
|
|
110
|
+
updateTimeoutRef.current = null;
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
}, [updateIndicator]);
|
|
114
|
+
const scheduleUpdate = useCallback(() => {
|
|
115
|
+
scheduleUpdateRef.current?.();
|
|
116
|
+
}, []);
|
|
117
|
+
// Atualizar quando activeValue mudar
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
scheduleUpdate();
|
|
120
|
+
}, [activeValue, scheduleUpdate]);
|
|
121
|
+
// Listener de resize
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
if (!updateOnResize)
|
|
124
|
+
return;
|
|
125
|
+
const handleResize = () => scheduleUpdate();
|
|
126
|
+
window.addEventListener("resize", handleResize);
|
|
127
|
+
return () => {
|
|
128
|
+
window.removeEventListener("resize", handleResize);
|
|
129
|
+
if (updateTimeoutRef.current !== null) {
|
|
130
|
+
cancelAnimationFrame(updateTimeoutRef.current);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}, [scheduleUpdate, updateOnResize]);
|
|
134
|
+
const registerElement = useCallback((element, value) => {
|
|
135
|
+
const previousElement = elementsRef.current.get(value);
|
|
136
|
+
// Só atualizar se o elemento realmente mudou
|
|
137
|
+
if (element === previousElement) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (element) {
|
|
141
|
+
elementsRef.current.set(value, element);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
// Só remover se o elemento existia antes
|
|
145
|
+
if (previousElement) {
|
|
146
|
+
elementsRef.current.delete(value);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
return; // Elemento já não existe, não precisa atualizar
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Agendar atualização de forma assíncrona para evitar loops
|
|
153
|
+
// Só atualizar se temos um elemento válido
|
|
154
|
+
if (element) {
|
|
155
|
+
scheduleUpdate();
|
|
156
|
+
}
|
|
157
|
+
}, [scheduleUpdate]);
|
|
158
|
+
const unregisterElement = useCallback((value) => {
|
|
159
|
+
elementsRef.current.delete(value);
|
|
160
|
+
scheduleUpdate();
|
|
161
|
+
}, [scheduleUpdate]);
|
|
162
|
+
// Refs para opções estáveis
|
|
163
|
+
const activeSelectorRef = useRef(activeSelector);
|
|
164
|
+
const getElementValueRef = useRef(getElementValue);
|
|
165
|
+
useEffect(() => {
|
|
166
|
+
activeSelectorRef.current = activeSelector;
|
|
167
|
+
getElementValueRef.current = getElementValue;
|
|
168
|
+
}, [activeSelector, getElementValue]);
|
|
169
|
+
// Observar mudanças no elemento ativo
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
const container = containerRef.current;
|
|
172
|
+
if (!container)
|
|
173
|
+
return;
|
|
174
|
+
const findActiveValue = () => {
|
|
175
|
+
const activeElement = container.querySelector(activeSelectorRef.current);
|
|
176
|
+
if (activeElement) {
|
|
177
|
+
let value;
|
|
178
|
+
if (getElementValueRef.current) {
|
|
179
|
+
value = getElementValueRef.current(activeElement);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// Tentar obter do atributo data-value
|
|
183
|
+
value = activeElement.getAttribute("data-value") || undefined;
|
|
184
|
+
// Se não tiver data-value, buscar no Map pelo elemento
|
|
185
|
+
if (!value) {
|
|
186
|
+
for (const [mapValue, mapElement] of elementsRef.current.entries()) {
|
|
187
|
+
if (mapElement === activeElement) {
|
|
188
|
+
value = mapValue;
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (value) {
|
|
195
|
+
setActiveValue((prev) => {
|
|
196
|
+
// Só atualizar se o valor realmente mudou
|
|
197
|
+
if (prev !== value) {
|
|
198
|
+
return value;
|
|
199
|
+
}
|
|
200
|
+
return prev;
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
const observer = new MutationObserver(() => {
|
|
206
|
+
// Usar requestAnimationFrame para evitar chamadas síncronas
|
|
207
|
+
requestAnimationFrame(findActiveValue);
|
|
208
|
+
});
|
|
209
|
+
observer.observe(container, {
|
|
210
|
+
attributes: true,
|
|
211
|
+
attributeFilter: ["data-state", "data-active", "aria-selected"],
|
|
212
|
+
subtree: true,
|
|
213
|
+
});
|
|
214
|
+
// Verificar estado inicial com delay para evitar loop
|
|
215
|
+
const timeoutId = setTimeout(findActiveValue, 0);
|
|
216
|
+
return () => {
|
|
217
|
+
observer.disconnect();
|
|
218
|
+
clearTimeout(timeoutId);
|
|
219
|
+
};
|
|
220
|
+
}, [containerRef]);
|
|
221
|
+
return {
|
|
222
|
+
indicatorStyle,
|
|
223
|
+
registerElement,
|
|
224
|
+
unregisterElement,
|
|
225
|
+
updateIndicator,
|
|
226
|
+
activeValue,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useGenealogy/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useGenealogy } from "./useGenealogy";
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useGenealogy - Headless UI Hook
|
|
3
|
+
*
|
|
4
|
+
* Fornece apenas: lógica, estado, processamento e API para árvores genealógicas
|
|
5
|
+
* NÃO fornece: markup, styles ou implementações pré-construídas
|
|
6
|
+
*
|
|
7
|
+
* Padrão Headless UI: você controla o markup e styles
|
|
8
|
+
*/
|
|
9
|
+
import type { Edge as ReactFlowEdge, Node as ReactFlowNode } from "@xyflow/react";
|
|
10
|
+
/**
|
|
11
|
+
* Tipos de relacionamento
|
|
12
|
+
*/
|
|
13
|
+
export type RelationshipType = "mother" | "father" | "child";
|
|
14
|
+
/**
|
|
15
|
+
* Dados de uma entidade na árvore genealógica (pessoa, animal, ninhada, etc.)
|
|
16
|
+
*/
|
|
17
|
+
export interface EntityData {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
birthDate?: string;
|
|
21
|
+
deathDate?: string;
|
|
22
|
+
gender?: "male" | "female" | "other";
|
|
23
|
+
image?: string;
|
|
24
|
+
photo?: string;
|
|
25
|
+
[key: string]: unknown;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Relacionamento entre entidades
|
|
29
|
+
*/
|
|
30
|
+
export interface Relationship {
|
|
31
|
+
from: string;
|
|
32
|
+
to: string;
|
|
33
|
+
type: RelationshipType;
|
|
34
|
+
metadata?: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Estrutura de dados de entrada para a árvore genealógica
|
|
38
|
+
*/
|
|
39
|
+
export interface GenealogyData {
|
|
40
|
+
people: EntityData[];
|
|
41
|
+
relationships: Relationship[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Estrutura interna hierárquica de uma entidade
|
|
45
|
+
*/
|
|
46
|
+
export interface EntityHierarchy {
|
|
47
|
+
person: EntityData;
|
|
48
|
+
parents: EntityData[];
|
|
49
|
+
mother?: EntityData;
|
|
50
|
+
father?: EntityData;
|
|
51
|
+
children: EntityData[];
|
|
52
|
+
spouse?: EntityData;
|
|
53
|
+
adoptions: EntityData[];
|
|
54
|
+
siblings: EntityData[];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Estado de expansão de um nó
|
|
58
|
+
*/
|
|
59
|
+
export interface NodeExpansionState {
|
|
60
|
+
[nodeId: string]: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Opções do hook useGenealogy
|
|
64
|
+
*/
|
|
65
|
+
export interface UseGenealogyOptions {
|
|
66
|
+
data: GenealogyData;
|
|
67
|
+
initialExpanded?: string[];
|
|
68
|
+
nodeWidth?: number;
|
|
69
|
+
nodeHeight?: number;
|
|
70
|
+
horizontalSpacing?: number;
|
|
71
|
+
verticalSpacing?: number;
|
|
72
|
+
onNodeSelect?: (nodeId: string, entity: EntityData) => void;
|
|
73
|
+
onNodeExpand?: (nodeId: string, expanded: boolean) => void;
|
|
74
|
+
onAddRelation?: (fromId: string, toId: string, type: RelationshipType) => void;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Retorno do hook useGenealogy
|
|
78
|
+
*/
|
|
79
|
+
export interface UseGenealogyReturn {
|
|
80
|
+
nodes: ReactFlowNode[];
|
|
81
|
+
edges: ReactFlowEdge[];
|
|
82
|
+
hierarchy: Map<string, EntityHierarchy>;
|
|
83
|
+
selectedNodeId: string | null;
|
|
84
|
+
expansionState: NodeExpansionState;
|
|
85
|
+
selectNode: (nodeId: string) => void;
|
|
86
|
+
expandNode: (nodeId: string, expanded?: boolean) => void;
|
|
87
|
+
collapseNode: (nodeId: string) => void;
|
|
88
|
+
addRelation: (fromId: string, toId: string, type: RelationshipType) => void;
|
|
89
|
+
getPersonHierarchy: (entityId: string) => EntityHierarchy | undefined;
|
|
90
|
+
getPersonRelations: (entityId: string) => Relationship[];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Hook headless para gerenciar árvores genealógicas
|
|
94
|
+
*/
|
|
95
|
+
export declare function useGenealogy({ data, initialExpanded, nodeWidth, nodeHeight, horizontalSpacing, verticalSpacing, onNodeSelect, onNodeExpand, onAddRelation, }: UseGenealogyOptions): UseGenealogyReturn;
|
|
96
|
+
//# sourceMappingURL=useGenealogy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGenealogy.d.ts","sourceRoot":"","sources":["../../../src/hooks/useGenealogy/useGenealogy.ts"],"names":[],"mappings":"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"}
|