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…
Reference in a new issue