shadcn.io is not affiliated with official shadcn/ui
Real Estate Listings Map Block for React
A map of twelve homes with a row of snap-scrolling listing cards under it: the card at the start rings its price pill, pressing a pill scrolls the row to its card, and a type toggle filters both.
Installation
Overview
Keep the map and the listings in step, with this real estate listings map for React with Base UI. Deedwick, a home listings site, draws twelve homes as price pills on an SVG street map of the invented market town of Quennelby, and a row of listing cards under it scrolls and snaps one card at a time. The card at the start of the row is the one the map marks: its pill gets a ring as you scroll, pressing a pill scrolls the row to that card, and Previous and Next step through the cards. A type Toggle Group (All, House, Flat, Cottage) carries its counts and filters the cards and the pills together; a home it leaves out keeps its pill in place, hidden. A card gives the type, the address, the price, bedrooms, bathrooms and area, and the date it was listed. The row is a plain scroll-snap list that scrolls its own box and never the page. It's built from Toggle Group, Button and Guides, with a CSS entrance only. For home listings, lettings and travel sites.
FAQ
How does the map know which card is showing?
The row reports its scroll position. On every scroll the block finds the card whose start edge is nearest the row's start edge (and the last card once the row is scrolled to its end) and rings that card's pill. It works in a right-to-left page too, because the distance is measured from the row's own start. Pressing a pill does the reverse: it scrolls the row with scrollBy so the card sits at the start, and never calls scrollIntoView, which would move the page.
Why not the Carousel component?
The map has to read the position of the row, and the catalog's Carousel hides its scroller behind its own page API on each base. A scroll-snap list gives the same swipe, the same snapping and the same keyboard scrolling on all seven targets with no per-library code. If you want autoplay, dots or looping, swap the list for the Carousel and drive the current card from its page callback instead of onScroll.
What happens to a card that the filter leaves out?
It leaves the row, and the row returns to its first card. Its pill stays where it is on the map, hidden and out of the tab order, so nothing else moves. Every type has at least two homes, so the row is never empty.
Can I use it without a mouse?
Yes. The row is a focusable scroll region, so the arrow keys scroll it; each card is a button that marks it; Previous and Next are named buttons that step one card and stay in the tab order at the ends. The pills are hidden from assistive technology and skipped by Tab because the cards say the same things in text. A polite message speaks the card once the row settles.