Ticket Number Ticker
moumenlab/ticket-number-tickerFreeComponent
An odometer that runs digits up on tabular-nums and middle-truncates long ids to start…end, with an optional GitHub PR status badge.
Live preview
live · rendered by the registry
Rendered by moumenlab on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://lab.moumen.dev/r/ticket-number-ticker.jsonSource
1"use client";23import { useEffect, useLayoutEffect, useRef, useState, type CSSProperties } from "react";4import { motion, MotionConfig, useAnimationControls, useReducedMotion } from "motion/react";56// Ticket number ticker - a ticket id shown as one celebratory value.7//8// The pill hugs its value and grows with it up to a max-width; a short #42 is a9// small pill, a longer id fills out toward the cap. Past the cap it uses the10// idiom every commit-SHA and wallet-address UI already uses: MIDDLE-TRUNCATE to11// `start…end`, keeping the two ends that identify and disambiguate and dropping12// the middle you can recover on hover (tooltip) or copy:13//14// #100000000042 → #10000…004215// #billing-webhook-...2026 → #billing-…-202616//17// How much survives is measured against the CAP's budget (not the current hug18// width) - a hidden clone is binary-searched to the last `#start…end` that fits.19//20// Numbers additionally get the odometer run-up: each surviving digit is a reel -21// a 1em window over a 0-9 strip - snapped to 0 then released to `10 + digit` so22// it scrolls a full turn and lands on target, cascading left→right. Bump23// `runKey` to play it (e.g. when a new ticket arrives). tabular-nums keeps every24// column exactly 1ch so nothing shifts as it rolls or truncates. Drop the digits25// entirely and it's a plain name: no reels.26//27// Pass `status` to show a GitHub pull-request state badge (open/draft/merged/28// closed, GitHub's own colours); pass `onStatusClick` to make it interactive.29// `width="fixed"` gives every pill one footprint for steady columns. As you30// type, motion's `layout` glides the centred pill to its new spot instead of31// snapping (position only - the width change stays instant so the new digit is32// never clipped). Animation via motion/react; honours prefers-reduced-motion.33// Requires the lab-theme tokens. Fully Tailwind, no CSS files.34//35// NOTE ON SIZE: the pill is deliberately compact (text-xl value, h-8 actions)36// so it drops straight into dashboards, list rows and toolbars. The lab demo37// page renders it inside a scale wrapper purely for presentation - what you38// install is the dashboard size you see in your own app.3940const MEASURE_SAFETY = 2; // px of slack so the value never kisses the clip edge4142const EASE = [0.22, 1, 0.36, 1] as const;43const EASE_ICON = [0.2, 0, 0, 1] as const;4445export type PrStatus = "open" | "draft" | "merged" | "closed";4647export interface TicketNumberState {48// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from moumenlab
All 14 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Caret-Anchored Mention Popovercaret-mention-popover | moumenlab | Components | Free | 1 dep | |
| Command Palette with Argument Chipscommand-palette | moumenlab | Components | Free | 1 dep | |
| Drag-to-Reorder Listdrag-to-reorder-list | moumenlab | Components | Free | 1 dep | |
| File Upload Staging Areafile-upload-staging | moumenlab | Components | Free | 1 dep | |
| Hover-Expand Icon Striphover-expand-icon-strip | moumenlab | Components | Free | 1 dep | |
| Inertial Wheel Listinertial-wheel-list | moumenlab | Components | Free | 1 dep | |
| Morphing Checkout Flowmorphing-checkout | moumenlab | Components | Free | 1 dep | |
| OTP Segmented Inputotp-segmented-input | moumenlab | Components | Free | 1 dep |
