@resi/cls
Imported React product widgets for Resi Central Leasing Sites. Components ship as an npm dependency rather than registry source so every site receives the same search behavior and can be upgraded without regenerating its markup.
Install
pnpm add @resi/cls
React 18 and 19 are supported as peer dependencies. UnitMapSearch includes
its own scoped CSS; consumers do not need Tailwind, UIkit, or YOOtheme. Import
the stylesheet once from the application's root layout so it is present on the
first server-rendered paint:
import "@resi/cls/styles.css";
UnitMapSearch
import { UnitMapSearch } from "@resi/cls";
export function Apartments() {
return (
<UnitMapSearch
algolia={{
applicationId: process.env.NEXT_PUBLIC_ALGOLIA_APP_ID!,
searchApiKey: process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_KEY!,
indexName: process.env.NEXT_PUBLIC_ALGOLIA_UNIT_INDEX!,
}}
googleMaps={{
apiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_KEY!,
}}
search={{
syncUrl: true,
buildUnitUrl: (_hit, slug) => `/listing/${slug}/`,
}}
filters={{
preFilters: 'propertyState:"TX"',
}}
theme={{
primary: "oklch(0.42 0.08 32)",
primaryForeground: "oklch(0.98 0.01 32)",
radius: "0.25rem",
}}
/>
);
}
The bundle carries a "use client" directive for Next.js App Router. API keys
are browser-visible by design: use an Algolia search-only key and restrict
the Google Maps browser key by referrer and API.
Configuration
algolia— application ID, search-only API key, and index name.googleMaps— browser API key plus optional center, zoom, maximum zoom, map ID, styles, gesture behavior, andclickableIcons. Without a map ID, the default map hides all built-in POI and transit labels/icons. UseenabledIconCategories, for example["public-transit", "parks"], to enable selected categories. Additionalstylesare appended afterward;clickableIcons: falsedisables every Google-provided icon without affecting property markers. Map-ID styling is configured in Google Cloud.theme— normalized TweakCN semantic values:background,foreground,card,cardForeground,primary,primaryForeground,secondary,secondaryForeground,muted,mutedForeground,accent,accentForeground,border,input,ring,radius,fontSans,fontSerif, andfontMono. Values are applied as component-scoped--resi-cls-*variables, never global tokens.layout— split or list presentation, result columns, viewport and control heights, pill radius, and card-price weight.filters— facet definitions, Algolia field mappings, price ranges, pre-filters, and initial selections.search— debounce, result limit, URL synchronization, initial query/sort, placeholder, detail URL builder, and missing-unit notice behavior.copy— all renter-visible headings, status text, and action labels.- Callbacks —
onUnitSelect,onPropertySelect,onSearchStateChange, andonError.
Supported icon categories are attractions, businesses, government,
medical, parks, places-of-worship, public-transit, schools, and
sports-complexes.
The mobile experience uses an accessible Map/List toggle. On desktop, the map and result grid render side-by-side with property-level price/count markers. If Google Maps fails, search and the apartment list remain usable.
Algolia index requirements
The Brick Timber defaults expect these filterable attributes:
unitAvailable,unitModel,unitGuestSuitecustomFacets.neighborhoodunitBedrooms,unitBathrooms,unitMinTmlpamenityNames,propertyAmenityNames
Hits should also include a stable unit ID, property ID/name, unit number,
property coordinates (or _geoloc), image/slug or permalink, and TMLP.
fieldMappings can adapt alternate names.
The widget enforces public marketability as:
unitAvailable && !unitModel && !unitGuestSuite
It displays only TMLP. Missing or invalid TMLP hides the price; it never falls
back to base rent or $0.
License
Licensed exclusively for websites or applications that connect to the Resi
platform. See LICENSE.