shadcn.io is not affiliated with official shadcn/ui
Map Sidebar Skeleton Block for React
A pharmacy chain's store locator in a window that loads in place: the search field, two filters and a drawn map stay while bars become five stores and their numbered pins.
Installation
Overview
Show a store locator while its results load, then swap the stores in without moving anything, with this map sidebar skeleton for React with Base UI. A framed window for Tormentil, a pharmacy chain, has a top bar with the locator's name and a Load control over a list pane and a drawn map of an invented town, Harlowmere. The pane's search field, its two filters, Open now and Pickup, and the map's streets are real from the first paint; the five stores, each a number, a name, two address lines, a distance and its hours, and their five numbered pins are Skeleton bars that become the data in the same cells when you press Load, the list first and then the pins. Once loaded, the search field and the Toggle Group filters really narrow the list and dim the pins of the stores they leave out. The list scrolls inside its pane and the window keeps its height; on a phone the map is a band above the list. It's built from Skeleton, Input, Toggle Group, Button and Guides, with a CSS entrance only. For store locators, branch finders and any list beside a map that waits for a query.
FAQ
What stays local, and how do I wire it to a real query?
Nothing is fetched. The five stores are typed in STORES, with their hours and pin positions, and the search and the filters work on that array. Load starts a 700 millisecond timer, and when it ends the phase becomes ready and the data swaps in; Reload goes back to the bars and in again. To wire it for real, delete the timer, the Load button and the polite line, and set data-state (loading or ready) and aria-busy on the region from your query's pending state, or use the bars as a Suspense fallback and render the real data when it arrives. The bars are derived from the same data as the real thing, so keep one component for both.
Do the search and the filters work?
Once the stores are loaded, yes, locally: the field matches the name, the street and the postcode, Open now keeps the stores open at the sample's fixed time, Pickup keeps the ones that offer it, and the polite line says how many match. Pins of the stores left out turn dashed instead of disappearing, so the numbers keep their places. While loading, the filters hold their state and apply when the data arrives.
Is the map real?
It is a drawing of an invented town, not to scale, built from a few SVG paths and numbered pins placed in percent of the drawing, with a caption that says so. In your app put a map library in its place and keep the pins' numbers in step with the list. The map stays left to right in a right-to-left page, because a map does not mirror.
Does the window change size while it loads?
No. The window has a fixed height, only the list scrolls inside its pane, and each store is a fixed-height row whose bars and data share one grid cell. The search field, the filters, the streets and the frame are real in both phases.
Is it accessible?
The region is marked busy while it loads and carries a screen-reader-only "Loading stores…", and the polite line announces what loaded once. The bars are hidden from assistive technology and the layer that isn't showing is invisible, so it is neither read nor focusable. The pulse stops when the data is in, and under reduced motion there is no pulse, no spinner and no stagger: the swap is instant. The list is a named region you can scroll from the keyboard, the pins are decorative and hidden from assistive technology, since the list says the same, and a store's number is hidden so only its name is read.