@solid-primitives/refs

Collection of primitives, components and directives that help managing references to JSX elements, keeping track of mounted/unmounted elements.
Primitives:
mergeRefs
- Utility for using jsx refs both for local variables and providing it to the props.ref
for component consumers.
elements
- Reactive signal that filters out non-element items from a signal array. (Can be used with children
primitive)
refs
- Get signal references to Elements of the reactive input. Which were added, which were removed. (Can be used with children
primitive)
mapRemoved
- Similar to Solid's mapArray
, but you map the elements that were removed from source array. Leting you keep them for longer.
resolveElements
— Will resolve value to a flat list of HTML elements or a single element or null
.
Directive:
unmount
- A directive that calls handler when the element get's unmounted from DOM.
Components:
<Children>
- Solid's children
helper in component form. Access it's children elements by get
property.
<Refs>
- Get up-to-date references of the multiple children elements.
<Ref>
- Get up-to-date reference to a single child element.
Types:
RefProps
- Component properties with types for ref
ResolvedChildren
- Type of resolved JSX elements provided by Solid's children
helper.
Vanilla helpers:
getChangedItems
- Tells you which elements got added to the array, and which got removed
getAddedItems
- Tells you elements got added to the array
getRemovedItems
- Tells you which elements got removed from the array
Installation
npm install @solid-primitives/refs
yarn add @solid-primitives/refs
Primitives
mergeRefs
Utility for using jsx refs both for local variables and providing it to the props.ref
for component consumers.
How to use it
import { mergeRefs } from "@solid-primitives/refs";
interface ButtonProps {
ref?: HTMLButtonElement | ((el: HTMLButtonElement) => void);
}
const Button = (props: ButtonProps) => {
let ref!: HTMLButtonElement;
onMount(() => {
});
return <button ref={mergeRefs(el => (ref = el), props.ref)} />;
};
let ref!: HTMLButtonElement;
<Button ref={ref} />;
elements
Reactive signal that filters out non-element items from a signal array. (Can be used with children
primitive)
How to use it
import { elements } from "@solid-primitives/refs";
const resolved = children(() => props.children);
const els = elements(resolved);
els();
const divs = elements(resolved, HTMLDivElement);
divs();
refs
Get signal references to Elements of the reactive input. Which were added, which were removed. (Can be used with children
primitive)
Used internally by <Refs>
component.
How to use it
import { refs } from "@solid-primitives/refs";
const resolved = children(() => props.children);
const [els, added, removed] = refs(resolved);
els();
added();
removed();
const [els, added, removed] = refs(resolved, HTMLDivElement);
els();
added();
removed();
mapRemoved
Reactively map removed items from a reactive signal array. If the mapping function return an element signal, this element will be placed in the array returned from primitive.
How to use it
import { mapRemoved } from "@solid-primitives/refs";
const MyComp = props => {
const resolved = children(() => props.children);
const combined = mapRemoved(resolved, (ref, index) => {
const [el, setEl] = createSignal(ref);
ref.style.filter = "grayscale(100%)";
createEffect(() => {
index();
});
const remove = () => {
setEl(undefined);
};
return el;
});
return combined;
};
resolveElements
Similarly to children()
helper from solid-js
will resolve provided value to a flat list of HTML elements or a single element or null
. But doesn't create a computation.
import { resolveElements } from "@solid-primitives/refs";
const MyComponent: ParentComponent = props => {
createEffect(() => {
const resolved = resolveElements(props.children);
resolved;
});
return "Don't access props.children here again — it'll create new dom nodes";
};
Directive
unmount
A directive that calls handler when the element get's unmounted from DOM.
Import
import { unmount } from "@solid-primitives/refs";
unmount;
How to use it
const [ref, setRef] = createSignal<Element | undefined>();
<div ref={el => setRef(el)} use:unmount={() => setRef(undefined)}>
Hello
</div>;
Components
<Children>
Solid's children
helper in component form. Access it's children elements by get
property.
How to use it
import {Children, ResolvedJSXElement} from "@solid-primitives/refs"
const [children, setChildren] = createSignal<ResolvedJSXElement>([])
<Children get={setChildren}>
<div></div>
...
</Children>
<Ref>
Get up-to-date reference to a single child element.
Import
import { Ref } from "@solid-primitives/refs";
How to use it
<Ref>
accepts these properties:
ref
- Getter of current element (or undefined
if not mounted)
onMount
- handle the child element getting mounted to the dom
onUnmount
- handle the child element getting unmounted from the dom
const [ref, setRef] = createSignal<Element | undefined>();
<Ref
ref={setRef}
onMount={el => console.log("Mounted", el)}
onUnmount={el => console.log("Unmounted", el)}
>
<Show when={show()}>
<div>Hello</div>
</Show>
</Ref>;
Providing generic Element type
<Ref<HTMLDivElement>
ref={el => {...}}
onMount={el => {...}}
onUnmount={el => {...}}
>
<div>Hello</div>
</Ref>
<Refs>
Get up-to-date references of the multiple children elements.
Import
import { Refs } from "@solid-primitives/refs";
How to use it
<Refs>
accepts these properties:
refs
- Getter of current array of elements
added
- Getter of added elements since the last change
removed
- Getter of removed elements since the last change
onChange
- handle children changes
const [refs, setRefs] = createSignal<Element[]>([]);
<Refs
refs={setRefs}
added={els => console.log("Added elements", els)}
removed={els => console.log("Removed elements", els)}
onChange={e => console.log(e)}
>
<For each={my_list()}>{item => <div>{item}</div>}</For>
<Show when={show()}>
<div>Hello</div>
</Show>
</Refs>;
Providing generic Element type
<Refs<HTMLDivElement>
refs={els => {}}
added={els => {}}
removed={els => {}}
onChange={e => {}}
>
<div>Hello</div>
</Refs>
Demo
https://stackblitz.com/edit/solid-vite-unocss-bkbgap?file=index.tsx
(run npm start
in the terminal)
Types
RefProps
Component properties with types for ref
interface RefProps<T extends Element> {
ref?: T | ((el: T) => void);
}
ResolvedChildren
Type of resolved JSX elements provided by Solid's children
helper.
type ResolvedChildren = ResolvedJSXElement | ResolvedJSXElement[];
Changelog
See CHANGELOG.md