UIInternal UI

Utilities

16 lib helpers, registries and tokens — the non-visual half of the kit, shown with live values.

field-kinds

@randall-enterprises/ui/components/data-view/field-kinds/index

One registry entry per value type, behind FieldValue and CellEditor. A kind owns its read-only Display and, when the type can be edited inline, its Editor — so adding a property type means adding a module, not a case to two switches.

Props (1)

type *string

returns FieldKind | undefined

text · editableselect · editableperson · editabledate · editablenumber · editableboolean · editablefile · read-onlyrelation · editableurl · read-onlyemail · read-onlyphone · read-only
type FieldKind<K extends ValueFieldType = ValueFieldType> = {
  kind: K;
  Display: (props: FieldDisplayProps) => ReactNode;
  Editor?: (props: FieldEditorProps) => ReactNode;
};

fieldKind("date")?.Editor   // undefined for a kind with no inline editor

bulk-actions

@randall-enterprises/ui/components/data-view/bulk-actions/index

The selection bar's overflow menu, declared once. Each action renders its own menu entry through Run — so an action that needs a sub-page or a count badge owns that markup — and asks the BulkActionContext whether the page gave it anything to do.

Edit propertyCopy linksDuplicateDelete · danger
type BulkAction<T> = {
  id: string;
  label: string;
  icon: ComponentType<{ className?: string; weight?: "bold" }>;
  group?: "danger";
  available: (ctx: BulkActionContext<T>) => boolean;
  Run: (ctx: BulkActionContext<T>) => ReactNode;
};

kanban geometry

@randall-enterprises/ui/components/data-view/kanban/lane-width

The board's pure parts: laneWidthPx fits the lanes to the board without ever going under the minimum, and dragKind reads a dnd-kit id back to what was picked up — a card, a lane header, a group or a sub-group band.

Props (5)

boardWidth *number
cardSize *CardSize
laneCount *number
MIN_LANE_WIDTH_PX176The narrowest a lane is ever allowed to get.
LANE_WIDTH_PXRecord<Exclude<CardSize, "fit">, number>Fixed lane widths, shared by the header rail and the lanes under it. The two

returns number

fit · 6 lanes · board 640px → 176pxfit · 6 lanes · board 1280px → 203pxfit · 6 lanes · board 1920px → 310pxfloor 176pxfixed 176/224/288px
dragKind("lane:todo") → lanedragKind("group:todo") → groupdragKind("band:q3") → banddragKind("row_42") → card

utils (cn)

@randall-enterprises/ui/lib/utils

clsx + tailwind-merge. Every conditional class in the kit flows through cn.

Props (1)

...inputsClassValue[]

cn("px-2", "px-4") → "px-4" (tailwind-merge keeps the winner)

format

@randall-enterprises/ui/lib/format

Money (cents in) and short dates (ISO in) for invoices and plans.

Props (3)

amountCents *number
currency *string
iso *string

returns string

$2,500.00$1,500.00Sep 20

friendly-error

@randall-enterprises/ui/lib/friendly-error

Maps operator/API failures to one safe line. Backs ErrorState. Promoted from the console.

Props (2)

error *unknown
surface *stringHuman name of the page/resource ("Activity", "Tickets", …)

returns FriendlyError

describeFriendlyError(E('relation "tickets" does not exist'), "Tickets").message → "Tickets is temporarily unavailable"

color-math

@randall-enterprises/ui/lib/color-math

CSS color parsing, luminance, and contrast ratios. Backs ColorContrast.

Props (2)

a *string
b *string

returns number | null

contrastRatio("#1a1914", "#fcfcf9") → 17.124776802287585

motion

@randall-enterprises/ui/lib/motion

Shared motion presets — one easing vocabulary for every animated component.

Props (4)

LIFT{ type: "spring", stiffness: 380, damping: 26, mass: 0.7, } as const
SETTLE{ type: "spring", stiffness: 260, damping: 34, mass: 0.8, } as const
CROSSFADE{ type: "spring", stiffness: 260, damping: 34, mass: 0.8, } as constSkeleton ↔ content morph
STILL{ duration: 0 } as const

LIFT

{"type":"spring","stiffness":380,"damping":26,"mass":0.7}

SETTLE

{"type":"spring","stiffness":260,"damping":34,"mass":0.8}

CROSSFADE

{"type":"spring","stiffness":260,"damping":34,"mass":0.8}

STILL

{"duration":0}

themes

@randall-enterprises/ui/lib/themes

Theme registry, init script, and document appliers. Built-ins below; the full registry is in code.

Props (2)

BUILTIN_THEME_IDS["light", "dark", "system"] as const
THEME_DEFINITIONSThemeDefinition[]
lightdarksystem3 definitions in registry

overlay-sheet

@randall-enterprises/ui/lib/overlay-sheet

The shared layer table for popups that present as bottom sheets on touch.

Props (3)

OVERLAY_SHEET_POSITIONER_CLASSstringClass for a positioner we own. Radix's positioner is reached with `:has()`
OVERLAY_SHEET_BACKDROP_CLASSstringClass for the Combobox's own dismiss layer, styled in `global.css`.
OVERLAY_SHEET_CONTENT_CLASSstringThe sheet face: full width at the bottom edge, square bottom corners, and a
ui-overlay-sheet-positionerui-overlay-sheet-backdroprelative w-full max-w-none min-w-0 max-h-[70svh] rounded-t-xl rounded-b-none border-x-0 border-b-0 pt-3 pb-[calc(var(--safe-bottom)+--spacing(4))] before:pointer-events-none before:absolute before:inset-x-0 before:top-1.5 before:z-10 before:mx-auto before:h-1.5 before:w-12 before:rounded-full before:bg-border before:content-['']

keep-portaled-combobox

@randall-enterprises/ui/lib/keep-portaled-combobox

Escape/outside-press guards that keep portaled comboboxes inside dialogs.

Props (3)

preventDefault *() => void
target *EventTarget | null
detail{ originalEvent?: Event }

Guards used by DialogForm + Combobox. Behavior demo lives on those pages.

useRestoreFocusOnClose

@randall-enterprises/ui/lib/use-restore-focus-on-close

Focus restoration for overlays. Live demo on the Hooks page.

Props (1)

mountSignal *unknown

See Hooks → useRestoreFocusOnClose for the live demo.

tokens/palette

@randall-enterprises/ui/tokens/palette

Raw palette values for JS consumers (email can't read CSS vars). Mirror changes in global.css.

Props (2)

palette{ border: semantic.light.border, bg: semantic.light.background, card00: semantic.light.card, card01: semantic.light.muted, card02: semantic.light.secondary, car
paletteDark{ border: semantic.dark.border, bg: semantic.dark.background, card00: semantic.dark.card, card01: semantic.dark.muted, card02: semantic.dark.secondary, card03:

light

dark