npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ariakit/solid-utils

v0.1.7

Published

Ariakit Solid utilities

Readme

@ariakit/solid-utils

Important: This package is an internal dependency of Ariakit and does not follow semantic versioning, meaning breaking changes may occur in patch and minor versions.

Shared Solid utilities used by Ariakit Solid packages.

Contents

Installation

npm i @ariakit/solid-utils

Usage

Import helpers from the package root:

import { mergeProps } from "@ariakit/solid-utils";

This package is ESM-only and exposes a single public entrypoint.

API reference

General utilities

Helpers for ids and tag names.

createId

function createId(
  defaultId?: MaybeAccessor<string | undefined>,
): Accessor<string>;

Generates a unique ID.

extractTagName

function extractTagName(
  element?: MaybeAccessor<HTMLElement | undefined>,
  fallback?: ValidComponent,
): () => any;

Returns the tag name by parsing an element.

Example:

function Component(props) {
  const [ref, setRef] = createSignal();
  const tagName = extractTagName(ref, "button"); // () => "div"
  return <div ref={setRef} {...props} />;
}

Reactivity utilities

Reactivity helpers for accessors, signals, props, and refs.

stableAccessor

function stableAccessor<T, U>(value: T, callback: (value: T) => U): () => U;

Creates a stable accessor. Useful when creating derived accessors that depend on a mutable variable that may change later.

Example:

let value = 0;
const accessor = stableAccessor(value, (v) => v + 1);
value = 100;
accessor(); // 1

ExtractPropsWithDefaultsExtractedProps

type NullablyRequired<T> = { [P in keyof T & keyof any]: T[P] };

type ExtractPropsWithDefaultsExtractedProps<
  P,
  D extends Partial<R>,
  R = NullablyRequired<P>,
> = {
  -readonly [K in keyof R as Extract<K, keyof D>]: D[K] extends undefined
    ? R[K]
    : Exclude<R[K], undefined>;
};

ExtractPropsWithDefaultsRestProps

type ExtractPropsWithDefaultsRestProps<P, D extends Partial<P>> = Omit<
  P,
  keyof D
>;

ExtractPropsWithDefaultsReturn

type ExtractPropsWithDefaultsReturn<P, D extends Partial<P>> = [
  ExtractPropsWithDefaultsExtractedProps<P, D>,
  ExtractPropsWithDefaultsRestProps<P, D>,
];

extractPropsWithDefaults

function extractPropsWithDefaults<
  P extends AnyObject,
  const D extends Partial<P>,
>(props: P, defaults: D): ExtractPropsWithDefaultsReturn<P, D>;

Extracts props from a props object and applies defaults to them. The return value is a tuple of the extracted props and the rest of the props.

To extract a prop without a default, set it to undefined.

Example:

const [extractedProps, restProps] = extractPropsWithDefaults(props, {
  orientation: "horizontal",
});

RefStore

type RefStore<T> = {
  /**
   * The current value of the ref. It is a non-reactive getter, wrapped with
   * the `untrack` function.
   *
   * **Important note**: since this is a getter, TypeScript might reflect the
   * wrong type in some cases. For example:
   *
   * ```ts
   * const ref = createRef<number>(); // ref.current type: number | undefined
   * ref.set(1);
   * console.log(ref.current); // 1
   * if (ref.current) {
   *   // ref.current type: number (narrowed by the if statement)
   // ... 18 more lines
   * by default.
   */
  reset: () => void;
};

A ref object that contains the value getter (value) and setter (set) as properties for convenience. It also has a reset method that can be used to set the value to the initial value that was passed, which is undefined by default. The current getter can be used to obtain the value without tracking it reactively.

Created by the createRef function.

Example:

const ref = createRef();
createEffect(() => {
  console.log(ref.value);
});
ref.set(buttonElement);
ref.reset();

createRef

function createRef<T>(): RefStore<T | undefined>;
function createRef<T>(initialValue: T): RefStore<T>;

Creates a ref object that contains the value getter (value) and setter (set) as properties for convenience. It also has a reset method that can be used to set the value to the initial value that was passed, which is undefined by default. The current getter can be used to obtain the value without tracking it reactively.

Example:

const ref = createRef();
createEffect(() => {
  console.log(ref.value);
});
<button ref={ref.set}>Button</button>;

mergeProps

function mergeProps<T extends JSX.HTMLAttributes<any>>(
  base: T,
  overrides: T,
  skipProps?: Array<keyof T>,
): T;

Merges two sets of props.

System utilities

Helpers for creating and composing Ariakit Solid components.

createInstance

function createInstance(
  Component: ValidComponent,
  props: Props<ValidComponent, Options>,
): import("solid-js").JSX.Element;

Creates a Solid component instance that supports the render and wrapInstance props.

wrapInstance

function wrapInstance<P, Q = P & { wrapInstance: WrapInstance }>(
  props: P & { wrapInstance?: WrapInstance },
  element: WrapInstanceValue,
): Q;

Returns props with an additional wrapInstance prop.

createHook

function createHook<
  T extends ValidComponent,
  P extends AnyObject = EmptyObject,
>(useProps: (props: Props<T, P>) => HTMLProps<T, P>): Hook<T, P>;

Creates a component hook that accepts props and returns props so they can be passed to a Solid component.

withOptions

function withOptions<
  T extends ValidComponent,
  P extends AnyObject,
  const D extends Partial<ComputedP>,
  ComputedP extends Props<T, P>,
>(
  defaults: D,
  useProps: (
    props: ExtractPropsWithDefaultsRestProps<ComputedP, D>,
    options: ExtractPropsWithDefaultsExtractedProps<ComputedP, D>,
  ) => HTMLProps<T, P>,
): (props: ComputedP) => HTMLProps<T, P>;

Splits "option props" from the rest in a component hook. Must be called inside createHook.

The first argument is an object that defines the props that will be extracted, with their default values. To extract a prop without a default, set it to undefined.

The hook function must be passed as the second argument, and it will receive the rest of the props and the extracted options.

Example:

export const useMyComponent = createHook<TagName, MyComponentOptions>(
  withOptions(
    { orientation: "horizontal" },
    function useMyComponent(props, options) {
      // ...
    },
  ),
);

Type utilities

Shared types for Ariakit Solid components.

RenderValue

type RenderValue<P extends AnyObject> = JSX.Element | Component<P>;

A value that can be rendered when passed to the render prop or the wrapInstance prop.

WrapInstanceValue

type WrapInstanceValue = RenderValue<ParentProps>;

A value passed to the wrapInstance prop.

WrapInstance

type WrapInstance = Array<WrapInstanceValue>;

The wrapInstance prop.

Options

interface Options {
  wrapInstance?: WrapInstance;
  /**
   * Allows the component to be rendered as a different HTML element or Solid
   * component. The value can be an `As` component instance or a function that
   * takes in the original component props and gives back a Solid component
   * instance with the props merged.
   *
   * Check out the [Composition](https://solid.ariakit.com/guide/composition) guide
   * for more details.
   */
  render?: RenderValue<JSX.HTMLAttributes<any>>;
}

Custom props including the render prop.

HTMLProps

type HTMLProps<
  T extends ValidComponent,
  P extends AnyObject = EmptyObject,
> = Omit<ComponentProps<T>, keyof P> & {
  [index: `data-${string}`]: unknown;
};

HTML props based on the element type, excluding custom props.

Example:

type ButtonHTMLProps = HTMLProps<"button", { custom?: boolean }>;

Props

type Props<T extends ValidComponent, P extends AnyObject = EmptyObject> = P &
  HTMLProps<T, P>;

Props based on the element type, including custom props.

Hook

type Hook<T extends ValidComponent, P extends AnyObject = EmptyObject> = <
  ElementType extends ValidComponent = T,
>(
  props?: Props<ElementType, P>,
) => HTMLProps<ElementType, P>;

A component hook that supports the render prop and returns HTML props based on the element type.

Example:

type UseButton = Hook<"button", { custom?: boolean }>;