UNPKG

rvx

Version:

A signal based rendering library

77 lines (71 loc) 1.79 kB
import type { Component, Content } from "../core/types.js"; import { NEXT_ID } from "./internals/next-unique-id.js"; /** * Allocate an ID that is unique in the current thread. * * @returns The unique id in the form `rvx_123`. */ export function uniqueId(): string { const next = NEXT_ID.value; if (typeof next === "number" && next >= Number.MAX_SAFE_INTEGER) { NEXT_ID.value = BigInt(NEXT_ID.value) + 1n; } else { NEXT_ID.value++; } return "rvx_" + String(next); } /** * A component that provides a unique id in the form `rvx_123` to it's children. * * See {@link UseUniqueId `<UseUniqueId>`} when using JSX. * * @example * ```tsx * import { useUniqueId, e } from "rvx"; * * useUniqueId(id => [ * e("label").set("for", id).append("Text"), * e("input").set("type", "text").set("id", id), * ]) * ``` */ export function useUniqueId<T = Content>(component: Component<string, T>): T { return component(uniqueId()); } /** * A component that provides a unique id in the form `rvx_123` to it's children. * * See {@link useUniqueId} when not using JSX. * * @example * ```tsx * import { UseUniqueId } from "rvx"; * * <UseUniqueId> * {id => <> * <label for={id}>Text</label> * <input type="text" id={id} /> * </>} * </UseUniqueId> * ``` */ export function UseUniqueId<T = Content>(props: { children: Component<string, T>; }): T { return props.children(uniqueId()); } const IDS = new WeakMap(); /** * Get a {@link uniqueId unique id} for the specified object. * * @param target The target object. * @returns The id. This is always the same id for the same object. */ export function uniqueIdFor(target: object): string { let id = IDS.get(target); if (id === undefined) { id = uniqueId(); IDS.set(target, id); } return id; }