# pulld > AI-installable, shadcn-compatible component registry. Production-ready React/Tailwind components that an AI coding agent (Claude Code, Cursor, v0) or the shadcn CLI can install by name. Every component is typed, accessible, and theme-aware. Free atoms plus paid Pro blocks. ## Install Add the namespace to your project's components.json, then add by name: ```json { "registries": { "@pulld": "https://pulld.pages.dev/r/{name}.json" } } ``` ```bash npx shadcn@latest add @pulld/copy-button # or directly by URL: npx shadcn@latest add https://pulld.pages.dev/r/copy-button.json ``` ## Components One line each: what the component is for. Each link serves that component's full description — the specific situations it is for, and the wording people ask for it by — alongside its source; the whole catalogue with those descriptions unabridged is at https://pulld.pages.dev/r/index.json. - [copy-button](https://pulld.pages.dev/r/copy-button.json): A one-click copy control: a square icon button that writes a string to the clipboard, swaps its clipboard icon for a tick, announces "Copied" to a screen reader, and resets itself a couple of seconds later. - [kbd](https://pulld.pages.dev/r/kbd.json): Inline keyboard key rendered as a real element and styled as a bordered monospace keycap — a drop-in for a bare tag that otherwise renders as unstyled monospace text. - [empty-state](https://pulld.pages.dev/r/empty-state.json): The centred placeholder a screen shows when it has nothing to draw — a dashed panel with an optional icon, a heading, one line of explanation, and room for a call to action. - [stat-card](https://pulld.pages.dev/r/stat-card.json): The single-number tile at the top of a dashboard: a label, one big value, and an optional percentage change with an up or down arrow — green when the number moved the right way, red when it did not. - [theme-toggle](https://pulld.pages.dev/r/theme-toggle.json): The one-button light/dark switch you drop in a navbar, header or settings row — click it and the whole app flips theme, and the choice survives a reload. - [avatar-stack](https://pulld.pages.dev/r/avatar-stack.json): A facepile in one prop: pass a list of people and a maximum, get a row of overlapping circular avatars with everything past the maximum collapsed into a "+N" badge. - [password-input](https://pulld.pages.dev/r/password-input.json): A password field with the show/hide eye already built in — the one control every sign-up form needs and shadcn/ui does not ship. - [spinner](https://pulld.pages.dev/r/spinner.json): An inline loading indicator that announces itself: a spinning lucide Loader2 inside a role="status" live region with a screen-reader-only label, so a pending operation is heard as well as seen. - [code-block](https://pulld.pages.dev/r/code-block.json): A read-only code panel: a bordered, scrollable box that shows a snippet with a copy button in the corner and an optional uppercase language label. - [loading-button](https://pulld.pages.dev/r/loading-button.json): Submit button that shows a spinner, announces itself, and refuses to fire twice while an async action is in flight. - [confirm-button](https://pulld.pages.dev/r/confirm-button.json): Inline two-step confirmation on the button itself, with no modal and no dialog state to wire up: the first click arms it — the label swaps to "Confirm?" and the button turns destructive — and only the second click calls onConfirm. - [command-palette](https://pulld.pages.dev/r/command-palette.json): A ready-made ⌘K command palette: one component you drop in, open with a keyboard shortcut, and fill with actions. - [toast](https://pulld.pages.dev/r/toast.json): A complete toast / notification system in one file: call `toast()` — or `toast.success` / `.error` / `.info` / `.warning` / `.loading` / `.promise` — from anywhere in your app, and render a single `` at the root. - [search-input](https://pulld.pages.dev/r/search-input.json): Search field with a leading magnifier and a trailing clear (✕) that appears as soon as there is text, empties the field, and puts focus back so typing can continue. - [number-input](https://pulld.pages.dev/r/number-input.json): A number field with − and + stepper buttons either side of it. - [otp-input](https://pulld.pages.dev/r/otp-input.json): A one-time passcode field split into separate digit boxes — the "enter the 6-digit code we sent you" screen. - [tag-input](https://pulld.pages.dev/r/tag-input.json): A multi-value text field: what gets typed becomes a removable chip, and the value the form sees is a plain string[]. - [copy-field](https://pulld.pages.dev/r/copy-field.json): Read-only field that shows a value with a copy button docked at its right edge: one click copies, and focusing or clicking anywhere in the field selects the whole value. - [segmented-control](https://pulld.pages.dev/r/segmented-control.json): A row of 2–4 mutually exclusive choices drawn as one moving pill on a shared track — the iOS-style segmented control, and what most dashboards use to switch a view or a range without navigating anywhere. - [step-indicator](https://pulld.pages.dev/r/step-indicator.json): Horizontal stepper that shows where someone is in a fixed sequence — numbered circle markers joined by a connecting line, each drawn as complete (filled, with a check), current (ringed and highlighted) or upcoming (muted). - [rating](https://pulld.pages.dev/r/rating.json): A star rating that works both ways: as an input that collects a score, and read-only as a display of one. - [timeline](https://pulld.pages.dev/r/timeline.json): A vertical timeline: a list of events drawn as dots on a connecting line, each with an optional timestamp, title, description and icon. - [announcement-bar](https://pulld.pages.dev/r/announcement-bar.json): A dismissible bar pinned above your header for a message the whole site needs to see: a launch or new release, a promo, sale or free-shipping offer, a scheduled-maintenance or downtime window, an incident or status notice, a beta or early-access note, a cookie or GDPR notice, a plan-expiring or payment-failed warning, or a 'you are viewing the docs for an old version' banner. - [file-dropzone](https://pulld.pages.dev/r/file-dropzone.json): A drag-and-drop file upload area that is also a real file picker: drop files onto it, or click it — or focus it and press Enter or Space — to open the native chooser. - [progress-ring](https://pulld.pages.dev/r/progress-ring.json): A circular progress indicator: an SVG ring that fills clockwise from twelve o'clock, with the percentage — or any icon or short label you pass — sitting in the middle of it. - [pricing-card](https://pulld.pages.dev/r/pricing-card.json): A single pricing plan card — one tier's box, with its name, its price, what it includes and the button that takes it. - [feature-card](https://pulld.pages.dev/r/feature-card.json): An icon + heading + one line of copy, as the repeating tile in the features or benefits section of a landing or marketing page — a “why us” grid, “what’s included”, value props, product highlights, services, capabilities, or a perks row on a pricing page. - [gauge](https://pulld.pages.dev/r/gauge.json): A semicircular (half-circle) gauge or dial that shows one measurement inside a known range, drawn as an SVG arc that fills from the left and animates to its new position. - [time-ago](https://pulld.pages.dev/r/time-ago.json): Auto-updating relative timestamp — "3 minutes ago", "just now", "in 2 days" — that re-renders on its own timer so the label stays true without a reload. - [multi-select](https://pulld.pages.dev/r/multi-select.json): A searchable multi-select: choose several options from a list you define, each shown as a removable badge in the trigger. - [countdown](https://pulld.pages.dev/r/countdown.json): A live countdown timer to a future moment — it re-renders every second, ticks down, never goes negative, and fires an onComplete callback once when it reaches zero. - [inline-edit](https://pulld.pages.dev/r/inline-edit.json): Click-to-edit text that stays where it is: a value shown as plain text with a pencil affordance that swaps to an input in the same spot when activated, commits on Enter or blur, and reverts on Escape — no dialog, drawer or separate edit form. - [autosize-textarea](https://pulld.pages.dev/r/autosize-textarea.json): A textarea that grows as you type and stops at a maximum height, then scrolls. - [currency-input](https://pulld.pages.dev/r/currency-input.json): A money input that shows a grouped, currency-formatted amount ($1,234.50) when idle and the raw number while you're editing, so the cursor never fights the thousands separators or symbol. - [floating-label-input](https://pulld.pages.dev/r/floating-label-input.json): A text input whose label sits inside the field like a placeholder, then shrinks and floats up to straddle the top border the moment the field is focused or holds a value — the Material "outlined" text field, as one accessible input with no animation library behind it. - [bulk-action-bar](https://pulld.pages.dev/r/bulk-action-bar.json): The bar that appears once rows are selected in a table or list — it shows "3 items selected", holds your bulk actions (delete, archive, export, assign, move, approve, mark as read) as children, and gives the user a way out of selection mode. - [save-status](https://pulld.pages.dev/r/save-status.json): The small inline "Saving… / Saved 2 minutes ago / Couldn't save · Retry" indicator that sits beside an autosaving surface, and the announcement that goes with it. - [form-error-summary](https://pulld.pages.dev/r/form-error-summary.json): The block that appears above a form after a failed submit — "There are 3 problems with your submission" followed by one link per error that jumps focus straight to the field it came from. - [type-to-confirm](https://pulld.pages.dev/r/type-to-confirm.json): The confirmation step in front of an irreversible action: the person has to type the resource's own name ("acme-prod") before the destructive button turns on. - [keyboard-shortcuts](https://pulld.pages.dev/r/keyboard-shortcuts.json): The help sheet that opens when the user presses ? — a modal listing every keyboard shortcut in the app, grouped by area, with the key caps drawn per platform. - [upload-list](https://pulld.pages.dev/r/upload-list.json): The list of files under a dropzone or file picker — one row each with the file name, its size, a progress bar while it uploads, an error with a retry button when it fails, and an X to drop it from the queue. - [bento-grid](https://pulld.pages.dev/r/bento-grid.json): The asymmetric panel grid behind most modern feature sections: a set of cards on one grid where a few cells are deliberately two columns wide or two rows tall, so the section reads as a composition instead of a row of identical boxes. - [tree-view](https://pulld.pages.dev/r/tree-view.json): The nested list you can open, close and walk with the arrow keys: a file explorer or file tree, a folder or directory tree, a category or taxonomy picker, an org chart, an API-schema browser, a docs sidebar with nested sections. - [sortable-list](https://pulld.pages.dev/r/sortable-list.json): Drag-to-reorder list: grab a row's grip handle and drop it in a new place — and do the same thing from the keyboard, which is the half that is normally missing. - [infinite-scroll](https://pulld.pages.dev/r/infinite-scroll.json): The footer of a list that keeps going: an invisible sentinel that loads the next page as it scrolls into view, plus a Load more button that always does the same job by hand. - [virtual-list](https://pulld.pages.dev/r/virtual-list.json): A long list that only puts the rows you can see into the DOM: five thousand rows render as about thirty nodes, so the page stops taking seconds to paint and scrolling stops stuttering. - [read-more](https://pulld.pages.dev/r/read-more.json): Long text clamped to a few lines with a Show more / Show less toggle that appears only when the text is genuinely too long. - [middle-truncate](https://pulld.pages.dev/r/middle-truncate.json): One line of text with the middle removed so that both ends stay readable, fitted to whatever width the container actually gives it. - [toc](https://pulld.pages.dev/r/toc.json): A table of contents for the page the reader is on, with the section they are currently reading highlighted as they scroll. - [date-input](https://pulld.pages.dev/r/date-input.json): A date field you type into, one segment at a time, that emits an ISO "YYYY-MM-DD" string. - [sparkline](https://pulld.pages.dev/r/sparkline.json): An inline SVG trend line — a sparkline — that shows the shape of a series in about the space of a line of text. - [slug-input](https://pulld.pages.dev/r/slug-input.json): A URL slug field that fills itself in from a title and then gets out of the way. - [password-strength](https://pulld.pages.dev/r/password-strength.json): A password strength meter for a sign-up, registration, change-password or reset-password form — the bar under the password field that says Weak or Strong, plus one line saying why. - [diff-view](https://pulld.pages.dev/r/diff-view.json): A line-by-line diff of two strings — the before/after view a screen needs when it has to show what changed: a config or settings change, a record edited in an admin panel, a document revision, a webhook payload against the last one, an audit-log entry, a restored backup next to what is live, or the edit an AI agent is proposing before the user accepts it. - [calendar-heatmap](https://pulld.pages.dev/r/calendar-heatmap.json): A year of daily counts as a grid of shaded squares — the GitHub-style contribution graph, drawn for whatever your app counts per day: commits, deploys, orders, sign-ins, posts, workouts, lessons, support tickets, API calls, or a habit tracker's streak. - [ansi-log](https://pulld.pages.dev/r/ansi-log.json): Renders raw terminal output — escape sequences and all — as styled, theme-aware HTML. - [cron-expression](https://pulld.pages.dev/r/cron-expression.json): Turns a cron expression into a sentence anyone can read, and lists the next times it fires. - [ratio-bar](https://pulld.pages.dev/r/ratio-bar.json): One horizontal bar that shows how a whole is divided up, with a legend that names every part — the GitHub-style language / storage bar. - [scroll-progress](https://pulld.pages.dev/r/scroll-progress.json): A bar that fills as the reader scrolls — the reading indicator across the top of an article, and the "how much is left?" cue on anything long. - [duration-input](https://pulld.pages.dev/r/duration-input.json): A text field that takes a length of time written the way people actually write one — 90m, 1h30m, 1h 30m, 2d 4h 15m, 1:30, 1.5h, 500ms, "90 minutes" — reads it into milliseconds, and echoes the reading back in words underneath it ("1 hour 30 minutes") so the interpretation is never left to be guessed at. - [color-picker](https://pulld.pages.dev/r/color-picker.json): A colour picker built from a hex/rgb/hsl text box and native hue, saturation and lightness sliders, with optional alpha and preset swatches. - [json-viewer](https://pulld.pages.dev/r/json-viewer.json): Renders a parsed JSON value as a collapsible, type-coloured tree you can read and navigate. - [image-comparison](https://pulld.pages.dev/r/image-comparison.json): A before/after slider: two images stacked in the same box with a divider you drag across them, so the second is revealed over the first instead of sitting next to it. - [timezone-select](https://pulld.pages.dev/r/timezone-select.json): A time zone picker: every IANA zone the browser knows, grouped by region and labelled with the UTC offset it is actually on — "New York (UTC-04:00)", "Kolkata (UTC+05:30)", "Chatham (UTC+12:45)". - [month-picker](https://pulld.pages.dev/r/month-picker.json): A month picker: a year of twelve months as a grid, with arrows on the year, that hands back a plain "YYYY-MM" string — "2026-08" — and never a day or a time zone. - [time-input](https://pulld.pages.dev/r/time-input.json): A time field you type into, one segment at a time, that hands back a plain 24-hour clock string — "09:30", or "09:30:15" with seconds — and never a date and never a time zone. - [weekly-hours](https://pulld.pages.dev/r/weekly-hours.json): A week of opening hours in one editor: seven rows, each a switch plus an opening and a closing time, handing back a plain object keyed by weekday. - [country-select](https://pulld.pages.dev/r/country-select.json): A country picker: all 249 ISO 3166-1 countries, named in the reader's own language, sorted the way that language sorts, and searchable by local name, English name or two-letter code. - [currency-select](https://pulld.pages.dev/r/currency-select.json): A currency picker: every ISO 4217 currency the runtime knows, named in the reader's own language, sorted the way that language sorts, and searchable by local name, English name, three-letter code or symbol. - [language-select](https://pulld.pages.dev/r/language-select.json): A UI language picker: every language named in its own language — 日本語, Deutsch, العربية, 한국어 — with its name in the page's language beside it, its BCP-47 tag, and a filter that reaches it by all four. - [phone-input](https://pulld.pages.dev/r/phone-input.json): An international phone number field: a searchable country picker, that country's calling code shown as a live prefix, and one E.164 string ("+819012345678") coming back out. - [password-generator](https://pulld.pages.dev/r/password-generator.json): A password generator: a read-only field holding the generated password, a Generate control, a copy button, and switches for length, character classes and look-alike exclusion. - [network-status](https://pulld.pages.dev/r/network-status.json): An offline banner that is right about being offline: it tells someone the page has lost the network, and — the harder half — only tells them it is back once that has actually been verified. - [recovery-codes](https://pulld.pages.dev/r/recovery-codes.json): The sheet of two-factor backup codes, with the three ways off the screen that people actually use: copy, download as a .txt, and print. - [unsaved-changes-guard](https://pulld.pages.dev/r/unsaved-changes-guard.json): A leave guard for a form with unsaved changes: it holds the departure, asks whether the work should be discarded, and lets it through only when the answer is yes. - [csv-export-button](https://pulld.pages.dev/r/csv-export-button.json): A button that turns rows into a CSV file the browser saves — with the two things the inline version gets wrong already handled: the spreadsheet formulas hiding in your data, and the fact that the page is usually only holding one page of the table. - [idle-timeout](https://pulld.pages.dev/r/idle-timeout.json): An inactivity timeout with a warning before it fires: it watches for the user going away, puts up a "you will be signed out in 1:59" dialog with a live countdown, lets them stay with one click, and keeps every open tab agreeing about when the session actually ends. - [char-counter](https://pulld.pages.dev/r/char-counter.json): The "42 left" that sits under a field with a limit — a bio, a post box, a product description, an SMS body, a subject line — counting the characters a person can actually see rather than the code units the string happens to be made of, and showing the limit being crossed instead of quietly cutting the text off. - [scroll-shadow](https://pulld.pages.dev/r/scroll-shadow.json): A scrolling box whose edges fade out while there is more content past them, and stop fading the moment there is not — the cue that tells a reader a wide table has columns off to the right, or that a panel continues below the fold. - [mention-input](https://pulld.pages.dev/r/mention-input.json): The comment box where typing `@` opens a list of people and picking one types their handle in — the completion that lives inside the prose, anchored under the caret rather than under the field. - [signature-pad](https://pulld.pages.dev/r/signature-pad.json): The box at the bottom of a form where somebody signs with a finger, a mouse or a stylus — and, beside it, the field where somebody who cannot draw types their name instead. - [image-crop](https://pulld.pages.dev/r/image-crop.json): The step that comes straight after a photo is chosen: the picture sits behind a frame of the shape the product needs, and you drag it about and pinch or scroll to zoom until the right part is in the window. - [sort-header](https://pulld.pages.dev/r/sort-header.json): One sortable column heading for a table you already have: press it and the rows re-order, press it again for the other direction, press it a third time and the table goes back to the order it arrived in. - [qr-code](https://pulld.pages.dev/r/qr-code.json): A scannable QR code, drawn as SVG, for putting a link, a Wi-Fi network or a 2FA secret on screen where a phone can pick it up. - [barcode](https://pulld.pages.dev/r/barcode.json): A scannable one-dimensional barcode, drawn as SVG, for the symbol a handheld scanner or a till actually reads — Code 128 for anything of your own, EAN-13 for a retail product number. - [share-button](https://pulld.pages.dev/r/share-button.json): A share control that opens the device's native share sheet and quietly degrades to copying the link where that sheet does not exist. - [print-button](https://pulld.pages.dev/r/print-button.json): Prints one region of the page — an invoice, a receipt, an order confirmation, a ticket or boarding pass, a packing slip, a report or dashboard panel, a chart, a table, a quote or estimate, an itinerary, a certificate, a prescription, a shipping label, a résumé, or a card carrying a generated QR code — instead of printing the page it happens to be sitting on. - [masked-input](https://pulld.pages.dev/r/masked-input.json): Holds a text field to one fixed shape while it is typed — a postal or ZIP code, a product or licence key, a serial, model or part number, an employee, member, account or policy number, a VIN, an IBAN, a SWIFT/BIC, a tracking number, an ISBN, a tax or national ID, a MAC address, a coupon or voucher code. - [fullscreen-button](https://pulld.pages.dev/r/fullscreen-button.json): A button that shows one element — a chart, a data table, a map, a video player, a preview pane — full-screen on its own, and keeps telling the truth about it afterwards. - [wake-lock-toggle](https://pulld.pages.dev/r/wake-lock-toggle.json): A toggle that stops the screen going dark while somebody is looking at it but not touching it, and — unlike every version written by hand — keeps on being true about whether the screen is actually being held awake. - [geolocation-button](https://pulld.pages.dev/r/geolocation-button.json): A "use my current location" button that is right about why it didn't. - [highlight-text](https://pulld.pages.dev/r/highlight-text.json): Text with the parts matching a search query highlighted, built so that neither the text nor the query can break it — and both of them routinely arrive from a URL query string. - [image-zoom](https://pulld.pages.dev/r/image-zoom.json): A frame that zooms whatever is inside it — wheel, trackpad pinch, double click or the buttons — and lets you drag it around once it no longer fits. - [speech-input](https://pulld.pages.dev/r/speech-input.json): A press-to-dictate microphone button that fills a text field by voice, and stops claiming to listen the moment the browser has stopped. - [date-range-preset](https://pulld.pages.dev/r/date-range-preset.json): A row of date-range presets — Today, Last 7 days, Month to date, Last month, Year to date — with a custom from/to range behind the last option, that answers with a relative expression like "last7d" instead of a pair of dates. - [camera-capture](https://pulld.pages.dev/r/camera-capture.json): A take-a-photo control that opens the device camera inline, shows a live preview, captures a still to a Blob, and — the part every hand-rolled version gets wrong — hands the camera back the moment it is done with it. - [filter-chips](https://pulld.pages.dev/r/filter-chips.json): The row of pills above a list that says which filters are in force — one chip per applied condition, each with a × that takes off only that condition, plus a clear-all that offers an undo. - [product-tour](https://pulld.pages.dev/r/product-tour.json): A guided tour of the real screen: a card that walks through your own UI, dimming the page and lighting up the one control each step is about, with Back and Next, a progress count, a way out, and placement that flips to whichever side of the target has room. - [pull-to-refresh](https://pulld.pages.dev/r/pull-to-refresh.json): A list that reloads when it is pulled down from the top, the way a native app does, plus a Refresh button that always does the same job. - [sticky-table-header](https://pulld.pages.dev/r/sticky-table-header.json): Keeps a long table's header row visible while the rows scroll, and freezes up to three leading columns while it scrolls sideways — Excel's freeze panes, for an HTML table — by wrapping the you already have, with no change to a single
. - [paste-area](https://pulld.pages.dev/r/paste-area.json): A region that takes whatever is on the clipboard — a screenshot, an image, a file, a table copied out of a spreadsheet, or plain text — and hands it over as typed items, with each pasted picture given a name it can actually be filed under instead of the image.png that every browser calls it. - [swipe-actions](https://pulld.pages.dev/r/swipe-actions.json): A list row that slides sideways under a thumb to reveal what can be done to it — archive, delete, mark read, pin, snooze — with a button on the row that reveals exactly the same actions, because a swipe is not a control a keyboard or a screen reader has. - [shortcut-recorder](https://pulld.pages.dev/r/shortcut-recorder.json): The settings field that records a keyboard shortcut: the user presses the combination they want and it is captured as a value you can store. - [audio-recorder](https://pulld.pages.dev/r/audio-recorder.json): A voice-note recorder: press to record, watch the input level move while it does, stop, play it back, and get a Blob you can upload — and, the part every hand-rolled version gets wrong, the microphone is handed back the moment it is finished with. - [nested-checkbox](https://pulld.pages.dev/r/nested-checkbox.json): The checkbox list with parents and children that agree with each other: tick every child and the parent fills in, tick the parent and the whole branch follows, tick some of them and the parent shows the third state — a dash, announced as "partially checked" rather than as "not checked". - [drag-select](https://pulld.pages.dev/r/drag-select.json): Rubber-band selection: drag from the empty space around a list, a grid or a board and everything the rectangle touches is selected, with the container scrolling itself when the pointer reaches its edge. - [json-input](https://pulld.pages.dev/r/json-input.json): A textarea for editing JSON by hand that says exactly where the mistake is — line, column and a caret you can jump to. - [column-resizer](https://pulld.pages.dev/r/column-resizer.json): Drag the line between two column headings to set that column's width, in a you already have — with the widths kept where you put them, a keyboard path through the same control, and double-click to fit a column to its contents. - [media-scrubber](https://pulld.pages.dev/r/media-scrubber.json): The playback position bar for an