@@ -3,6 +3,8 @@ import { createEffect, onCleanup, type Accessor } from "solid-js";
33import { useId } from "./useId" ;
44import { useIsMounted } from "./useIsMounted" ;
55
6+ import type { ObserveElement } from "./useDomWidth" ;
7+
68export const useSyncHeight = ( {
79 selector,
810 wrapper,
@@ -24,53 +26,70 @@ export const useSyncHeight = ({
2426 if ( enable ( ) ) {
2527 let clean = ( ) => { } ;
2628
27- const timer = setTimeout ( ( ) => {
28- const container = document . querySelector ( `#diff-root${ id ( ) } ` ) ;
29+ const container = document . querySelector ( `#diff-root${ id ( ) } ` ) ;
2930
30- const elements = Array . from ( container ?. querySelectorAll ( selector ( ) ) || [ ] ) ;
31+ const elements = Array . from ( container ?. querySelectorAll ( selector ( ) ) || [ ] ) ;
3132
32- const wrappers = Array . from ( container ?. querySelectorAll ( wrapper ( ) ) || [ ] ) ;
33+ const wrappers = wrapper ( ) ? Array . from ( container ?. querySelectorAll ( wrapper ( ) ) || [ ] ) : elements ;
3334
34- if ( elements . length === 2 && wrappers . length === 2 ) {
35- const ele1 = elements [ 0 ] as HTMLElement ;
36- const ele2 = elements [ 1 ] as HTMLElement ;
35+ if ( elements . length === 2 && wrappers . length === 2 ) {
36+ const ele1 = elements [ 0 ] as HTMLElement ;
37+ const ele2 = elements [ 1 ] as HTMLElement ;
3738
38- const wrapper1 = wrappers [ 0 ] as HTMLElement ;
39- const wrapper2 = wrappers [ 1 ] as HTMLElement ;
39+ const wrapper1 = wrappers [ 0 ] as HTMLElement ;
40+ const wrapper2 = wrappers [ 1 ] as HTMLElement ;
4041
41- const target = ele1 . getAttribute ( "data-side" ) === side ( ) ? ele1 : ele2 ;
42+ const target = ele1 . getAttribute ( "data-side" ) === side ( ) ? ele1 : ele2 ;
4243
43- const cb = ( ) => {
44- ele1 . style . height = "auto" ;
45- ele2 . style . height = "auto" ;
46- const rect1 = ele1 . getBoundingClientRect ( ) ;
47- const rect2 = ele2 . getBoundingClientRect ( ) ;
48- const maxHeight = Math . max ( rect1 . height , rect2 . height ) ;
49- wrapper1 . style . height = maxHeight + "px" ;
50- wrapper2 . style . height = maxHeight + "px" ;
51- wrapper1 . setAttribute ( "data-sync-height" , String ( maxHeight ) ) ;
52- wrapper2 . setAttribute ( "data-sync-height" , String ( maxHeight ) ) ;
53- } ;
44+ const typedTarget = target as ObserveElement ;
5445
55- cb ( ) ;
46+ const cb = ( ) => {
47+ ele1 . style . height = "auto" ;
48+ ele2 . style . height = "auto" ;
49+ const rect1 = ele1 . getBoundingClientRect ( ) ;
50+ const rect2 = ele2 . getBoundingClientRect ( ) ;
51+ const maxHeight = Math . max ( rect1 . height , rect2 . height ) ;
52+ wrapper1 . style . height = maxHeight + "px" ;
53+ wrapper2 . style . height = maxHeight + "px" ;
54+ wrapper1 . setAttribute ( "data-sync-height" , String ( maxHeight ) ) ;
55+ wrapper2 . setAttribute ( "data-sync-height" , String ( maxHeight ) ) ;
56+ } ;
5657
57- const observer = new ResizeObserver ( cb ) ;
58+ cb ( ) ;
5859
59- observer . observe ( target ) ;
60+ const cleanCb = ( ) => {
61+ typedTarget . __observeCallback ?. delete ( cb ) ;
62+ if ( typedTarget . __observeCallback ?. size === 0 ) {
63+ typedTarget . __observeInstance ?. disconnect ( ) ;
64+ target . removeAttribute ( "data-observe" ) ;
65+ delete typedTarget . __observeCallback ;
66+ delete typedTarget . __observeInstance ;
67+ }
68+ } ;
6069
61- target . setAttribute ( "data-observe" , "height" ) ;
70+ if ( typedTarget . __observeCallback ) {
71+ typedTarget . __observeCallback . add ( cb ) ;
6272
63- clean = ( ) => {
64- observer . disconnect ( ) ;
65- target ?. removeAttribute ( "data-observe" ) ;
66- } ;
73+ clean = cleanCb ;
74+ return ;
6775 }
68- } ) ;
6976
70- onCleanup ( ( ) => {
71- clean ( ) ;
72- clearTimeout ( timer ) ;
73- } ) ;
77+ typedTarget . __observeCallback = new Set ( ) ;
78+
79+ typedTarget . __observeCallback . add ( cb ) ;
80+
81+ const observer = new ResizeObserver ( ( ) => typedTarget . __observeCallback ?. forEach ( ( cb ) => cb ( ) ) ) ;
82+
83+ typedTarget . __observeInstance = observer ;
84+
85+ observer . observe ( target ) ;
86+
87+ target . setAttribute ( "data-observe" , "height" ) ;
88+
89+ clean = cleanCb ;
90+ }
91+
92+ onCleanup ( ( ) => clean ( ) ) ;
7493 }
7594 } ;
7695
0 commit comments