This component no longer exists. It was in ericts-ui’s manifest when we first indexed it and is not there now — the registry served its inventory on 2026-08-15 and this item was not on it. The install command below will fail. It is kept here because a tutorial somewhere still tells people to run it.
Expanding Slider
ericts-ui/expanding-sliderRemovedComponent
A composable icon button that grows into a wider button on hover, focus, or drag, revealing a draggable track inside the same surface.
Live preview
live · rendered by the registry
Rendered by ericts-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.ericts.com/r/expanding-slider.jsonSource
1"use client";23import * as React from "react";45import { cn } from "@/lib/utils";67// The surface is one pill: collapsed it is an icon button, expanded it is a8// wider button that holds the track. Pill radii nest cleanly, so the trigger9// fills the surface's content box instead of carrying its own box model.10//11// The glyph, rail, and handle keep the YouTube player's volume control sizing;12// the box around them is tighter and the track is longer. The rim alone no13// longer clears the glyph, so the track carries a small leading inset to hold14// YouTube's 8px gap. The tail is wider than the lead only because our surface15// ends in a rounded cap that a player bar does not have.16const SURFACE_HEIGHT = 36;17const SURFACE_BORDER = 1;18const TRIGGER_SIZE = SURFACE_HEIGHT - SURFACE_BORDER * 2;19const ICON_SIZE = 24;20const DEFAULT_TRACK_WIDTH = 72;21const RAIL_HEIGHT = 3;22const THUMB_SIZE = 12;23const TRACK_INSET = 4;24const TRACK_END_INSET = 12;25const PAGE_STEP_MULTIPLIER = 10;26// Leaving the surface should not snap it shut: a grace period forgives a27// pointer that clips the rounded cap on its way to the thumb. 300ms is the28// hover-intent convention (Radix's close delay) and keeps the whole exit —29// grace plus the 200ms collapse — inside half a second, so a control this30// frequently used never reads as stuck open.31const DEFAULT_COLLAPSE_DELAY = 300;3233type ExpandingSliderContextValue = {34 value: number;35 min: number;36 max: number;37 step: number;38 /** Position of the value in [0, 1]. */39 ratio: number;40 disabled: boolean;41 expanded: boolean;42 dragging: boolean;43 label: string;44 valueText?: string;45 trackWidth: number;46 /** Attached by the rail; every measurement is taken from it. */47 railRef: React.RefObject<HTMLDivElement | null>;48 commitValue: (next: number) => void;49 valueFromPointer: (clientX: number) => number | undefined;50 stepBy: (steps: number) => void;51 setDragging: (dragging: boolean) => void;52};5354const ExpandingSliderContext =55 React.createContext<ExpandingSliderContextValue | null>(null);5657function useExpandingSliderContext(component: string) {58 const context = React.useContext(ExpandingSliderContext);5960 if (!context) {61 throw new Error(`${component} must be rendered inside <ExpandingSlider>.`);62 }6364 return context;65}6667export type ExpandingSliderProps = Omit<68 React.ComponentProps<"div">,69 "defaultValue" | "onChange"70> & {71 /** Controlled value. */72 value?: number;73 /** Initial value for uncontrolled usage. */74// … truncated
Files it writes
More from ericts-ui
All 43 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Adaptive Draweradaptive-drawer | ericts-ui | Components | Free | 2 deps | |
| Adaptive Switchadaptive-switch | ericts-ui | Components | Free | 2 deps | |
| Check Markcheck-mark | ericts-ui | Components | Free | no deps · 2 files | |
| Context Cursorcontext-cursor | ericts-ui | Components | Free | 1 dep | |
| Copy Buttoncopy-button | ericts-ui | Components | Free | 2 deps | |
| Expandable Dialogexpandable-dialog | ericts-ui | Components | Free | 1 dep | |
| Expandable Panelexpandable-panel | ericts-ui | Components | Free | 2 deps | |
| Expandable Segmented Tabsexpandable-segmented-tabs | ericts-ui | Components | Free | 1 dep |
