Skip to content

Utils

Dependency-light helpers the UI primitives build on — ref composition, selectable-item collections, and shadcn namespace interop.

Shared, dependency-light utilities the components build on. Each is copyable through dgadd or the shadcn CLI and importable from the package; you own the copied source.

Documented utilities

UtilityKindWhat it does
composeRefsfunctionMerge any number of React refs — callback, object, null, or undefined — into one ref callback, for the React 19 ref-as-prop pattern.
selectable-collectioncollectionDOM-order item registry plus enabled-item filtering and highlighted/selected/first-enabled value resolution for compound selection components.
shadcn NamespaceinteropMap @ui / @diffgazer-keys shadcn registry aliases in components.json so namespaced installs resolve UI and keys items.

Installing

Info:

Before publication: Diffgazer packages are not yet published to npm, so there is no dgadd bin until you install one. Follow the canonical Copy-first mode procedure to build and pack @diffgazer/add, then install that packed tarball in the target app. The target-app install is what puts dgadd on pnpm exec.

composeRefs and selectable-collection install like any other item, into lib/. composeRefs is a single lib/compose-refs.ts; selectable-collection writes three files — lib/selectable-collection.ts, lib/selectable-collection-observer.ts, and lib/selectable-group.ts — and additionally resolves the @diffgazer-keys/focusable registry item.

bash
pnpm exec dgadd add ui/compose-refs

They are also pulled in automatically when you add a component that depends on them — composeRefs ships with select, menu, tabs, radio, checkbox, navigation-list, and command-palette.

Import from the copied source, or from the package in package mode:

tsx
// Copy mode
import { cn } from "@/lib/utils";
import { composeRefs } from "@/lib/compose-refs";

// Package mode
import { cn } from "@diffgazer/ui/lib/utils";
import { composeRefs } from "@diffgazer/ui/lib/compose-refs";

Other registry utilities

The registry ships more registry:lib helpers without standalone pages here. They install the same way (dgadd add ui/<name>) and come along with the components that use them:

  • utilscn() class-name merge (clsx + tailwind-merge), imported by every component.
  • aria, typeahead, search — ARIA and keyboard-interaction helpers shared across form and listbox composites.
  • focus-outline, marker-rail — the keyboard-focus outline and the selected-row left rail as plain class-name constants, so every component draws the same two marks. Importable from the package as @diffgazer/ui/lib/focus-outline and @diffgazer/ui/lib/marker-rail.
  • selectable-variants, segmented-variants, input-variants, stepper-variants — CVA variant definitions that live in the shared registry/lib/ directory. See Variants for which components consume each.
  • sidebar-variants — a registry:ui item, not registry:lib: its CVA definitions are colocated in registry/ui/sidebar/ because only Sidebar uses them.