react-listing-engine 0.6.4 → 0.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +54 -65
  2. package/dist/chunk-OXSYNZAJ.js +2 -0
  3. package/dist/chunk-PE27NATS.cjs +2 -0
  4. package/dist/index.cjs +2 -2
  5. package/dist/index.d.cts +95 -16
  6. package/dist/index.d.ts +95 -16
  7. package/dist/index.js +1 -1
  8. package/dist/{listing-app-wmMuDlVU.d.ts → listing-app-4Vs_SMNl.d.cts} +146 -26
  9. package/dist/{listing-app-DJbvx3oe.d.cts → listing-app-CkEGdUV9.d.ts} +146 -26
  10. package/dist/map-provider.interface-DT-v1plm.d.cts +67 -0
  11. package/dist/map-provider.interface-DT-v1plm.d.ts +67 -0
  12. package/dist/maps/google/index.d.cts +1 -2
  13. package/dist/maps/google/index.d.ts +1 -2
  14. package/dist/styled/index.cjs +1 -1
  15. package/dist/styled/index.d.cts +7 -10
  16. package/dist/styled/index.d.ts +7 -10
  17. package/dist/styled/index.js +1 -1
  18. package/dist/testing/index.d.cts +1 -2
  19. package/dist/testing/index.d.ts +1 -2
  20. package/package.json +3 -14
  21. package/dist/chunk-2VUHLHHX.cjs +0 -2
  22. package/dist/chunk-35KYEBAC.js +0 -2
  23. package/dist/chunk-5FBI2WIM.js +0 -2
  24. package/dist/chunk-6PZHSHU3.js +0 -2
  25. package/dist/chunk-CGT3RHJ7.js +0 -2
  26. package/dist/chunk-CHNUE46K.cjs +0 -2
  27. package/dist/chunk-EYXV5OMY.cjs +0 -2
  28. package/dist/chunk-LCQZIWBO.cjs +0 -2
  29. package/dist/chunk-R3FX2V3N.js +0 -2
  30. package/dist/chunk-RXHR66FS.cjs +0 -2
  31. package/dist/components-provider-CF0Mo0B8.d.cts +0 -120
  32. package/dist/components-provider-CjMxkxrP.d.ts +0 -120
  33. package/dist/entity-adapter.interface-BDgbSxhq.d.cts +0 -33
  34. package/dist/entity-adapter.interface-BDgbSxhq.d.ts +0 -33
  35. package/dist/listing-config-options.interface-ZJYY_ZvR.d.cts +0 -12
  36. package/dist/listing-config-options.interface-ZJYY_ZvR.d.ts +0 -12
  37. package/dist/map-provider.interface-BMnwW3ob.d.cts +0 -37
  38. package/dist/map-provider.interface-BxexMT3X.d.ts +0 -37
  39. package/dist/presets/rental/index.cjs +0 -2
  40. package/dist/presets/rental/index.d.cts +0 -266
  41. package/dist/presets/rental/index.d.ts +0 -266
  42. package/dist/presets/rental/index.js +0 -2
  43. package/dist/shadcn/index.cjs +0 -2
  44. package/dist/shadcn/index.d.cts +0 -261
  45. package/dist/shadcn/index.d.ts +0 -261
  46. package/dist/shadcn/index.js +0 -2
  47. package/dist/url-sync.controller-CsU_QxoS.d.cts +0 -89
  48. package/dist/url-sync.controller-DX67JivW.d.ts +0 -89
@@ -1,120 +0,0 @@
1
- import { a as EntityAdapter, M as MapPoint } from './entity-adapter.interface-BDgbSxhq.cjs';
2
- import * as react from 'react';
3
- import { ComponentType, ReactNode } from 'react';
4
-
5
- interface FilterControlProps<TValue> {
6
- value: TValue;
7
- onChange(next: TValue): void;
8
- }
9
- interface FilterDefinition<TFilters, TValue = unknown> {
10
- key: string;
11
- order: number;
12
- render: string | ComponentType<FilterControlProps<TValue>>;
13
- toParams(value: TValue): Partial<TFilters>;
14
- fromParams(filters: TFilters): TValue;
15
- isActive?(filters: TFilters): boolean;
16
- /** Optional human-readable label rendered above the control by `ListingFilters`. Omit for an unlabeled filter (backward compatible). */
17
- label?: string;
18
- }
19
-
20
- interface ClusterOptions {
21
- maxZoom?: number;
22
- radius?: number;
23
- }
24
- interface MarkerRenderer<TEntity> {
25
- iconUrl?(entity: TEntity): string;
26
- element?(entity: TEntity): HTMLElement;
27
- onClick?(entity: TEntity): void;
28
- }
29
- interface DatasetDefinition<TEntity, TFilters> {
30
- id: string;
31
- adapter: EntityAdapter<TEntity, TFilters>;
32
- marker: MarkerRenderer<TEntity>;
33
- clustering?: ClusterOptions | false;
34
- visible?: () => boolean;
35
- }
36
-
37
- /**
38
- * Framework-free registry for `FilterDefinition`s: programmatic add / remove /
39
- * reorder / replace, plus folding raw control values into `TFilters`
40
- * (`toFilters`) and reporting which registered filters currently affect an
41
- * applied `TFilters` (`activeKeys`).
42
- *
43
- * Defs are stored by VALUE (shallow-cloned on `add`/`replace`), never by the
44
- * caller's original reference — `reorder()` rewrites `order` in place on the
45
- * registry's own copy. This is deliberate: the same `FilterDefinition` object
46
- * can legitimately be registered in more than one `FilterRegistry` instance
47
- * (e.g. two listing pages sharing a base filter set), and without cloning,
48
- * one registry's `reorder()` would silently mutate `.order` on the shared
49
- * object and bleed into every other registry (and the caller) holding it.
50
- */
51
- declare class FilterRegistry<TFilters> {
52
- private readonly defs;
53
- add<TValue = unknown>(def: FilterDefinition<TFilters, TValue>): this;
54
- remove(key: string): this;
55
- replace<TValue = unknown>(key: string, def: FilterDefinition<TFilters, TValue>): this;
56
- reorder(keys: string[]): this;
57
- list(): FilterDefinition<TFilters>[];
58
- has(key: string): boolean;
59
- toFilters(values: Record<string, unknown>): TFilters;
60
- activeKeys(filters: TFilters): string[];
61
- }
62
-
63
- interface IListingCardProps {
64
- item: unknown;
65
- selected?: boolean;
66
- onSelect?: () => void;
67
- }
68
- interface IListingMarkerProps {
69
- point: MapPoint<unknown>;
70
- }
71
- interface IListingPopupProps {
72
- entity: unknown;
73
- onClose?: () => void;
74
- }
75
- interface IListingSidebarProps {
76
- children?: ReactNode;
77
- }
78
- interface IListingFilterPanelProps {
79
- children?: ReactNode;
80
- }
81
- interface IListingSearchProps {
82
- value: string;
83
- onChange(value: string): void;
84
- placeholder?: string;
85
- }
86
- interface IListingEmptyProps {
87
- }
88
- interface IListingLoadingProps {
89
- }
90
- interface IListingResultHeaderProps {
91
- count: number;
92
- total?: number;
93
- }
94
- interface IListingToolbarProps {
95
- children?: ReactNode;
96
- }
97
- interface IListingComponents {
98
- Card: ComponentType<IListingCardProps>;
99
- Marker: ComponentType<IListingMarkerProps>;
100
- Popup: ComponentType<IListingPopupProps>;
101
- Sidebar: ComponentType<IListingSidebarProps>;
102
- FilterPanel: ComponentType<IListingFilterPanelProps>;
103
- Search: ComponentType<IListingSearchProps>;
104
- Empty: ComponentType<IListingEmptyProps>;
105
- Loading: ComponentType<IListingLoadingProps>;
106
- ResultHeader: ComponentType<IListingResultHeaderProps>;
107
- Toolbar: ComponentType<IListingToolbarProps>;
108
- }
109
- /**
110
- * Injection point for custom-component overrides. Every slot is optional —
111
- * anything not provided falls back to the (unstyled) default. Mirrors
112
- * `react-wizard-engine`'s `WizardComponentsProvider`: explicit per-slot
113
- * `provided ?? defaults.X` merge, not a generic/reflective loop.
114
- */
115
- declare function ListingComponentsProvider(props: Partial<IListingComponents> & {
116
- children: ReactNode;
117
- }): react.JSX.Element;
118
- declare function useListingComponents(): IListingComponents;
119
-
120
- export { type ClusterOptions as C, type DatasetDefinition as D, FilterRegistry as F, type IListingToolbarProps as I, ListingComponentsProvider as L, type MarkerRenderer as M, type FilterControlProps as a, type FilterDefinition as b, type IListingCardProps as c, type IListingComponents as d, type IListingEmptyProps as e, type IListingFilterPanelProps as f, type IListingLoadingProps as g, type IListingMarkerProps as h, type IListingPopupProps as i, type IListingResultHeaderProps as j, type IListingSearchProps as k, type IListingSidebarProps as l, useListingComponents as u };
@@ -1,120 +0,0 @@
1
- import { a as EntityAdapter, M as MapPoint } from './entity-adapter.interface-BDgbSxhq.js';
2
- import * as react from 'react';
3
- import { ComponentType, ReactNode } from 'react';
4
-
5
- interface FilterControlProps<TValue> {
6
- value: TValue;
7
- onChange(next: TValue): void;
8
- }
9
- interface FilterDefinition<TFilters, TValue = unknown> {
10
- key: string;
11
- order: number;
12
- render: string | ComponentType<FilterControlProps<TValue>>;
13
- toParams(value: TValue): Partial<TFilters>;
14
- fromParams(filters: TFilters): TValue;
15
- isActive?(filters: TFilters): boolean;
16
- /** Optional human-readable label rendered above the control by `ListingFilters`. Omit for an unlabeled filter (backward compatible). */
17
- label?: string;
18
- }
19
-
20
- interface ClusterOptions {
21
- maxZoom?: number;
22
- radius?: number;
23
- }
24
- interface MarkerRenderer<TEntity> {
25
- iconUrl?(entity: TEntity): string;
26
- element?(entity: TEntity): HTMLElement;
27
- onClick?(entity: TEntity): void;
28
- }
29
- interface DatasetDefinition<TEntity, TFilters> {
30
- id: string;
31
- adapter: EntityAdapter<TEntity, TFilters>;
32
- marker: MarkerRenderer<TEntity>;
33
- clustering?: ClusterOptions | false;
34
- visible?: () => boolean;
35
- }
36
-
37
- /**
38
- * Framework-free registry for `FilterDefinition`s: programmatic add / remove /
39
- * reorder / replace, plus folding raw control values into `TFilters`
40
- * (`toFilters`) and reporting which registered filters currently affect an
41
- * applied `TFilters` (`activeKeys`).
42
- *
43
- * Defs are stored by VALUE (shallow-cloned on `add`/`replace`), never by the
44
- * caller's original reference — `reorder()` rewrites `order` in place on the
45
- * registry's own copy. This is deliberate: the same `FilterDefinition` object
46
- * can legitimately be registered in more than one `FilterRegistry` instance
47
- * (e.g. two listing pages sharing a base filter set), and without cloning,
48
- * one registry's `reorder()` would silently mutate `.order` on the shared
49
- * object and bleed into every other registry (and the caller) holding it.
50
- */
51
- declare class FilterRegistry<TFilters> {
52
- private readonly defs;
53
- add<TValue = unknown>(def: FilterDefinition<TFilters, TValue>): this;
54
- remove(key: string): this;
55
- replace<TValue = unknown>(key: string, def: FilterDefinition<TFilters, TValue>): this;
56
- reorder(keys: string[]): this;
57
- list(): FilterDefinition<TFilters>[];
58
- has(key: string): boolean;
59
- toFilters(values: Record<string, unknown>): TFilters;
60
- activeKeys(filters: TFilters): string[];
61
- }
62
-
63
- interface IListingCardProps {
64
- item: unknown;
65
- selected?: boolean;
66
- onSelect?: () => void;
67
- }
68
- interface IListingMarkerProps {
69
- point: MapPoint<unknown>;
70
- }
71
- interface IListingPopupProps {
72
- entity: unknown;
73
- onClose?: () => void;
74
- }
75
- interface IListingSidebarProps {
76
- children?: ReactNode;
77
- }
78
- interface IListingFilterPanelProps {
79
- children?: ReactNode;
80
- }
81
- interface IListingSearchProps {
82
- value: string;
83
- onChange(value: string): void;
84
- placeholder?: string;
85
- }
86
- interface IListingEmptyProps {
87
- }
88
- interface IListingLoadingProps {
89
- }
90
- interface IListingResultHeaderProps {
91
- count: number;
92
- total?: number;
93
- }
94
- interface IListingToolbarProps {
95
- children?: ReactNode;
96
- }
97
- interface IListingComponents {
98
- Card: ComponentType<IListingCardProps>;
99
- Marker: ComponentType<IListingMarkerProps>;
100
- Popup: ComponentType<IListingPopupProps>;
101
- Sidebar: ComponentType<IListingSidebarProps>;
102
- FilterPanel: ComponentType<IListingFilterPanelProps>;
103
- Search: ComponentType<IListingSearchProps>;
104
- Empty: ComponentType<IListingEmptyProps>;
105
- Loading: ComponentType<IListingLoadingProps>;
106
- ResultHeader: ComponentType<IListingResultHeaderProps>;
107
- Toolbar: ComponentType<IListingToolbarProps>;
108
- }
109
- /**
110
- * Injection point for custom-component overrides. Every slot is optional —
111
- * anything not provided falls back to the (unstyled) default. Mirrors
112
- * `react-wizard-engine`'s `WizardComponentsProvider`: explicit per-slot
113
- * `provided ?? defaults.X` merge, not a generic/reflective loop.
114
- */
115
- declare function ListingComponentsProvider(props: Partial<IListingComponents> & {
116
- children: ReactNode;
117
- }): react.JSX.Element;
118
- declare function useListingComponents(): IListingComponents;
119
-
120
- export { type ClusterOptions as C, type DatasetDefinition as D, FilterRegistry as F, type IListingToolbarProps as I, ListingComponentsProvider as L, type MarkerRenderer as M, type FilterControlProps as a, type FilterDefinition as b, type IListingCardProps as c, type IListingComponents as d, type IListingEmptyProps as e, type IListingFilterPanelProps as f, type IListingLoadingProps as g, type IListingMarkerProps as h, type IListingPopupProps as i, type IListingResultHeaderProps as j, type IListingSearchProps as k, type IListingSidebarProps as l, useListingComponents as u };
@@ -1,33 +0,0 @@
1
- type EntityId = string | number;
2
- interface Bounds {
3
- west: number;
4
- south: number;
5
- east: number;
6
- north: number;
7
- }
8
- interface LatLng {
9
- lat: number;
10
- lng: number;
11
- }
12
- interface PageRequest {
13
- cursor?: string | null;
14
- limit: number;
15
- }
16
- interface Page<T> {
17
- items: T[];
18
- nextCursor: string | null;
19
- total?: number;
20
- }
21
- interface MapPoint<TEntity = unknown> {
22
- id: EntityId;
23
- position: LatLng;
24
- entity: TEntity;
25
- }
26
- type QueryParams = Record<string, string | undefined>;
27
- interface EntityAdapter<TEntity, TFilters> {
28
- list(filters: TFilters, page: PageRequest): Promise<Page<TEntity>>;
29
- getPoints(filters: TFilters, bounds: Bounds): Promise<MapPoint<TEntity>[]>;
30
- getById?(id: EntityId): Promise<TEntity>;
31
- }
32
-
33
- export type { Bounds as B, EntityId as E, LatLng as L, MapPoint as M, Page as P, QueryParams as Q, EntityAdapter as a, PageRequest as b };
@@ -1,33 +0,0 @@
1
- type EntityId = string | number;
2
- interface Bounds {
3
- west: number;
4
- south: number;
5
- east: number;
6
- north: number;
7
- }
8
- interface LatLng {
9
- lat: number;
10
- lng: number;
11
- }
12
- interface PageRequest {
13
- cursor?: string | null;
14
- limit: number;
15
- }
16
- interface Page<T> {
17
- items: T[];
18
- nextCursor: string | null;
19
- total?: number;
20
- }
21
- interface MapPoint<TEntity = unknown> {
22
- id: EntityId;
23
- position: LatLng;
24
- entity: TEntity;
25
- }
26
- type QueryParams = Record<string, string | undefined>;
27
- interface EntityAdapter<TEntity, TFilters> {
28
- list(filters: TFilters, page: PageRequest): Promise<Page<TEntity>>;
29
- getPoints(filters: TFilters, bounds: Bounds): Promise<MapPoint<TEntity>[]>;
30
- getById?(id: EntityId): Promise<TEntity>;
31
- }
32
-
33
- export type { Bounds as B, EntityId as E, LatLng as L, MapPoint as M, Page as P, QueryParams as Q, EntityAdapter as a, PageRequest as b };
@@ -1,12 +0,0 @@
1
- declare enum PaginationMode {
2
- Paged = "paged",
3
- Infinite = "infinite"
4
- }
5
-
6
- interface IListingConfigOptions {
7
- pagination: PaginationMode;
8
- pageSize: number;
9
- debounceMs: number;
10
- }
11
-
12
- export { type IListingConfigOptions as I, PaginationMode as P };
@@ -1,12 +0,0 @@
1
- declare enum PaginationMode {
2
- Paged = "paged",
3
- Infinite = "infinite"
4
- }
5
-
6
- interface IListingConfigOptions {
7
- pagination: PaginationMode;
8
- pageSize: number;
9
- debounceMs: number;
10
- }
11
-
12
- export { type IListingConfigOptions as I, PaginationMode as P };
@@ -1,37 +0,0 @@
1
- import { L as LatLng, B as Bounds } from './entity-adapter.interface-BDgbSxhq.cjs';
2
-
3
- /**
4
- * Providers that need an API key take it via their factory (e.g. `googleProvider({ apiKey })`),
5
- * not per-mount.
6
- */
7
- interface MapInitOptions {
8
- apiKey?: string;
9
- center?: LatLng;
10
- zoom?: number;
11
- }
12
- interface MapHandle {
13
- readonly raw: unknown;
14
- }
15
- interface RenderedLayer {
16
- id: string;
17
- markers: Array<{
18
- id: string | number;
19
- position: LatLng;
20
- iconUrl?: string;
21
- element?: HTMLElement;
22
- }>;
23
- clustering?: {
24
- maxZoom?: number;
25
- } | false;
26
- onMarkerClick?(id: string | number): void;
27
- }
28
- type Unsubscribe = () => void;
29
- interface MapProvider {
30
- mount(el: HTMLElement, opts: MapInitOptions): Promise<MapHandle> | MapHandle;
31
- renderLayer(handle: MapHandle, layer: RenderedLayer): Unsubscribe;
32
- onBoundsChange(handle: MapHandle, cb: (b: Bounds) => void): Unsubscribe;
33
- fitBounds(handle: MapHandle, b: Bounds): void;
34
- destroy(handle: MapHandle): void;
35
- }
36
-
37
- export type { MapProvider as M, RenderedLayer as R, Unsubscribe as U, MapHandle as a, MapInitOptions as b };
@@ -1,37 +0,0 @@
1
- import { L as LatLng, B as Bounds } from './entity-adapter.interface-BDgbSxhq.js';
2
-
3
- /**
4
- * Providers that need an API key take it via their factory (e.g. `googleProvider({ apiKey })`),
5
- * not per-mount.
6
- */
7
- interface MapInitOptions {
8
- apiKey?: string;
9
- center?: LatLng;
10
- zoom?: number;
11
- }
12
- interface MapHandle {
13
- readonly raw: unknown;
14
- }
15
- interface RenderedLayer {
16
- id: string;
17
- markers: Array<{
18
- id: string | number;
19
- position: LatLng;
20
- iconUrl?: string;
21
- element?: HTMLElement;
22
- }>;
23
- clustering?: {
24
- maxZoom?: number;
25
- } | false;
26
- onMarkerClick?(id: string | number): void;
27
- }
28
- type Unsubscribe = () => void;
29
- interface MapProvider {
30
- mount(el: HTMLElement, opts: MapInitOptions): Promise<MapHandle> | MapHandle;
31
- renderLayer(handle: MapHandle, layer: RenderedLayer): Unsubscribe;
32
- onBoundsChange(handle: MapHandle, cb: (b: Bounds) => void): Unsubscribe;
33
- fitBounds(handle: MapHandle, b: Bounds): void;
34
- destroy(handle: MapHandle): void;
35
- }
36
-
37
- export type { MapProvider as M, RenderedLayer as R, Unsubscribe as U, MapHandle as a, MapInitOptions as b };
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
2
- var _chunkCHNUE46Kcjs = require('../../chunk-CHNUE46K.cjs');var _chunkLCQZIWBOcjs = require('../../chunk-LCQZIWBO.cjs');var _chunk2VUHLHHXcjs = require('../../chunk-2VUHLHHX.cjs');var Y=["grocery","shopping","restaurants","schools","hospitals","parks","gyms","cafes"];function _(e,t){let n=e.list;return{id:"businesses",adapter:{list:n?(r,o)=>n(r,o):async()=>({items:[],nextCursor:null}),getPoints:(r,o)=>e.search(r,o).then(s=>s.filter(i=>!_optionalChain([t, 'optionalAccess', _2 => _2.categories])||t.categories.includes(i.category))).then(s=>s.map(i=>({id:i.id,position:i.coordinates,entity:i})))},marker:{iconUrl:r=>_nullishCoalesce(_optionalChain([t, 'optionalAccess', _3 => _3.icons, 'optionalAccess', _4 => _4[r.category]]), () => ("")),onClick:_optionalChain([t, 'optionalAccess', _5 => _5.onClick])},clustering:{maxZoom:15},visible:()=>!0}}var _jsxruntime = require('react/jsx-runtime');function b({value:e,onChange:t}){return _jsxruntime.jsx.call(void 0, "input",{type:"search",value:e,onChange:r=>{t(r.target.value)},"aria-label":"Keyword",placeholder:"Search keyword",className:"h-9 w-full rounded-md border border-border bg-background px-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"})}var _react = require('react');var k=["house","apartment","condo","townhouse","land"],N={house:"House",apartment:"Apartment",condo:"Condo",townhouse:"Townhouse",land:"Land"};function F({value:e,onChange:t}){let[n,r]=_react.useState.call(void 0, !1),o=i=>l=>{t(l.target.checked?[...e,i]:e.filter(c=>c!==i))};return _jsxruntime.jsxs.call(void 0, "details",{open:n,className:"group relative",children:[_jsxruntime.jsxs.call(void 0, "summary",{onClick:i=>{i.preventDefault(),r(l=>!l)},"aria-expanded":n,className:"flex h-9 w-fit cursor-pointer list-none items-center gap-1.5 rounded-md border border-border bg-background px-3 text-sm text-foreground motion-safe:transition-colors hover:bg-foreground/[0.06] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [&::-webkit-details-marker]:hidden",children:["Property type",e.length>0&&_jsxruntime.jsx.call(void 0, "span",{className:"inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-primary px-1 text-xs font-semibold tabular-nums text-primary-foreground",children:e.length}),_jsxruntime.jsx.call(void 0, "svg",{"aria-hidden":"true",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",className:"size-3.5 shrink-0 text-muted-foreground motion-safe:transition-transform group-open:rotate-180",children:_jsxruntime.jsx.call(void 0, "path",{d:"m6 9 6 6 6-6"})})]}),_jsxruntime.jsxs.call(void 0, "fieldset",{className:"absolute z-10 mt-1.5 flex w-48 flex-col gap-1.5 rounded-md border border-border bg-popover p-3 text-popover-foreground shadow-md",children:[_jsxruntime.jsx.call(void 0, "legend",{className:"sr-only",children:"Property type"}),k.map(i=>_jsxruntime.jsxs.call(void 0, "label",{className:"flex items-center gap-2 text-sm",children:[_jsxruntime.jsx.call(void 0, "input",{type:"checkbox",checked:e.includes(i),onChange:o(i),className:"size-4 rounded border-border accent-primary"}),N[i]]},i))]})]})}function R(e){if(e==="")return;let t=Number(e);return Number.isNaN(t)?void 0:t}function y({value:e,onChange:t}){let n=s=>{t({...e,min:R(s.target.value)})},r=s=>{t({...e,max:R(s.target.value)})},o="h-9 w-full rounded-md border border-border bg-background px-2 text-sm tabular-nums text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";return _jsxruntime.jsxs.call(void 0, "div",{className:"flex items-center gap-2",children:[_jsxruntime.jsx.call(void 0, "input",{type:"number",inputMode:"numeric","aria-label":"Minimum",placeholder:"Min",value:_nullishCoalesce(e.min, () => ("")),onChange:n,className:o}),_jsxruntime.jsx.call(void 0, "span",{"aria-hidden":"true",className:"text-muted-foreground",children:"-"}),_jsxruntime.jsx.call(void 0, "input",{type:"number",inputMode:"numeric","aria-label":"Maximum",placeholder:"Max",value:_nullishCoalesce(e.max, () => ("")),onChange:r,className:o})]})}function f(e){return new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(e)}function v(e){return e.length?`${e[0].toUpperCase()}${e.slice(1)}`:e}function J({item:e,selected:t,onSelect:n}){let r=e,o=_chunkLCQZIWBOcjs.a.call(void 0, "flex w-full flex-col overflow-hidden rounded-[10px] border border-border bg-card text-left text-card-foreground","motion-safe:transition-shadow",n&&"hover:shadow-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",t&&"ring-2 ring-ring"),s=_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[_optionalChain([r, 'optionalAccess', _6 => _6.imageUrl])?_jsxruntime.jsx.call(void 0, "img",{src:r.imageUrl,alt:_nullishCoalesce(r.title, () => ("")),className:"aspect-[4/3] w-full rounded-t-[10px] object-cover"}):_jsxruntime.jsx.call(void 0, "div",{className:"aspect-[4/3] w-full rounded-t-[10px] bg-muted","aria-hidden":"true"}),_jsxruntime.jsxs.call(void 0, "div",{className:"flex flex-1 flex-col gap-1 p-3",children:[_optionalChain([r, 'optionalAccess', _7 => _7.title])&&_jsxruntime.jsx.call(void 0, "span",{className:"text-base font-semibold",children:r.title}),_optionalChain([r, 'optionalAccess', _8 => _8.address])&&_jsxruntime.jsx.call(void 0, "span",{className:"text-sm text-muted-foreground",children:r.address}),_optionalChain([r, 'optionalAccess', _9 => _9.propertyType])!=null&&r.bedrooms!=null&&r.bathrooms!=null&&_jsxruntime.jsxs.call(void 0, "span",{className:"text-sm text-muted-foreground",children:[v(r.propertyType)," \xB7 ",r.bedrooms," bd \xB7 ",r.bathrooms," ba"]}),_optionalChain([r, 'optionalAccess', _10 => _10.price])!=null&&_jsxruntime.jsxs.call(void 0, "span",{className:"mt-1 font-bold tabular-nums",children:[f(r.price)," ",_jsxruntime.jsx.call(void 0, "span",{className:"text-sm font-normal text-muted-foreground",children:"/mo"})]})]})]});return n?_jsxruntime.jsx.call(void 0, "button",{type:"button",onClick:n,"aria-pressed":_nullishCoalesce(t, () => (!1)),className:o,children:s}):_jsxruntime.jsx.call(void 0, "article",{className:o,children:s})}function ee({point:e}){let t=e.entity;return _jsxruntime.jsxs.call(void 0, "span",{className:"relative inline-flex items-center whitespace-nowrap rounded-full bg-primary px-2.5 py-1 text-xs font-bold tabular-nums text-primary-foreground shadow",children:[_optionalChain([t, 'optionalAccess', _11 => _11.price])!=null?f(t.price):"",_jsxruntime.jsx.call(void 0, "span",{"aria-hidden":"true",className:"absolute -bottom-[3px] left-1/2 h-2 w-2 -translate-x-1/2 rotate-45 rounded-br-[2px] bg-primary"})]})}function S(e){let t=document.createElement("div");t.className="relative inline-flex items-center whitespace-nowrap rounded-full bg-primary px-2.5 py-1 text-xs font-bold text-primary-foreground shadow",t.textContent=f(e.price),t.style.position="relative",t.style.display="inline-flex",t.style.alignItems="center",t.style.whiteSpace="nowrap",t.style.borderRadius="9999px",t.style.backgroundColor="var(--primary, #16a34a)",t.style.color="var(--primary-foreground, #ffffff)",t.style.padding="4px 10px",t.style.fontSize="12px",t.style.fontWeight="700",t.style.fontFamily="inherit",t.style.boxShadow="0 1px 2px rgba(0, 0, 0, 0.3)";let n=document.createElement("span");return n.className="absolute -bottom-[3px] left-1/2 h-2 w-2 -translate-x-1/2 rotate-45 rounded-br-[2px] bg-primary",n.style.position="absolute",n.style.left="50%",n.style.bottom="-3px",n.style.width="8px",n.style.height="8px",n.style.borderRadius="0 0 2px 0",n.style.backgroundColor="var(--primary, #16a34a)",n.style.transform="translateX(-50%) rotate(45deg)",t.appendChild(n),t}function ie(e,t){let n=e.getById;return{id:"properties",adapter:{list:(r,o)=>e.list(r,o),getPoints:(r,o)=>e.search(r,o).then(s=>s.map(i=>({id:i.id,position:i.coordinates,entity:i}))),getById:n?r=>n(r):void 0},marker:{iconUrl:_optionalChain([t, 'optionalAccess', _12 => _12.iconUrl]),element:_nullishCoalesce(_optionalChain([t, 'optionalAccess', _13 => _13.element]), () => (S)),onClick:_optionalChain([t, 'optionalAccess', _14 => _14.onClick])},clustering:{maxZoom:14}}}var D={key:"price",order:10,label:"Price",render:y,toParams:e=>({minPrice:e.min,maxPrice:e.max}),fromParams:e=>({min:e.minPrice,max:e.maxPrice}),isActive:e=>e.minPrice!=null||e.maxPrice!=null},I={key:"beds",order:20,label:"Bedrooms",render:y,toParams:e=>({minBeds:e.min,maxBeds:e.max}),fromParams:e=>({min:e.minBeds,max:e.maxBeds}),isActive:e=>e.minBeds!=null||e.maxBeds!=null},M={key:"baths",order:30,label:"Bathrooms",render:y,toParams:e=>({minBaths:e.min,maxBaths:e.max}),fromParams:e=>({min:e.minBaths,max:e.maxBaths}),isActive:e=>e.minBaths!=null||e.maxBaths!=null},L={key:"propertyType",order:40,label:"Property type",render:F,toParams:e=>({propertyTypes:e.length?e:void 0}),fromParams:e=>_nullishCoalesce(e.propertyTypes, () => ([])),isActive:e=>(_nullishCoalesce(_optionalChain([e, 'access', _15 => _15.propertyTypes, 'optionalAccess', _16 => _16.length]), () => (0)))>0},O={key:"keyword",order:50,label:"Keyword",render:b,toParams:e=>({keyword:e||void 0}),fromParams:e=>_nullishCoalesce(e.keyword, () => ("")),isActive:e=>!!e.keyword},U= exports.rentalFilters =[D,I,M,L,O];function pe(){return e=>{U.forEach(t=>e.add(t))}}var A=["house","apartment","condo","townhouse","land"];function V(e){return A.includes(e)}function p(e){if(e===void 0||e==="")return;let t=Number(e);return Number.isNaN(t)?void 0:t}function H(e){let t={};return e.minPrice!=null&&(t.minPrice=String(e.minPrice)),e.maxPrice!=null&&(t.maxPrice=String(e.maxPrice)),e.minBeds!=null&&(t.minBeds=String(e.minBeds)),e.maxBeds!=null&&(t.maxBeds=String(e.maxBeds)),e.minBaths!=null&&(t.minBaths=String(e.minBaths)),e.maxBaths!=null&&(t.maxBaths=String(e.maxBaths)),_optionalChain([e, 'access', _17 => _17.propertyTypes, 'optionalAccess', _18 => _18.length])&&(t.type=e.propertyTypes.join(",")),e.keyword&&(t.q=e.keyword),t}function Q(e){let t={},n=p(e.minPrice);n!==void 0&&(t.minPrice=n);let r=p(e.maxPrice);r!==void 0&&(t.maxPrice=r);let o=p(e.minBeds);o!==void 0&&(t.minBeds=o);let s=p(e.maxBeds);s!==void 0&&(t.maxBeds=s);let i=p(e.minBaths);i!==void 0&&(t.minBaths=i);let l=p(e.maxBaths);l!==void 0&&(t.maxBaths=l);let c=_optionalChain([e, 'access', _19 => _19.type, 'optionalAccess', _20 => _20.split, 'call', _21 => _21(","), 'access', _22 => _22.map, 'call', _23 => _23(B=>B.trim()), 'access', _24 => _24.filter, 'call', _25 => _25(V)]);return _optionalChain([c, 'optionalAccess', _26 => _26.length])&&(t.propertyTypes=c),e.q&&(t.keyword=e.q),t}function ue(e={}){let t=_nullishCoalesce(e.history, () => (new (0, _chunkCHNUE46Kcjs.a)({mode:e.mode})));return new (0, _chunk2VUHLHHXcjs.a)({history:t,toQuery:H,toFilters:Q,hydrateOnStart:e.hydrateOnStart})}exports.KNOWN_BUSINESS_CATEGORIES = Y; exports.KeywordFilterControl = b; exports.PropertyCard = J; exports.PropertyMarker = ee; exports.PropertyTypeFilterControl = F; exports.RangeFilterControl = y; exports.defaultPriceMarkerElement = S; exports.formatRentalPrice = f; exports.nearbyBusinessesDataset = _; exports.propertiesDataset = ie; exports.rentalFilters = U; exports.rentalFiltersFromQuery = Q; exports.rentalFiltersToQuery = H; exports.rentalUrlSync = ue; exports.withRentalFilters = pe;