Masonry: use MutationObserver instead
- originally tricks with the reactive system
This commit is contained in:
		
							parent
							
								
									18fa2810c4
								
							
						
					
					
						commit
						487de9237b
					
				
					 1 changed files with 16 additions and 19 deletions
				
			
		| 
						 | 
				
			
			@ -5,10 +5,8 @@ import {
 | 
			
		|||
  type Ref,
 | 
			
		||||
  createRenderEffect,
 | 
			
		||||
  onCleanup,
 | 
			
		||||
  children,
 | 
			
		||||
  createEffect,
 | 
			
		||||
  createSignal,
 | 
			
		||||
  onMount,
 | 
			
		||||
} from "solid-js";
 | 
			
		||||
import { Dynamic, type DynamicProps } from "solid-js/web";
 | 
			
		||||
import MasonryLayout from "masonry-layout";
 | 
			
		||||
| 
						 | 
				
			
			@ -20,7 +18,6 @@ type MasonryContainer =
 | 
			
		|||
  | Component<{
 | 
			
		||||
      ref?: Ref<Element>;
 | 
			
		||||
      class?: string;
 | 
			
		||||
      children?: JSX.Element;
 | 
			
		||||
    }>;
 | 
			
		||||
 | 
			
		||||
type ElementOf<T extends MasonryContainer> =
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +34,10 @@ function forwardRef<T>(value: T, ref?: Ref<T>) {
 | 
			
		|||
  (ref as (value: T) => void)(value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function createMasonry(element: Element, options: () => MasonryLayout.Options) {
 | 
			
		||||
function createCompatMasonry(
 | 
			
		||||
  element: Element,
 | 
			
		||||
  options: () => MasonryLayout.Options,
 | 
			
		||||
) {
 | 
			
		||||
  const layout = new MasonryLayout(element, {
 | 
			
		||||
    initLayout: false,
 | 
			
		||||
  });
 | 
			
		||||
| 
						 | 
				
			
			@ -46,11 +46,21 @@ function createMasonry(element: Element, options: () => MasonryLayout.Options) {
 | 
			
		|||
 | 
			
		||||
  const size = createElementSize(element);
 | 
			
		||||
 | 
			
		||||
  const treeMutObx = new MutationObserver(() => {
 | 
			
		||||
    layout.reloadItems?.();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  onCleanup(() => treeMutObx.disconnect());
 | 
			
		||||
 | 
			
		||||
  createRenderEffect(() => {
 | 
			
		||||
    const opts = options();
 | 
			
		||||
    layout.option?.(opts);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  createRenderEffect(() => {
 | 
			
		||||
    treeMutObx.observe(element, { childList: true });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  createRenderEffect(() => {
 | 
			
		||||
    const width = size.width; // only tracking width
 | 
			
		||||
    layout.layout?.();
 | 
			
		||||
| 
						 | 
				
			
			@ -61,8 +71,6 @@ function createMasonry(element: Element, options: () => MasonryLayout.Options) {
 | 
			
		|||
      layout.layout?.();
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return layout;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const supportsCSSMasonryLayout = /* @__PURE__ */ CSS.supports(
 | 
			
		||||
| 
						 | 
				
			
			@ -85,9 +93,7 @@ if (import.meta.env.VITE_PLATFROM_MASONRY_ALWAYS_COMPAT) {
 | 
			
		|||
function MasonryCompat<T extends MasonryContainer>(
 | 
			
		||||
  oprops: DynamicProps<T> & { class?: string },
 | 
			
		||||
) {
 | 
			
		||||
  const [props, rest] = splitProps(oprops, ["ref", "children", "class"]);
 | 
			
		||||
 | 
			
		||||
  const childrenComponents = children(() => props.children);
 | 
			
		||||
  const [props, rest] = splitProps(oprops, ["ref", "class"]);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Dynamic
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +102,7 @@ function MasonryCompat<T extends MasonryContainer>(
 | 
			
		|||
 | 
			
		||||
        const [columnGap, setColumnGap] = createSignal<number>();
 | 
			
		||||
 | 
			
		||||
        const layout = createMasonry(element, () => {
 | 
			
		||||
        createCompatMasonry(element, () => {
 | 
			
		||||
          return {
 | 
			
		||||
            gutter: columnGap(),
 | 
			
		||||
          };
 | 
			
		||||
| 
						 | 
				
			
			@ -115,18 +121,9 @@ function MasonryCompat<T extends MasonryContainer>(
 | 
			
		|||
            setColumnGap(Number(colGap.slice(0, colGap.length - 2)));
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        createRenderEffect(() => {
 | 
			
		||||
          childrenComponents(); // just tracks
 | 
			
		||||
          setTimeout(() => {
 | 
			
		||||
            layout.reloadItems?.();
 | 
			
		||||
            layout.layout?.();
 | 
			
		||||
          }, 0);
 | 
			
		||||
        });
 | 
			
		||||
      }}
 | 
			
		||||
      class={`Masonry CompatMasonry ${props.class || ""}`}
 | 
			
		||||
      {...rest}
 | 
			
		||||
      children={childrenComponents}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue