UNPKG

@solid-primitives/refs

Version:

Library of primitives, components and directives for SolidJS that help managing references to JSX elements.

152 lines (151 loc) 6.18 kB
import { Accessor, JSX } from "solid-js"; export type { ResolvedChildren, ResolvedJSXElement } from "solid-js/types/reactive/signal.js"; /** * Type for the `ref` prop */ export type Ref<T> = T | ((el: T) => void) | undefined; /** * Component properties with types for `ref` prop * ```ts * { * ref?: T | ((el: T) => void); * } * ``` */ export interface RefProps<T> { ref?: Ref<T>; } /** * Utility for chaining multiple `ref` assignments with `props.ref` forwarding. * @param refs list of ref setters. Can be a `props.ref` prop for ref forwarding or a setter to a local variable (`el => ref = el`). * @example * ```tsx * interface ButtonProps { * ref?: Ref<HTMLButtonElement> * } * function Button (props: ButtonProps) { * let ref: HTMLButtonElement | undefined * onMount(() => { * // use the local ref * }) * return <button ref={mergeRefs(props.ref, el => ref = el)} /> * } * * // in consumer's component: * let ref: HTMLButtonElement | undefined * <Button ref={ref} /> * ``` */ export declare function mergeRefs<T>(...refs: Ref<T>[]): (el: T) => void; /** * Default predicate used in `resolveElements()` and `resolveFirst()` to filter Elements. * * On the client it uses `instanceof Element` check, on the server it checks for the object with `t` property. (generated by compiling JSX) */ export declare const defaultElementPredicate: (item: JSX.Element | Element) => item is Element; /** * Utility for resolving recursively nested JSX children to a single element or an array of elements using a predicate. * * It does **not** create a computation - should be wrapped in one to repeat the resolution on changes. * * @param value JSX children * @param predicate predicate to filter elements * @returns single element or an array of elements or `null` if no elements were found */ export declare function getResolvedElements<T extends object>(value: JSX.Element, predicate: (item: JSX.Element | T) => item is T): T | T[] | null; export type ResolveChildrenReturn<T extends object> = Accessor<T | T[] | null> & { toArray: () => T[]; }; /** * Utility for resolving recursively nested JSX children to a single element or an array of elements using a predicate. * * @param fn Accessor of JSX children * @param predicate predicate to filter elements. * ```ts * // default predicate * (item: JSX.Element): item is Element => item instanceof Element * ``` * @param serverPredicate predicate to filter elements on server. {@link defaultElementPredicate} * @returns Signal of a single element or an array of elements or `null` if no elements were found * ```ts * Accessor<T | T[] | null> & { toArray: () => T[] } * ``` * @example * ```tsx * function Button(props: ParentProps) { * const children = resolveElements(() => props.children) * return <For each={children.toArray()}> * {child => <div>{child.localName}: {child}</div>} * </For> * } * ``` */ export declare function resolveElements(fn: Accessor<JSX.Element>): ResolveChildrenReturn<Element>; export declare function resolveElements<T extends object & JSX.Element>(fn: Accessor<JSX.Element>, predicate: (item: JSX.Element) => item is T, serverPredicate?: (item: JSX.Element) => item is T): ResolveChildrenReturn<T>; export declare function resolveElements<T extends object>(fn: Accessor<JSX.Element>, predicate: (item: JSX.Element | T) => item is T, serverPredicate?: (item: JSX.Element | T) => item is T): ResolveChildrenReturn<T>; /** * Utility for resolving recursively nested JSX children in search of the first element that matches a predicate. * * It does **not** create a computation - should be wrapped in one to repeat the resolution on changes. * * @param value JSX children * @param predicate predicate to filter elements * @returns single found element or `null` if no elements were found */ export declare function getFirstChild<T extends object>(value: JSX.Element, predicate: (item: JSX.Element | T) => item is T): T | null; /** * Utility for resolving recursively nested JSX children in search of the first element that matches a predicate. * @param fn Accessor of JSX children * @param predicate predicate to filter elements. * ```ts * // default predicate * (item: JSX.Element): item is Element => item instanceof Element * ``` * @param serverPredicate predicate to filter elements on server. {@link defaultElementPredicate} * @returns Signal of a single found element or `null` if no elements were found * ```ts * Accessor<T | null> * ``` * @example * ```tsx * function Button(props: ParentProps) { * const child = resolveFirst(() => props.children) * return <div>{child()?.localName}: {child()}</div> * } * ``` */ export declare function resolveFirst(fn: Accessor<JSX.Element>): Accessor<Element | null>; export declare function resolveFirst<T extends object & JSX.Element>(fn: Accessor<JSX.Element>, predicate: (item: JSX.Element) => item is T, serverPredicate?: (item: JSX.Element) => item is T): Accessor<T | null>; export declare function resolveFirst<T extends object>(fn: Accessor<JSX.Element>, predicate: (item: JSX.Element | T) => item is T, serverPredicate?: (item: JSX.Element | T) => item is T): Accessor<T | null>; /** * Get up-to-date references of the multiple children elements. * @param ref Getter of current array of elements * @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/refs#Refs * @example * ```tsx * const [refs, setRefs] = createSignal<Element[]>([]); * <Refs ref={setRefs}> * {props.children} * </Refs> * ``` */ export declare function Refs(props: { ref: Ref<Element[]>; children: JSX.Element; }): JSX.Element; /** * Get up-to-date reference to a single child element. * @param ref Getter of current element *(or `undefined` if not mounted)* * @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/refs#Ref * @example * ```tsx * const [ref, setRef] = createSignal<Element | undefined>(); * <Ref ref={setRef}> * {props.children} * </Ref> * ``` */ export declare function Ref(props: { ref: Ref<Element | undefined>; children: JSX.Element; }): JSX.Element;