Property Card

Pro

Real-estate and rental listing card with swipeable photos, price, beds, baths and area. Saving fills the heart and can leave a small marker, so saved homes stand out in the list.

Preview

Installation

npx @lumioui/cli add pro/property-card

Usage

import { PropertyCard } from "@/components/ui/property-card/property-card";
<PropertyCard />

Examples

Search results

A home-search results feed.

Map peek

Map search for rentals.

Custom photos

A holiday-rental listing that renders its own pager pages through `renderPhoto`: every photo carries its room caption, and each page owns its tap (where a screen would drop in a LightboxImage) — here it pins the room you are looking at.

Row list

A saved-rentals list.

API reference

Prop Type Default
photos* PropertyPhoto[]

Listing photos — https URLs or { uri, alt }. The first is the cover.

—
price* number | string

Price — a number is formatted with formatPrice, a string prints as-is.

—
address* string

Street address — one line, truncates.

—
priceSuffix string

Unit after the price ("/mo", "/night").

—
formatPrice (price: number) => string

Formatter for numeric prices. Default $689,000.

defaultFormat
priceNote string

Short line beside the price ("Price cut $15k", "Est. $3,940/mo").

—
beds number

Bedrooms — 0 prints "Studio".

—
baths number —
area number

Interior area.

—
areaUnit string

Area unit. Default "sqft".

—
facts string[]

Replace the beds/baths/area row with your own facts ("Garden", "EPC B").

—
subtitle string

Secondary line under the address (neighbourhood, listing agent, "Listed 3 days ago").

—
tags string[]

Pills over the photo — keep to one or two ("Open house Sat", "New").

—
saved boolean

Controlled saved state.

—
defaultSaved boolean

Uncontrolled initial saved state.

—
onSavedChange (saved: boolean) => void

Called when the heart toggles. Omit both saved props and this to hide the heart.

—
savedLabel string

Where a save lands ("Tour list"). Stack layout shows a "Saved · …" chip over the photo on save, which condenses into an accent dot that stays.

—
layout "stack" | "row"

stack (photo on top with pager) or row (thumbnail left). Default "stack".

"stack"
aspectRatio number

Photo aspect ratio in stack layout. Default 4 / 3.

4 / 3
photoIndex number

Controlled photo index.

—
defaultPhotoIndex number

Uncontrolled initial photo index.

0
onPhotoIndexChange (index: number) => void

Fires when the pager settles on a new photo.

—
onPhotoPress (index: number) => void

Tap on a photo — open a lightbox at that index. Falls back to onPress.

—
renderPhoto
(source: { uri: string }, index: number … (source: { uri: string }, index: number, photo: PropertyPhoto) => React.ReactNode

Render each photo yourself — e.g. a LightboxImage so a tap zooms out of the card. Receives the image source, the index and the original photo entry; fill the page (h-full w-full). The returned node owns its own taps (onPhotoPress is not wired around it). Default: a cover Image.

—
onPress () => void

Tap anywhere else on the card — open the listing.

—
footer React.ReactNode

Extra content at the bottom of the card body (agent row, CTA).

—
className string —