@molecule/app-listing-card-react
Feature · listing-card · App (browser) · v1.0.2 · Apache-2.0
React listing/product-card primitives with media, body, actions slots
npm install @molecule/app-listing-card-reactHow it works
@molecule/app-listing-card-react is a ready-made listing-card feature for the app (browser) side. It composes the core interfaces it needs, so it works with whichever providers your app has bonded.
import {
ListingCard,
ListingCardMedia,
ListingCardBody,
ListingCardActions,
ListingGrid,
} from '@molecule/app-listing-card-react'
;<ListingGrid columns={3}>
<ListingCard onClick={() => navigate(`/listings/${item.id}`)}>
<ListingCardMedia src={item.imageUrl} aspect="4/3" alt={item.name} />
<ListingCardBody title={item.name} subtitle={item.location} price={`$${item.price}/night`} />
<ListingCardActions>
<button
onClick={(e) => {
e.stopPropagation()
saveListing(item.id)
}}
>
Save
</button>
</ListingCardActions>
</ListingCard>
</ListingGrid>Works with: @molecule/app-react, @molecule/app-ui, @molecule/app-ui-react
Reference
React product / property / listing card primitives.
Exports:
<ListingCard>— outer Card shell. Props:children,onClick?,className?,dataMolId?.<ListingCardMedia>— top image slot. Props:src?,alt?,children?(custom media node),aspect?('1/1' | '4/3' | '16/9' | '3/2', default'4/3', applied as an inline aspect-ratio style),overlay?(badge / favorite button, absolutely positioned over the media),className?.<ListingCardBody>— stacked text. Props:title,subtitle?,price?,meta?,className?.<ListingCardActions>— action row. Props:children,layout?('horizontal'default |'stacked'),className?.<ListingGrid>— grid container. Props:children,columns?(1–6, default 3),gap?,className?.
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Quick Start
import {
ListingCard,
ListingCardMedia,
ListingCardBody,
ListingCardActions,
ListingGrid,
} from '@molecule/app-listing-card-react'
;<ListingGrid columns={3}>
<ListingCard onClick={() => navigate(`/listings/${item.id}`)}>
<ListingCardMedia src={item.imageUrl} aspect="4/3" alt={item.name} />
<ListingCardBody title={item.name} subtitle={item.location} price={`$${item.price}/night`} />
<ListingCardActions>
<button
onClick={(e) => {
e.stopPropagation()
saveListing(item.id)
}}
>
Save
</button>
</ListingCardActions>
</ListingCard>
</ListingGrid>
Type
feature
Installation
npm install @molecule/app-listing-card-react @molecule/app-react @molecule/app-ui @molecule/app-ui-react react
npm install -D @types/react
API
Interfaces
ListingCardProps
Props for ListingCard.
interface ListingCardProps {
/** Slots — usually `<ListingCardMedia>` + `<ListingCardBody>` + `<ListingCardActions>`. */
children: ReactNode
/**
* Called on any click on the card — including clicks inside
* `<ListingCardActions>`, which bubble into it unless the action handler
* calls `e.stopPropagation()`.
*/
onClick?: () => void
/** Extra classes on the outer Card. */
className?: string
/** `data-mol-id` for AI-agent selectors. */
dataMolId?: string
}
ListingCardActionsProps
Props for ListingCardActions.
interface ListingCardActionsProps {
/** Action content — buttons, favorite toggle, etc. */
children: ReactNode
/** Layout — `'horizontal'` (default) fills width, `'stacked'` is vertical. */
layout?: 'horizontal' | 'stacked'
/** Extra classes. */
className?: string
}
ListingCardBodyProps
Props for ListingCardBody.
interface ListingCardBodyProps {
/** Primary title / name. */
title: ReactNode
/** Secondary line (subtitle, location, category). */
subtitle?: ReactNode
/** Price / metric line. */
price?: ReactNode
/** Optional extras row (rating, availability, badges). */
meta?: ReactNode
/** Extra classes. */
className?: string
}
ListingCardMediaProps
Props for ListingCardMedia.
interface ListingCardMediaProps {
/** Image URL or ReactNode. */
src?: string
alt?: string
/** Override with a ReactNode (video, carousel, svg). */
children?: ReactNode
/** Aspect ratio (`'1/1' | '4/3' | '16/9' | '3/2'`), applied as an inline `aspect-ratio` style. Defaults to `'4/3'`. */
aspect?: '1/1' | '4/3' | '16/9' | '3/2'
/** Optional overlay node (badge, favorite heart). */
overlay?: ReactNode
/** Extra classes. */
className?: string
}
ListingGridProps
Props for ListingGrid.
interface ListingGridProps {
children: ReactNode
/** Column count, fixed at every viewport width. Defaults to 3. */
columns?: 1 | 2 | 3 | 4 | 5 | 6
gap?: 'xs' | 'sm' | 'md' | 'lg'
className?: string
}
Functions
ListingCard(props)
Product / property / listing card shell. Just a <Card> with vertical
stacking of its children — typically <ListingCardMedia> +
<ListingCardBody> + <ListingCardActions>.
Use for product tiles, property cards, course cards, listings, and similar content-card layouts.
function ListingCard({ children, onClick, className, dataMolId }: ListingCardProps): JSX.Element
props— Component props (seeListingCardProps).
ListingCardActions(props)
Bottom action row of a <ListingCard> (Add to cart, Save, etc.).
function ListingCardActions({
children,
layout = 'horizontal',
className,
}: ListingCardActionsProps): JSX.Element
props— Component props (seeListingCardActionsProps).
ListingCardBody(props)
Body of a <ListingCard> — title / subtitle / price / meta rows stacked.
function ListingCardBody({
title,
subtitle,
price,
meta,
className,
}: ListingCardBodyProps): JSX.Element
props— Component props (seeListingCardBodyProps).
ListingCardMedia(props)
Media slot at the top of a <ListingCard>. Locks aspect ratio via
inline style so apps get consistent card sizing without custom CSS.
function ListingCardMedia({
src,
alt,
children,
aspect = '4/3',
overlay,
className,
}: ListingCardMediaProps): JSX.Element
props— Component props (seeListingCardMediaProps).
ListingGrid(props)
Grid for <ListingCard>s — a fixed columns-column grid at every
viewport width. Alias for CardGrid tuned for listing layouts — same
shape, different semantic name so importers can self-document.
function ListingGrid({
children,
columns = 3,
gap = 'md',
className,
}: ListingGridProps): JSX.Element
props— Component props (seeListingGridProps).
Injection Notes
Requirements
Peer dependencies:
@molecule/app-react^1.0.1@molecule/app-ui^1.0.1@molecule/app-ui-react^1.0.1react^18.0.0 || ^19.0.0
Runtime Dependencies
-
@molecule/app-react -
@molecule/app-ui -
@molecule/app-ui-react -
react -
ListingCard.onClickis attached to the WHOLE card — clicks on buttons inside<ListingCardActions>bubble into it. Calle.stopPropagation()in every action handler (as in the example) or the card navigation fires too. -
<ListingGrid columns={n}>renders a responsive n-column grid (viacm.grid): 1 column on phones, stepping up tonat larger breakpoints, so listings don't overflow on mobile. OverrideclassNamefor a fixed grid. -
overlaychildren are rendered inside an absolutely-positioned inset-0 layer; give interactive overlays their own pointer handling and stopPropagation. -
Styling resolves through
getClassMap(); the shell uses<Card>from@molecule/app-ui-react— wire a ClassMap bond first.