react-listing-engine 0.10.0 → 0.12.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # react-listing-engine
2
2
 
3
+ ## 0.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Server rendering: the app can now render real results to HTML, and hydrate them in place.
8
+
9
+ Three things stood in the way, and all three are fixed.
10
+
11
+ `ListingProvider` built its engine in a `useEffect` and returned `null` until that ran, which made every consumer client-only by construction -- on a server there are no effects, so the whole tree rendered to nothing. The engine is now constructed during render; the constructor is pure (store, registries, config, no browser API), and everything with a side effect still happens in the effect.
12
+
13
+ `ListingApp` returned `null` until an API-key `map` prop resolved to a provider through a dynamic import. It now renders without waiting: `ListingMap` already tolerates a missing provider, and because the resolution state starts `false` on both the server and the client's first render, the markup matches and hydration has nothing to reconcile. `hasMap` is derived from the PROP rather than from whether the provider resolved -- otherwise the layout renders list-only and switches to split mid-load, which is both a reflow and a hydration mismatch.
14
+
15
+ New `initialResults` on `ListingApp` (and `withInitialResults` for hand-composed providers) seeds the first page, so the first render already has rows instead of blanking while an adapter call goes out -- an adapter call being something a server render cannot do. `autoFetch` now defaults to off when results are seeded, so the identical page is not refetched a moment later.
16
+
17
+ Two changes worth checking before upgrading:
18
+
19
+ `ListingEngine` gains `isDisposed`, and `ListingProvider` uses it to replace an engine that React Strict Mode has already torn down. Because the engine now outlives the effect, Strict Mode's mount/cleanup/mount would otherwise leave a disposed engine -- emitter dead -- in context.
20
+
21
+ `ListingStoreInit` is now generic over `<TEntity, TFilters>` rather than `<TFilters>`, so it can describe the seeded page. This is a type-only break, and only for code that names that type directly.
22
+
23
+ ## 0.11.0
24
+
25
+ ### Minor Changes
26
+
27
+ - Add a `resultsSlot` prop to `ListingApp` (and the underlying `StyledListingLayout`): when set, it replaces the ENTIRE results column -- the header, the grid and the pagination -- with the given content, inside the same scrolling `.rle-list` container. It is for the states where a result list is the wrong thing to show at all rather than a different-looking one: a viewport too wide for individual results to mean anything, an onboarding prompt, a saved-search upsell. The existing `Empty` and `Loading` component slots cannot express those, because both still render inside the results column and leave its header, sort control and pager standing. Without it, consumers had to hide `.rle-list-grid`, `.rle-list-header__toolbar` and `.rle-pagination` with their own CSS, which made three internal class names part of the public contract by accident. The map is unaffected -- give a dataset an empty `getPoints` at that scale if its pins should go too. Fully backward-compatible: omit it and the ordinary results column renders as before.
28
+
3
29
  ## 0.10.0
4
30
 
5
31
  ### Minor Changes
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ var ee=class{state;listeners=new Set;constructor(e){this.state=this.freezeState({filters:{...e.filters},results:e.results?{items:[...e.results.items],nextCursor:e.results.nextCursor,total:e.results.total}:{items:[],nextCursor:null},bounds:null,selection:null,hovered:null,pagination:{mode:e.mode??"paged",loading:!1,pageIndex:0},layers:{},points:{}})}getState(){return this.state}setFilters(e){this.setState({filters:{...this.state.filters,...e}})}setResults(e){this.setState({results:{items:[...e.items],nextCursor:e.nextCursor,total:e.total}})}appendResults(e){this.setState({results:{items:[...this.state.results.items,...e.items],nextCursor:e.nextCursor,total:e.total}})}setBounds(e){this.setState({bounds:e?{...e}:null})}setSelection(e){this.setState({selection:e})}setHovered(e){this.setState({hovered:e})}setLayerVisible(e,i){this.setState({layers:{...this.state.layers,[e]:i}})}setLoading(e){this.setState({pagination:{...this.state.pagination,loading:e}})}setPageIndex(e){this.setState({pagination:{...this.state.pagination,pageIndex:e}})}setPoints(e,i){this.setState({points:{...this.state.points,[e]:[...i]}})}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}setState(e){this.state=this.freezeState({...this.state,...e}),this.notify()}notify(){for(let e of this.listeners)e()}freezeState(e){Object.freeze(e.filters),Object.freeze(e.results.items),Object.freeze(e.results),e.bounds&&Object.freeze(e.bounds),Object.freeze(e.pagination),Object.freeze(e.layers);for(let i of Object.values(e.points))Object.freeze(i);return Object.freeze(e.points),Object.freeze(e)}};var $=class{defs=new Map;add(e){if(this.defs.has(e.key))throw new Error(`FilterRegistry: filter "${e.key}" is already registered`);return this.defs.set(e.key,{...e}),this}remove(e){return this.defs.delete(e),this}replace(e,i){if(!this.defs.has(e))throw new Error(`FilterRegistry: cannot replace unregistered filter "${e}"`);return this.defs.set(e,{...i,key:e}),this}reorder(e){let i=this.list(),n=e.filter(s=>this.defs.has(s));n.forEach((s,o)=>{this.defs.get(s).order=o});let r=new Set(n);return i.filter(s=>!r.has(s.key)).forEach((s,o)=>{s.order=n.length+o}),this}list(){return[...this.defs.values()].sort((e,i)=>e.order-i.order)}has(e){return this.defs.has(e)}toFilters(e){return this.list().filter(n=>Object.hasOwn(e,n.key)).map(n=>n.toParams(e[n.key])).reduce((n,r)=>({...n,...r}),{})}activeKeys(e){return this.list().filter(i=>i.isActive?.(e)).map(i=>i.key)}clearedParams(){return this.list().reduce((e,i)=>Object.assign(e,i.toParams(i.fromParams({}))),{})}};var te=class{defs=new Map;add(e){if(this.defs.has(e.id))throw new Error(`DatasetRegistry: dataset "${e.id}" is already registered`);return this.defs.set(e.id,{...e}),this}get(e){return this.defs.get(e)}has(e){return this.defs.has(e)}list(){return[...this.defs.values()]}visibleIds(){return this.list().filter(e=>e.visible?.()!==!1).map(e=>e.id)}};var ie=class{map=new Map;dispose(){this.map.clear()}emit(e){let i=this.map.get(e.type);if(i)for(let r of[...i])r(e);let n=this.map.get("*");if(n)for(let r of[...n])r(e)}on(e,i){let n=this.map.get(e);return n||(n=new Set,this.map.set(e,n)),n.add(i),()=>{n.delete(i)}}};var He={pagination:"paged",pageSize:20,debounceMs:250};var ne=class{options;constructor(e){this.options=Object.freeze({...He,...e})}};var re=class{filters;map;datasets;primaryDatasetId;store;disposed=!1;emitter=new ie;config;debounceTimer=null;debounceResolve=null;queryToken=0;pointsToken=0;mapHandle=null;constructor(e){this.datasets=e.datasets,this.filters=e.filters??new $,this.map=e.map,this.config=new ne(e.config);let i=e.primaryDatasetId??this.datasets.list()[0]?.id;if(i==null||!this.datasets.has(i))throw new Error(`ListingEngine: primary dataset "${i??""}" is not registered \u2014 pass a valid primaryDatasetId or register at least one dataset`);this.primaryDatasetId=i,this.store=new ee({filters:e.initialFilters??{},mode:this.config.options.pagination,results:e.initialResults})}get state(){return this.store.getState()}get options(){return this.config.options}applyFilters(e){this.store.setFilters(e),this.emitter.emit({type:"FiltersChanged",filters:this.currentFilters()}),this.clearDebounce();let i=++this.queryToken,n=this.config.options.debounceMs;return n<=0?this.runQuery(i):new Promise(r=>{this.debounceResolve=r,this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.debounceResolve=null,r(this.runQuery(i))},n)})}async loadPage(){let e=this.state.results.nextCursor;if(e===null)return;let i=++this.queryToken,n=this.primaryDataset();this.store.setLoading(!0);try{let r=await n.adapter.list(this.currentFilters(),{cursor:e,limit:this.config.options.pageSize});if(i!==this.queryToken)return;this.config.options.pagination==="infinite"?this.store.appendResults(r):this.store.setResults(r),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:r.items.length})}finally{i===this.queryToken&&this.store.setLoading(!1)}}async goToPage(e){if(e<0)return;let i=++this.queryToken,n=this.primaryDataset();this.store.setLoading(!0);try{let r=await n.adapter.list(this.currentFilters(),{offset:e*this.config.options.pageSize,limit:this.config.options.pageSize});if(i!==this.queryToken)return;this.store.setResults(r),this.store.setPageIndex(e),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:r.items.length})}finally{i===this.queryToken&&this.store.setLoading(!1)}}async loadPoints(e){this.store.setBounds(e),this.emitter.emit({type:"BoundsChanged",bounds:e});let i=this.currentFilters(),n=++this.pointsToken;await Promise.allSettled(this.datasets.visibleIds().map(async r=>{let s=this.datasets.get(r);if(!s)return;let o=await s.adapter.getPoints(i,e);n===this.pointsToken&&this.store.setPoints(r,o)}))}setMapHandle(e){this.mapHandle=e}fitBounds(e,i){!this.map||!this.mapHandle||this.map.fitBounds(this.mapHandle,e,i)}selectPoint(e,i){this.store.setSelection(i);let n=this.state.points[e]?.find(r=>r.id===i);n&&this.emitter.emit({type:"PointClicked",datasetId:e,id:n.id,entity:n.entity})}setHovered(e,i){this.store.setHovered(i)}toggleLayer(e){let n=!(this.state.layers[e]??!0);this.store.setLayerVisible(e,n),this.emitter.emit({type:"LayerToggled",datasetId:e,visible:n})}subscribe(e){return this.store.subscribe(e)}on(e,i){return this.emitter.on(e,i)}get isDisposed(){return this.disposed}dispose(){this.clearDebounce(),this.emitter.dispose(),this.mapHandle=null,this.disposed=!0}async runQuery(e){if(e!==this.queryToken)return;let i=this.primaryDataset();this.store.setLoading(!0);try{let n=await i.adapter.list(this.currentFilters(),{cursor:null,limit:this.config.options.pageSize});if(e!==this.queryToken)return;this.store.setResults(n),this.store.setPageIndex(0),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:n.items.length})}finally{e===this.queryToken&&this.store.setLoading(!1)}}primaryDataset(){return this.datasets.get(this.primaryDatasetId)}currentFilters(){return this.store.getState().filters}clearDebounce(){this.debounceTimer!==null&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.debounceResolve!==null&&(this.debounceResolve(),this.debounceResolve=null)}};function ze(...t){let e={config:{},filters:new $,datasets:new te};for(let i of t)i(e);return e}var Ue=t=>e=>{e.config={...e.config,...t}},Ke=t=>e=>{e.map=t},Ve=t=>e=>{e.datasets.add(t)},qe=t=>e=>{t(e.filters)},Hi=t=>e=>{e.urlSync=t},$e=t=>e=>{e.initialFilters=t},We=t=>e=>{e.initialResults=t},zi=t=>e=>{e.primaryDatasetId=t};import{createContext as Ft,useContext as kt}from"react";import{jsx as S,jsxs as Qe}from"react/jsx-runtime";function wt(t){return String(t?.title??"")}var St=({item:t})=>S("div",{children:wt(t)}),Ct=()=>S("div",{}),fe=()=>S("div",{}),It=({children:t})=>S("div",{children:t}),Et=({children:t})=>S("div",{children:t}),xt=({value:t,onChange:e,placeholder:i})=>S("input",{type:"search",value:t,placeholder:i,onChange:n=>e(n.target.value),"aria-label":i??"Search"}),Rt=()=>S("div",{role:"status",children:"No results"}),Nt=()=>S("div",{role:"status","aria-busy":"true",children:"Loading\u2026"}),Mt=({count:t})=>Qe("div",{children:[t," results"]}),Dt=({children:t})=>S("div",{children:t}),Bt=({view:t,onViewChange:e})=>Qe("nav",{"aria-label":"Listing navigation",children:[S("button",{type:"button","aria-pressed":t==="list",onClick:()=>e("list"),children:"List"}),S("button",{type:"button","aria-pressed":t==="map",onClick:()=>e("map"),children:"Map"})]}),w={BottomNav:Bt,Card:St,Marker:Ct,Popup:fe,Sidebar:It,FilterPanel:Et,Search:xt,Empty:Rt,Loading:Nt,ResultHeader:Mt,Toolbar:Dt},je=Ft(w);function Ge(t){let{BottomNav:e,Card:i,Marker:n,Popup:r,Sidebar:s,FilterPanel:o,Search:a,Empty:l,Loading:p,ResultHeader:d,Toolbar:m,children:y}=t,x={BottomNav:e??w.BottomNav,Card:i??w.Card,Marker:n??w.Marker,Popup:r??w.Popup,Sidebar:s??w.Sidebar,FilterPanel:o??w.FilterPanel,Search:a??w.Search,Empty:l??w.Empty,Loading:p??w.Loading,ResultHeader:d??w.ResultHeader,Toolbar:m??w.Toolbar};return S(je.Provider,{value:x,children:y})}function C(){return kt(je)}import{createContext as Ot}from"react";var se=Ot(null);import{useContext as _t}from"react";function v(){let t=_t(se);if(t===null)throw new Error("useListing must be used within a <ListingProvider>");return t}import{useCallback as Ze,useSyncExternalStore as At}from"react";function I(){let t=v(),e=Ze(n=>t.subscribe(n),[t]),i=Ze(()=>t.state,[t]);return At(e,i,i)}import{useCallback as Xe}from"react";function oe(){let t=v(),e=I(),i=Xe(r=>t.applyFilters(r),[t]),n=Xe((r,s)=>t.applyFilters({[r]:s}),[t]);return{filters:e.filters,set:i,setField:n}}import{jsx as Z,jsxs as Ht}from"react/jsx-runtime";function ye({className:t,groupClassName:e,hideLabels:i,draft:n,onDraftChange:r}={}){let s=v(),{FilterPanel:o}=C(),{filters:a}=oe(),l=n!==void 0&&r!==void 0,p=l?n:a;return Z(o,{children:Z("div",{className:t??"space-y-5",children:s.filters.list().map(d=>{if(typeof d.render=="string")return Z("div",{"data-filter":d.key,className:e},d.key);let m=d.render;return Ht("div",{className:e,children:[d.label&&!i&&Z("div",{className:"mb-1.5 text-[13px] font-medium text-foreground",children:d.label}),Z(m,{value:d.fromParams(p),onChange:y=>l?r(d.toParams(y)):void s.applyFilters(d.toParams(y))})]},d.key)})})})}function W(){return I().results}import{jsx as ae}from"react/jsx-runtime";function zt(t,e){if(t&&typeof t=="object"&&"id"in t){let i=t.id;if(typeof i=="string"||typeof i=="number")return i}return e}function Je({className:t}={}){let e=v(),{items:i}=W(),{pagination:n,selection:r}=I(),{Card:s,Empty:o,Loading:a}=C();return n.loading&&i.length===0?ae(a,{}):i.length===0?ae(o,{}):ae("div",{role:"list",className:t,children:i.map((l,p)=>{let d=zt(l,p);return ae(s,{item:l,selected:r===d,onSelect:()=>e.selectPoint(e.primaryDatasetId,d)},d)})})}import{useEffect as X,useRef as H,useState as Ye}from"react";import{createPortal as Ut}from"react-dom";import{jsx as he,jsxs as it}from"react/jsx-runtime";var Kt={west:-179.9,south:-85,east:179.9,north:85},et=.1,tt=.02;function Vt(t){if(t.length===0)return null;let e=t[0].lng,i=t[0].lng,n=t[0].lat,r=t[0].lat;for(let{lat:a,lng:l}of t)l<e&&(e=l),l>i&&(i=l),a<n&&(n=a),a>r&&(r=a);let s=r>n?(r-n)*et:tt,o=i>e?(i-e)*et:tt;return{west:e-o,east:i+o,south:n-s,north:r+s}}function nt(t){let{center:e,zoom:i,fallback:n,mapControls:r,onMapReady:s}=t,o=v(),a=I(),l=H(s);l.current=s;let p=H(null),d=H(null),m=H(null),[y,x]=Ye(!1),F=H(!1),V=H(!1),O=H(!1),u=o.map;X(()=>{let h=m.current;if(!u||!h)return;let b=[];for(let g of Object.keys(a.points)){if(a.layers[g]===!1)continue;let f=o.datasets.get(g),k=a.points[g]??[],A={id:g,markers:k.map(R=>({id:R.id,position:R.position,iconUrl:f?.marker.iconUrl?.(R.entity),element:f?.marker.element?.(R.entity)})),clustering:f?.clustering,onMarkerClick:R=>o.selectPoint(g,R)};b.push(u.renderLayer(h,A))}return()=>{b.forEach(g=>g())}},[o,u,y,a.points,a.layers]),X(()=>{if(!p.current||!u)return;let h=p.current,b=!1,g=null;return(async()=>{let f=await u.mount(h,{center:e,zoom:i,fullscreenTarget:d.current??void 0});if(b){u.destroy(f);return}m.current=f,o.setMapHandle(f),g=u.onBoundsChange(f,k=>{O.current?O.current=!1:V.current=!0,o.loadPoints(k)}),x(!0),l.current?.(f.nativeMap??f.raw),o.loadPoints(Kt)})(),()=>{b=!0,g?.(),m.current&&(u.destroy(m.current),m.current=null,o.setMapHandle(null),l.current?.(null)),x(!1)}},[o,u]),X(()=>{let h=m.current;if(!u||!h||e||F.current||V.current)return;let b=[];for(let f of Object.keys(a.points))if(a.layers[f]!==!1)for(let k of a.points[f]??[])b.push(k.position);let g=Vt(b);g&&(F.current=!0,O.current=!0,u.fitBounds(h,g))},[u,e,y,a.points,a.layers]),X(()=>{u?.updateMarkerStates(a.selection,a.hovered)},[u,y,a.selection,a.hovered]);let{Popup:N}=C(),z=N!==fe,T=a.points[o.primaryDatasetId]??[],P=a.selection!=null?T.find(h=>h.id===a.selection):void 0,[_,q]=Ye(null),M=H(P);return M.current=P,X(()=>{let h=m.current;if(!u||!h||!z)return;let b=M.current;if(!b)return;let g=u.mountOverlay(b.position);q({entity:b.entity,position:b.position,container:g.container});let f=()=>o.selectPoint(o.primaryDatasetId,null),k=R=>{R.key==="Escape"&&f()};document.addEventListener("keydown",k);let A=u.onMapClick(f);return()=>{document.removeEventListener("keydown",k),A(),g.unmount(),q(null)}},[o,u,y,a.selection,z]),it("div",{ref:d,className:"relative h-full min-h-0 w-full",children:[it("div",{ref:p,className:!u&&n?"flex h-full min-h-0 w-full items-center justify-center":"h-full min-h-0 w-full",children:[!u&&n,z&&_?Ut(he(N,{entity:_.entity,onClose:()=>o.selectPoint(o.primaryDatasetId,null)}),_.container):null]}),r!=null&&he("div",{className:"pointer-events-none absolute inset-0",children:he("div",{className:"pointer-events-auto",children:r})})]})}import{jsx as J,jsxs as $t}from"react/jsx-runtime";var ve="gap";function qt(t,e){if(t<=7)return Array.from({length:t},(s,o)=>o+1);let i=Math.max(2,e-1),n=Math.min(t-1,e+1),r=[1];i>2&&r.push(ve);for(let s=i;s<=n;s+=1)r.push(s);return n<t-1&&r.push(ve),r.push(t),r}function rt(){let t=v(),{results:e,pagination:i}=I();if(i.mode==="infinite")return e.nextCursor==null?null:J("button",{type:"button",disabled:i.loading,onClick:()=>{t.loadPage()},children:"Load more"});let n=t.options.pageSize,{pageIndex:r}=i,s=r+1,o=e.total!=null?Math.ceil(e.total/n):null,a=o!=null?s<o:e.nextCursor!=null||e.items.length>=n;if(o!=null?o<=1:r===0&&!a)return null;let l=p=>()=>{t.goToPage(p)};return $t("nav",{className:"rle-pagination","aria-label":"Pagination",children:[J("button",{type:"button",className:"rle-page-btn rle-page-btn--nav","aria-label":"Previous page",disabled:i.loading||r===0,onClick:l(r-1),children:"\u2039"}),o!=null&&qt(o,s).map((p,d)=>p===ve?J("span",{className:"rle-page-ellipsis",children:"\u2026"},`gap-${d}`):J("button",{type:"button",className:p===s?"rle-page-btn rle-page-btn--active":"rle-page-btn","aria-label":`Page ${p}`,"aria-current":p===s?"page":void 0,disabled:i.loading,onClick:l(p-1),children:p},p)),J("button",{type:"button",className:"rle-page-btn rle-page-btn--nav","aria-label":"Next page",disabled:i.loading||!a,onClick:l(r+1),children:"\u203A"})]})}import{jsx as Wt}from"react/jsx-runtime";function st(){let{items:t,total:e}=W(),{ResultHeader:i}=C();return Wt(i,{count:t.length,total:e})}import{useEffect as jt,useRef as Gt}from"react";function ot(t,e){let i=v(),n=Gt(e);n.current=e,jt(()=>i.on(t,r=>n.current(r)),[i,t])}import{useCallback as Qt,useEffect as Zt,useRef as Xt,useState as at}from"react";import{jsx as Jt}from"react/jsx-runtime";function lt(t){let{children:e,...i}=t,[n]=at(()=>i),r=Qt(()=>new re({datasets:n.datasets,filters:n.filters,config:n.config,map:n.map,initialFilters:n.initialFilters,initialResults:n.initialResults,primaryDatasetId:n.primaryDatasetId}),[n]),[s,o]=at(r),a=Xt(s);return a.current=s,Zt(()=>{let l=a.current;return l.isDisposed&&(l=r(),a.current=l,o(l)),n.urlSync&&n.urlSync.start(l),()=>{n.urlSync&&n.urlSync.stop(),l.dispose()}},[n,r]),Jt(se.Provider,{value:s,children:e})}import{jsx as E,jsxs as Y}from"react/jsx-runtime";function dt({view:t,onViewChange:e}){return E("nav",{className:"rle-bottom-nav","aria-label":"Listing navigation",children:Y("div",{className:"rle-viewtoggle",role:"group","aria-label":"View",children:[Y("button",{type:"button",className:`rle-viewtoggle__btn${t==="list"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":t==="list",onClick:()=>e("list"),children:[E(Yt,{}),"List"]}),Y("button",{type:"button",className:`rle-viewtoggle__btn${t==="map"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":t==="map",onClick:()=>e("map"),children:[E(ei,{}),"Map"]})]})})}function Yt(){return Y("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[E("line",{x1:"8",y1:"6",x2:"20",y2:"6"}),E("line",{x1:"8",y1:"12",x2:"20",y2:"12"}),E("line",{x1:"8",y1:"18",x2:"20",y2:"18"}),E("line",{x1:"4",y1:"6",x2:"4.01",y2:"6"}),E("line",{x1:"4",y1:"12",x2:"4.01",y2:"12"}),E("line",{x1:"4",y1:"18",x2:"4.01",y2:"18"})]})}function ei(){return Y("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[E("polygon",{points:"1 6 8 3 16 6 23 3 23 18 16 21 8 18 1 21 1 6"}),E("line",{x1:"8",y1:"3",x2:"8",y2:"18"}),E("line",{x1:"16",y1:"6",x2:"16",y2:"21"})]})}function j(t){return typeof t!="number"?t:new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(t)}import{Fragment as ii,jsx as D,jsxs as pt}from"react/jsx-runtime";function ti(t){return t?"rle-card rle-card--selected":"rle-card"}function be({item:t,selected:e,onSelect:i}){let n=t??{},r=ti(e),s=pt(ii,{children:[n.imageUrl?D("img",{src:n.imageUrl,alt:n.title??"",className:"rle-card-media"}):D("div",{className:"rle-card-media rle-card-media--placeholder","aria-hidden":"true"}),pt("div",{className:"rle-card-body",children:[n.title&&D("span",{className:"rle-card-title",children:n.title}),n.subtitle&&D("span",{className:"rle-card-address",children:n.subtitle}),n.badge&&D("div",{className:"rle-card-info",children:D("span",{className:"rle-card-info-item",children:n.badge})}),n.price!=null&&D("span",{className:"rle-card-price",children:j(n.price)})]})]});return i?D("button",{type:"button",onClick:i,"aria-pressed":e??!1,className:r,children:s}):D("article",{className:r,children:s})}import{jsx as le,jsxs as ut}from"react/jsx-runtime";function Le(t){return ut("div",{role:"status",className:"rle-empty",children:[ut("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",className:"rle-empty-icon","aria-hidden":"true",children:[le("circle",{cx:"11",cy:"11",r:"7"}),le("path",{d:"m21 21-4.3-4.3"})]}),le("p",{className:"rle-empty-title",children:"No results"}),le("p",{className:"rle-empty-hint",children:"Try adjusting your filters or search terms."})]})}import{jsx as ni}from"react/jsx-runtime";function Pe({children:t}){return ni("div",{className:"rle-filter-panel",children:t})}import{jsx as de,jsxs as ri}from"react/jsx-runtime";function Te(t){return de("div",{className:"rle-loading",role:"status","aria-busy":"true","aria-label":"Loading results",children:Array.from({length:3}).map((e,i)=>ri("div",{className:"rle-loading-item",children:[de("div",{className:"rle-skeleton",style:{aspectRatio:"4 / 3",width:"100%"}}),de("div",{className:"rle-skeleton",style:{height:16,width:"65%"}}),de("div",{className:"rle-skeleton",style:{height:12,width:"35%"}})]},i))})}import{jsx as si}from"react/jsx-runtime";function Fe({point:t}){let e=t.entity??{};return si("span",{className:"rle-pin",children:e.price!=null?j(e.price):""})}import{jsx as G,jsxs as ke}from"react/jsx-runtime";function we({entity:t,onClose:e}){let i=t??{};return ke("div",{className:"rle-popup",role:"group","aria-label":"Location details",children:[G("button",{type:"button",onClick:e,"aria-label":"Close",className:"rle-popup-close",children:ke("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[G("path",{d:"M18 6 6 18"}),G("path",{d:"m6 6 12 12"})]})}),ke("div",{children:[i.title&&G("div",{className:"rle-card-title",children:i.title}),i.subtitle&&G("div",{className:"rle-card-address",children:i.subtitle}),i.price!=null&&G("div",{className:"rle-card-price",children:j(i.price)})]})]})}import{jsx as oi}from"react/jsx-runtime";function Se({count:t,total:e}){let i=e!=null&&e!==t?`${t} of ${e} results`:`${t} results`;return oi("div",{className:"rle-result-header",children:i})}import{jsx as ai}from"react/jsx-runtime";function Ce({value:t,onChange:e,placeholder:i}){return ai("input",{type:"search",value:t,placeholder:i,onChange:n=>e(n.target.value),"aria-label":i??"Search",className:"rle-input"})}import{jsx as li}from"react/jsx-runtime";function Ie({children:t}){return li("aside",{className:"rle-sidebar",children:t})}import{jsx as di}from"react/jsx-runtime";function Ee({children:t}){return di("div",{className:"rle-toolbar",children:t})}var ct={BottomNav:dt,Card:be,Marker:Fe,Popup:we,Sidebar:Ie,FilterPanel:Pe,Search:Ce,Empty:Le,Loading:Te,ResultHeader:Se,Toolbar:Ee};import{useEffect as xe,useRef as pi,useState as mt}from"react";import{createPortal as ui}from"react-dom";import{Fragment as mi,jsx as B,jsxs as pe}from"react/jsx-runtime";function gt({open:t,onOpenChange:e,title:i,children:n,footer:r}){let s=pi(null),[o,a]=mt(!1),[l,p]=mt(!1);return xe(()=>{if(!t){p(!1),a(!1);return}a(!0);let d=requestAnimationFrame(()=>p(!0));return()=>cancelAnimationFrame(d)},[t]),xe(()=>{if(!o)return;let d=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=d}},[o]),xe(()=>{if(!o)return;s.current?.focus();function d(m){m.key==="Escape"&&e(!1)}return document.addEventListener("keydown",d),()=>document.removeEventListener("keydown",d)},[o,e]),!o||typeof document>"u"?null:ui(pe(mi,{children:[B("div",{className:`rle-sheet-backdrop${l?" rle-sheet-backdrop--open":""}`,onClick:()=>e(!1),"aria-hidden":"true"}),pe("div",{ref:s,className:`rle-sheet${l?" rle-sheet--open":""}`,role:"dialog","aria-modal":"true","aria-label":i,tabIndex:-1,children:[B("div",{className:"rle-sheet__handle","aria-hidden":"true"}),pe("div",{className:"rle-sheet__header",children:[i&&B("div",{className:"rle-sheet__title",children:i}),B("button",{type:"button",className:"rle-sheet__close",onClick:()=>e(!1),"aria-label":"Close",children:B(ci,{})})]}),B("div",{className:"rle-sheet__body",children:n}),r&&B("div",{className:"rle-sheet__footer",children:r})]})]}),document.body)}function ci(){return pe("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[B("path",{d:"M18 6 6 18"}),B("path",{d:"m6 6 12 12"})]})}import{useEffect as ce,useRef as Re,useState as K}from"react";import{jsx as L,jsxs as ue}from"react/jsx-runtime";function ft({search:t,onFiltersClick:e,filterCount:i=0,action:n}){let{Search:r}=C();return ue("header",{className:"rle-mobile-header",children:[t&&L("div",{className:"rle-mobile-header__search",children:L(r,{value:t.value,onChange:t.onChange,placeholder:t.placeholder})}),ue("button",{type:"button",className:"rle-btn rle-mobile-header__btn",onClick:e,children:[L(gi,{}),L("span",{children:"Filters"}),i>0&&L("span",{className:"rle-mobile-header__count",children:i})]}),n&&L("button",{type:"button",className:"rle-btn rle-mobile-header__btn rle-mobile-header__btn--icon",onClick:n.onClick,"aria-label":n.label,children:n.icon??L(fi,{})})]})}function gi(){return ue("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[L("line",{x1:"4",y1:"6",x2:"20",y2:"6"}),L("circle",{cx:"9",cy:"6",r:"2",fill:"currentColor",stroke:"none"}),L("line",{x1:"4",y1:"12",x2:"20",y2:"12"}),L("circle",{cx:"15",cy:"12",r:"2",fill:"currentColor",stroke:"none"}),L("line",{x1:"4",y1:"18",x2:"20",y2:"18"}),L("circle",{cx:"11",cy:"18",r:"2",fill:"currentColor",stroke:"none"})]})}function fi(){return ue("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[L("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),L("line",{x1:"5",y1:"12",x2:"19",y2:"12"})]})}import{Fragment as yt,jsx as c,jsxs as U}from"react/jsx-runtime";var yi=c("div",{className:"rle-empty",children:"Map unavailable"});function hi(){let t=Re(null),[e,i]=K(!0),[n,r]=K(!0);return ce(()=>{let s=t.current;if(!s)return;let o=()=>{let{clientWidth:m,scrollLeft:y,scrollWidth:x}=s;i(y<=0),r(y+m>=x-1)},a=0,l=()=>{a||(a=requestAnimationFrame(()=>{a=0,o()}))};o(),s.addEventListener("scroll",o,{passive:!0});let p,d;return typeof ResizeObserver<"u"&&(p=new ResizeObserver(o),p.observe(s)),typeof MutationObserver<"u"&&(d=new MutationObserver(l),d.observe(s,{characterData:!0,childList:!0,subtree:!0})),()=>{s.removeEventListener("scroll",o),p?.disconnect(),d?.disconnect(),a&&cancelAnimationFrame(a)}},[]),{atEnd:n,atStart:e,ref:t}}function vi(t,e){if(t===e)return!0;if(typeof t!="object"||t===null||typeof e!="object"||e===null)return!1;let i=t,n=e,r=new Set([...Object.keys(i),...Object.keys(n)]);for(let s of r)if(i[s]!==n[s])return!1;return!0}function ht({search:t,filterBarStart:e,resultsSlot:i,toolbarEnd:n,mobileAction:r,autoFetch:s=!0,initialPage:o,hasMap:a,mapCenter:l,mapZoom:p,mapControls:d,onMapReady:m,mobileSheetFooter:y,className:x}){let F=v(),{BottomNav:V,Search:O}=C(),u=W(),{filters:N,set:z}=oe(),{pagination:T}=I(),P=a??F.map!=null,[_,q]=K("list"),[M,h]=K(!1),{atEnd:b,atStart:g,ref:f}=hi(),k=Re(null);ce(()=>{T.mode==="paged"&&k.current&&(k.current.scrollTop=0)},[T.mode,T.pageIndex]);let[A,R]=K(N),[bt,Lt]=K(M);M!==bt&&(Lt(M),M&&R(N));let Me=ge=>R(Tt=>({...Tt,...ge})),[De,Be]=K(!1),me=Re(!1);ce(()=>{if(De){if(T.loading){me.current=!0;return}me.current&&(me.current=!1,Be(!1),h(!1))}},[De,T.loading]);let Q=t?{value:String(N[t.filterKey]??""),onChange:ge=>{z({[t.filterKey]:ge||void 0})},placeholder:t.placeholder}:void 0;ce(()=>{s!==!1&&(o&&o>0?F.goToPage(o):F.applyFilters({}))},[F,s]);let Oe=()=>{Me(F.filters.clearedParams())},_e=()=>{if(vi(A,N)){h(!1);return}Be(!0),F.applyFilters(A)},Pt=F.filters.activeKeys(N).length,Ae=u.total??u.items.length;return U("div",{className:x?`rle-app ${x}`:"rle-app",children:[U("div",{className:"rle-filter-bar",children:[U("div",{className:"rle-filter-bar__scroll",ref:f,children:[Q&&c("div",{className:"rle-filter-bar__search",children:c(O,{value:Q.value,onChange:Q.onChange,placeholder:Q.placeholder})}),e&&c("div",{className:"rle-filter-bar__slot",children:e}),c(ye,{className:"rle-filters-row",groupClassName:"rle-filter-group",hideLabels:!0})]}),!g&&c("div",{className:"rle-filter-bar__fade rle-filter-bar__fade--start","aria-hidden":"true"}),!b&&c("div",{className:"rle-filter-bar__fade rle-filter-bar__fade--end","aria-hidden":"true"})]}),c(ft,{search:Q,onFiltersClick:()=>h(!0),filterCount:Pt,action:r}),U("div",{className:`rle-body ${P?"rle-split":"rle-body--list-only"}`,"data-mobile-view":_,children:[c("div",{className:"rle-list",ref:k,children:i??U(yt,{children:[U("div",{className:"rle-list-header",children:[c(st,{}),n&&c("div",{className:"rle-list-header__toolbar",children:n})]}),c(Je,{className:"rle-list-grid"}),c(rt,{})]})}),P&&c("div",{className:"rle-map",children:c(nt,{center:l,zoom:p,fallback:yi,mapControls:d,onMapReady:m})})]}),P&&c(V,{view:_,onViewChange:q}),c(gt,{title:"Filters",open:M,onOpenChange:h,footer:y?y({draft:A,apply:_e,clear:Oe,resultCount:Ae,loading:T.loading}):U(yt,{children:[c("button",{type:"button",className:"rle-btn rle-btn--ghost",onClick:Oe,children:"Clear all"}),c("button",{type:"button",className:"rle-btn rle-btn--primary rle-sheet__apply",disabled:T.loading,onClick:_e,children:T.loading?c("span",{className:"rle-spinner","aria-label":"Updating results"}):`Show ${Ae} results`})]}),children:c(ye,{className:"rle-filter-stack",groupClassName:"rle-filter-group",draft:A,onDraftChange:Me})})]})}import{useEffect as bi,useRef as Li,useState as Pi}from"react";import{jsx as Ne,jsxs as ki}from"react/jsx-runtime";function vt(t){return"provider"in t}function Ti(t){let e=t!=null&&!vt(t),i=e?t.apiKey:void 0,n=e?t.mapId:void 0,r=e?t.mapOptions:void 0,s=e?t.styles:void 0,o=e?t.overlayMarkers:void 0,[a,l]=Pi(()=>!t||vt(t)?{ready:!0,provider:t?.provider}:{ready:!1});return bi(()=>{if(!i)return;let p=!1;return import("./maps/google/index.js").then(({googleProvider:d})=>{p||l({ready:!0,provider:d({apiKey:i,mapId:n,mapOptions:r,styles:s,overlayMarkers:o})})}),()=>{p=!0}},[i,n]),a}function Fi({onFiltersChange:t}){let e=Li(t);return e.current=t,ot("FiltersChanged",i=>{i.type==="FiltersChanged"&&e.current(i.filters)}),null}function qr(t){let{datasets:e,filters:i,map:n,components:r,initialFilters:s,initialResults:o,onFiltersChange:a,mobileAction:l,search:p,filterBarStart:d,resultsSlot:m,toolbarEnd:y,mapControls:x,onMapReady:F,mobileSheetFooter:V,config:O,autoFetch:u,initialPage:N,className:z}=t,{provider:T}=Ti(n),P=[];for(let M of e)P.push(Ve(M));i&&P.push(qe(i)),T&&P.push(Ke(T)),s&&P.push($e(s)),o&&P.push(We(o)),O&&P.push(Ue(O));let _=ze(...P),q={...ct,...r};return ki(lt,{..._,children:[a&&Ne(Fi,{onFiltersChange:a}),Ne(Ge,{...q,children:Ne(ht,{className:z,search:p,filterBarStart:d,resultsSlot:m,toolbarEnd:y,mobileAction:l,autoFetch:u??o==null,hasMap:n!=null,mapCenter:n?.center,mapZoom:n?.zoom,mapControls:x,onMapReady:F,initialPage:N,mobileSheetFooter:V})})]})}export{ee as a,$ as b,te as c,ie as d,He as e,ne as f,re as g,ze as h,Ue as i,Ke as j,Ve as k,qe as l,Hi as m,$e as n,We as o,zi as p,fe as q,Ge as r,C as s,se as t,v as u,I as v,oe as w,ye as x,W as y,Je as z,nt as A,rt as B,st as C,ot as D,lt as E,dt as F,be as G,Le as H,Pe as I,Te as J,Fe as K,we as L,Se as M,Ce as N,Ie as O,Ee as P,ct as Q,gt as R,ht as S,qr as T};
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } 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; } var _class; var _class2; var _class3; var _class4; var _class5;"use client";
2
+ var ee= (_class =class{__init() {this.listeners=new Set}constructor(e){;_class.prototype.__init.call(this);this.state=this.freezeState({filters:{...e.filters},results:e.results?{items:[...e.results.items],nextCursor:e.results.nextCursor,total:e.results.total}:{items:[],nextCursor:null},bounds:null,selection:null,hovered:null,pagination:{mode:_nullishCoalesce(e.mode, () => ("paged")),loading:!1,pageIndex:0},layers:{},points:{}})}getState(){return this.state}setFilters(e){this.setState({filters:{...this.state.filters,...e}})}setResults(e){this.setState({results:{items:[...e.items],nextCursor:e.nextCursor,total:e.total}})}appendResults(e){this.setState({results:{items:[...this.state.results.items,...e.items],nextCursor:e.nextCursor,total:e.total}})}setBounds(e){this.setState({bounds:e?{...e}:null})}setSelection(e){this.setState({selection:e})}setHovered(e){this.setState({hovered:e})}setLayerVisible(e,i){this.setState({layers:{...this.state.layers,[e]:i}})}setLoading(e){this.setState({pagination:{...this.state.pagination,loading:e}})}setPageIndex(e){this.setState({pagination:{...this.state.pagination,pageIndex:e}})}setPoints(e,i){this.setState({points:{...this.state.points,[e]:[...i]}})}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}setState(e){this.state=this.freezeState({...this.state,...e}),this.notify()}notify(){for(let e of this.listeners)e()}freezeState(e){Object.freeze(e.filters),Object.freeze(e.results.items),Object.freeze(e.results),e.bounds&&Object.freeze(e.bounds),Object.freeze(e.pagination),Object.freeze(e.layers);for(let i of Object.values(e.points))Object.freeze(i);return Object.freeze(e.points),Object.freeze(e)}}, _class);var $= (_class2 =class{constructor() { _class2.prototype.__init2.call(this); }__init2() {this.defs=new Map}add(e){if(this.defs.has(e.key))throw new Error(`FilterRegistry: filter "${e.key}" is already registered`);return this.defs.set(e.key,{...e}),this}remove(e){return this.defs.delete(e),this}replace(e,i){if(!this.defs.has(e))throw new Error(`FilterRegistry: cannot replace unregistered filter "${e}"`);return this.defs.set(e,{...i,key:e}),this}reorder(e){let i=this.list(),n=e.filter(s=>this.defs.has(s));n.forEach((s,o)=>{this.defs.get(s).order=o});let r=new Set(n);return i.filter(s=>!r.has(s.key)).forEach((s,o)=>{s.order=n.length+o}),this}list(){return[...this.defs.values()].sort((e,i)=>e.order-i.order)}has(e){return this.defs.has(e)}toFilters(e){return this.list().filter(n=>Object.hasOwn(e,n.key)).map(n=>n.toParams(e[n.key])).reduce((n,r)=>({...n,...r}),{})}activeKeys(e){return this.list().filter(i=>_optionalChain([i, 'access', _2 => _2.isActive, 'optionalCall', _3 => _3(e)])).map(i=>i.key)}clearedParams(){return this.list().reduce((e,i)=>Object.assign(e,i.toParams(i.fromParams({}))),{})}}, _class2);var te= (_class3 =class{constructor() { _class3.prototype.__init3.call(this); }__init3() {this.defs=new Map}add(e){if(this.defs.has(e.id))throw new Error(`DatasetRegistry: dataset "${e.id}" is already registered`);return this.defs.set(e.id,{...e}),this}get(e){return this.defs.get(e)}has(e){return this.defs.has(e)}list(){return[...this.defs.values()]}visibleIds(){return this.list().filter(e=>_optionalChain([e, 'access', _4 => _4.visible, 'optionalCall', _5 => _5()])!==!1).map(e=>e.id)}}, _class3);var ie= (_class4 =class{constructor() { _class4.prototype.__init4.call(this); }__init4() {this.map=new Map}dispose(){this.map.clear()}emit(e){let i=this.map.get(e.type);if(i)for(let r of[...i])r(e);let n=this.map.get("*");if(n)for(let r of[...n])r(e)}on(e,i){let n=this.map.get(e);return n||(n=new Set,this.map.set(e,n)),n.add(i),()=>{n.delete(i)}}}, _class4);var He={pagination:"paged",pageSize:20,debounceMs:250};var ne=class{constructor(e){this.options=Object.freeze({...He,...e})}};var re= (_class5 =class{__init5() {this.disposed=!1}__init6() {this.emitter=new ie}__init7() {this.debounceTimer=null}__init8() {this.debounceResolve=null}__init9() {this.queryToken=0}__init10() {this.pointsToken=0}__init11() {this.mapHandle=null}constructor(e){;_class5.prototype.__init5.call(this);_class5.prototype.__init6.call(this);_class5.prototype.__init7.call(this);_class5.prototype.__init8.call(this);_class5.prototype.__init9.call(this);_class5.prototype.__init10.call(this);_class5.prototype.__init11.call(this);this.datasets=e.datasets,this.filters=_nullishCoalesce(e.filters, () => (new $)),this.map=e.map,this.config=new ne(e.config);let i=_nullishCoalesce(e.primaryDatasetId, () => (_optionalChain([this, 'access', _6 => _6.datasets, 'access', _7 => _7.list, 'call', _8 => _8(), 'access', _9 => _9[0], 'optionalAccess', _10 => _10.id])));if(i==null||!this.datasets.has(i))throw new Error(`ListingEngine: primary dataset "${_nullishCoalesce(i, () => (""))}" is not registered \u2014 pass a valid primaryDatasetId or register at least one dataset`);this.primaryDatasetId=i,this.store=new ee({filters:_nullishCoalesce(e.initialFilters, () => ({})),mode:this.config.options.pagination,results:e.initialResults})}get state(){return this.store.getState()}get options(){return this.config.options}applyFilters(e){this.store.setFilters(e),this.emitter.emit({type:"FiltersChanged",filters:this.currentFilters()}),this.clearDebounce();let i=++this.queryToken,n=this.config.options.debounceMs;return n<=0?this.runQuery(i):new Promise(r=>{this.debounceResolve=r,this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.debounceResolve=null,r(this.runQuery(i))},n)})}async loadPage(){let e=this.state.results.nextCursor;if(e===null)return;let i=++this.queryToken,n=this.primaryDataset();this.store.setLoading(!0);try{let r=await n.adapter.list(this.currentFilters(),{cursor:e,limit:this.config.options.pageSize});if(i!==this.queryToken)return;this.config.options.pagination==="infinite"?this.store.appendResults(r):this.store.setResults(r),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:r.items.length})}finally{i===this.queryToken&&this.store.setLoading(!1)}}async goToPage(e){if(e<0)return;let i=++this.queryToken,n=this.primaryDataset();this.store.setLoading(!0);try{let r=await n.adapter.list(this.currentFilters(),{offset:e*this.config.options.pageSize,limit:this.config.options.pageSize});if(i!==this.queryToken)return;this.store.setResults(r),this.store.setPageIndex(e),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:r.items.length})}finally{i===this.queryToken&&this.store.setLoading(!1)}}async loadPoints(e){this.store.setBounds(e),this.emitter.emit({type:"BoundsChanged",bounds:e});let i=this.currentFilters(),n=++this.pointsToken;await Promise.allSettled(this.datasets.visibleIds().map(async r=>{let s=this.datasets.get(r);if(!s)return;let o=await s.adapter.getPoints(i,e);n===this.pointsToken&&this.store.setPoints(r,o)}))}setMapHandle(e){this.mapHandle=e}fitBounds(e,i){!this.map||!this.mapHandle||this.map.fitBounds(this.mapHandle,e,i)}selectPoint(e,i){this.store.setSelection(i);let n=_optionalChain([this, 'access', _11 => _11.state, 'access', _12 => _12.points, 'access', _13 => _13[e], 'optionalAccess', _14 => _14.find, 'call', _15 => _15(r=>r.id===i)]);n&&this.emitter.emit({type:"PointClicked",datasetId:e,id:n.id,entity:n.entity})}setHovered(e,i){this.store.setHovered(i)}toggleLayer(e){let n=!(_nullishCoalesce(this.state.layers[e], () => (!0)));this.store.setLayerVisible(e,n),this.emitter.emit({type:"LayerToggled",datasetId:e,visible:n})}subscribe(e){return this.store.subscribe(e)}on(e,i){return this.emitter.on(e,i)}get isDisposed(){return this.disposed}dispose(){this.clearDebounce(),this.emitter.dispose(),this.mapHandle=null,this.disposed=!0}async runQuery(e){if(e!==this.queryToken)return;let i=this.primaryDataset();this.store.setLoading(!0);try{let n=await i.adapter.list(this.currentFilters(),{cursor:null,limit:this.config.options.pageSize});if(e!==this.queryToken)return;this.store.setResults(n),this.store.setPageIndex(0),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:n.items.length})}finally{e===this.queryToken&&this.store.setLoading(!1)}}primaryDataset(){return this.datasets.get(this.primaryDatasetId)}currentFilters(){return this.store.getState().filters}clearDebounce(){this.debounceTimer!==null&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.debounceResolve!==null&&(this.debounceResolve(),this.debounceResolve=null)}}, _class5);function ze(...t){let e={config:{},filters:new $,datasets:new te};for(let i of t)i(e);return e}var Ue=t=>e=>{e.config={...e.config,...t}},Ke= exports.j =t=>e=>{e.map=t},Ve= exports.k =t=>e=>{e.datasets.add(t)},qe= exports.l =t=>e=>{t(e.filters)},Hi= exports.m =t=>e=>{e.urlSync=t},$e= exports.n =t=>e=>{e.initialFilters=t},We= exports.o =t=>e=>{e.initialResults=t},zi= exports.p =t=>e=>{e.primaryDatasetId=t};var _react = require('react');var _jsxruntime = require('react/jsx-runtime');function wt(t){return String(_nullishCoalesce(_optionalChain([t, 'optionalAccess', _16 => _16.title]), () => ("")))}var St=({item:t})=>_jsxruntime.jsx.call(void 0, "div",{children:wt(t)}),Ct=()=>_jsxruntime.jsx.call(void 0, "div",{}),fe= exports.q =()=>_jsxruntime.jsx.call(void 0, "div",{}),It=({children:t})=>_jsxruntime.jsx.call(void 0, "div",{children:t}),Et=({children:t})=>_jsxruntime.jsx.call(void 0, "div",{children:t}),xt=({value:t,onChange:e,placeholder:i})=>_jsxruntime.jsx.call(void 0, "input",{type:"search",value:t,placeholder:i,onChange:n=>e(n.target.value),"aria-label":_nullishCoalesce(i, () => ("Search"))}),Rt=()=>_jsxruntime.jsx.call(void 0, "div",{role:"status",children:"No results"}),Nt=()=>_jsxruntime.jsx.call(void 0, "div",{role:"status","aria-busy":"true",children:"Loading\u2026"}),Mt=({count:t})=>_jsxruntime.jsxs.call(void 0, "div",{children:[t," results"]}),Dt=({children:t})=>_jsxruntime.jsx.call(void 0, "div",{children:t}),Bt=({view:t,onViewChange:e})=>_jsxruntime.jsxs.call(void 0, "nav",{"aria-label":"Listing navigation",children:[_jsxruntime.jsx.call(void 0, "button",{type:"button","aria-pressed":t==="list",onClick:()=>e("list"),children:"List"}),_jsxruntime.jsx.call(void 0, "button",{type:"button","aria-pressed":t==="map",onClick:()=>e("map"),children:"Map"})]}),w={BottomNav:Bt,Card:St,Marker:Ct,Popup:fe,Sidebar:It,FilterPanel:Et,Search:xt,Empty:Rt,Loading:Nt,ResultHeader:Mt,Toolbar:Dt},je=_react.createContext.call(void 0, w);function Ge(t){let{BottomNav:e,Card:i,Marker:n,Popup:r,Sidebar:s,FilterPanel:o,Search:a,Empty:l,Loading:p,ResultHeader:d,Toolbar:m,children:y}=t,x={BottomNav:_nullishCoalesce(e, () => (w.BottomNav)),Card:_nullishCoalesce(i, () => (w.Card)),Marker:_nullishCoalesce(n, () => (w.Marker)),Popup:_nullishCoalesce(r, () => (w.Popup)),Sidebar:_nullishCoalesce(s, () => (w.Sidebar)),FilterPanel:_nullishCoalesce(o, () => (w.FilterPanel)),Search:_nullishCoalesce(a, () => (w.Search)),Empty:_nullishCoalesce(l, () => (w.Empty)),Loading:_nullishCoalesce(p, () => (w.Loading)),ResultHeader:_nullishCoalesce(d, () => (w.ResultHeader)),Toolbar:_nullishCoalesce(m, () => (w.Toolbar))};return _jsxruntime.jsx.call(void 0, je.Provider,{value:x,children:y})}function C(){return _react.useContext.call(void 0, je)}var se=_react.createContext.call(void 0, null);function v(){let t=_react.useContext.call(void 0, se);if(t===null)throw new Error("useListing must be used within a <ListingProvider>");return t}function I(){let t=v(),e=_react.useCallback.call(void 0, n=>t.subscribe(n),[t]),i=_react.useCallback.call(void 0, ()=>t.state,[t]);return _react.useSyncExternalStore.call(void 0, e,i,i)}function oe(){let t=v(),e=I(),i=_react.useCallback.call(void 0, r=>t.applyFilters(r),[t]),n=_react.useCallback.call(void 0, (r,s)=>t.applyFilters({[r]:s}),[t]);return{filters:e.filters,set:i,setField:n}}function ye({className:t,groupClassName:e,hideLabels:i,draft:n,onDraftChange:r}={}){let s=v(),{FilterPanel:o}=C(),{filters:a}=oe(),l=n!==void 0&&r!==void 0,p=l?n:a;return _jsxruntime.jsx.call(void 0, o,{children:_jsxruntime.jsx.call(void 0, "div",{className:_nullishCoalesce(t, () => ("space-y-5")),children:s.filters.list().map(d=>{if(typeof d.render=="string")return _jsxruntime.jsx.call(void 0, "div",{"data-filter":d.key,className:e},d.key);let m=d.render;return _jsxruntime.jsxs.call(void 0, "div",{className:e,children:[d.label&&!i&&_jsxruntime.jsx.call(void 0, "div",{className:"mb-1.5 text-[13px] font-medium text-foreground",children:d.label}),_jsxruntime.jsx.call(void 0, m,{value:d.fromParams(p),onChange:y=>l?r(d.toParams(y)):void s.applyFilters(d.toParams(y))})]},d.key)})})})}function W(){return I().results}function zt(t,e){if(t&&typeof t=="object"&&"id"in t){let i=t.id;if(typeof i=="string"||typeof i=="number")return i}return e}function Je({className:t}={}){let e=v(),{items:i}=W(),{pagination:n,selection:r}=I(),{Card:s,Empty:o,Loading:a}=C();return n.loading&&i.length===0?_jsxruntime.jsx.call(void 0, a,{}):i.length===0?_jsxruntime.jsx.call(void 0, o,{}):_jsxruntime.jsx.call(void 0, "div",{role:"list",className:t,children:i.map((l,p)=>{let d=zt(l,p);return _jsxruntime.jsx.call(void 0, s,{item:l,selected:r===d,onSelect:()=>e.selectPoint(e.primaryDatasetId,d)},d)})})}var _reactdom = require('react-dom');var Kt={west:-179.9,south:-85,east:179.9,north:85},et=.1,tt=.02;function Vt(t){if(t.length===0)return null;let e=t[0].lng,i=t[0].lng,n=t[0].lat,r=t[0].lat;for(let{lat:a,lng:l}of t)l<e&&(e=l),l>i&&(i=l),a<n&&(n=a),a>r&&(r=a);let s=r>n?(r-n)*et:tt,o=i>e?(i-e)*et:tt;return{west:e-o,east:i+o,south:n-s,north:r+s}}function nt(t){let{center:e,zoom:i,fallback:n,mapControls:r,onMapReady:s}=t,o=v(),a=I(),l=_react.useRef.call(void 0, s);l.current=s;let p=_react.useRef.call(void 0, null),d=_react.useRef.call(void 0, null),m=_react.useRef.call(void 0, null),[y,x]=_react.useState.call(void 0, !1),F=_react.useRef.call(void 0, !1),V=_react.useRef.call(void 0, !1),O=_react.useRef.call(void 0, !1),u=o.map;_react.useEffect.call(void 0, ()=>{let h=m.current;if(!u||!h)return;let b=[];for(let g of Object.keys(a.points)){if(a.layers[g]===!1)continue;let f=o.datasets.get(g),k=_nullishCoalesce(a.points[g], () => ([])),A={id:g,markers:k.map(R=>({id:R.id,position:R.position,iconUrl:_optionalChain([f, 'optionalAccess', _17 => _17.marker, 'access', _18 => _18.iconUrl, 'optionalCall', _19 => _19(R.entity)]),element:_optionalChain([f, 'optionalAccess', _20 => _20.marker, 'access', _21 => _21.element, 'optionalCall', _22 => _22(R.entity)])})),clustering:_optionalChain([f, 'optionalAccess', _23 => _23.clustering]),onMarkerClick:R=>o.selectPoint(g,R)};b.push(u.renderLayer(h,A))}return()=>{b.forEach(g=>g())}},[o,u,y,a.points,a.layers]),_react.useEffect.call(void 0, ()=>{if(!p.current||!u)return;let h=p.current,b=!1,g=null;return(async()=>{let f=await u.mount(h,{center:e,zoom:i,fullscreenTarget:_nullishCoalesce(d.current, () => (void 0))});if(b){u.destroy(f);return}m.current=f,o.setMapHandle(f),g=u.onBoundsChange(f,k=>{O.current?O.current=!1:V.current=!0,o.loadPoints(k)}),x(!0),_optionalChain([l, 'access', _24 => _24.current, 'optionalCall', _25 => _25(_nullishCoalesce(f.nativeMap, () => (f.raw)))]),o.loadPoints(Kt)})(),()=>{b=!0,_optionalChain([g, 'optionalCall', _26 => _26()]),m.current&&(u.destroy(m.current),m.current=null,o.setMapHandle(null),_optionalChain([l, 'access', _27 => _27.current, 'optionalCall', _28 => _28(null)])),x(!1)}},[o,u]),_react.useEffect.call(void 0, ()=>{let h=m.current;if(!u||!h||e||F.current||V.current)return;let b=[];for(let f of Object.keys(a.points))if(a.layers[f]!==!1)for(let k of _nullishCoalesce(a.points[f], () => ([])))b.push(k.position);let g=Vt(b);g&&(F.current=!0,O.current=!0,u.fitBounds(h,g))},[u,e,y,a.points,a.layers]),_react.useEffect.call(void 0, ()=>{_optionalChain([u, 'optionalAccess', _29 => _29.updateMarkerStates, 'call', _30 => _30(a.selection,a.hovered)])},[u,y,a.selection,a.hovered]);let{Popup:N}=C(),z=N!==fe,T=_nullishCoalesce(a.points[o.primaryDatasetId], () => ([])),P=a.selection!=null?T.find(h=>h.id===a.selection):void 0,[_,q]=_react.useState.call(void 0, null),M=_react.useRef.call(void 0, P);return M.current=P,_react.useEffect.call(void 0, ()=>{let h=m.current;if(!u||!h||!z)return;let b=M.current;if(!b)return;let g=u.mountOverlay(b.position);q({entity:b.entity,position:b.position,container:g.container});let f=()=>o.selectPoint(o.primaryDatasetId,null),k=R=>{R.key==="Escape"&&f()};document.addEventListener("keydown",k);let A=u.onMapClick(f);return()=>{document.removeEventListener("keydown",k),A(),g.unmount(),q(null)}},[o,u,y,a.selection,z]),_jsxruntime.jsxs.call(void 0, "div",{ref:d,className:"relative h-full min-h-0 w-full",children:[_jsxruntime.jsxs.call(void 0, "div",{ref:p,className:!u&&n?"flex h-full min-h-0 w-full items-center justify-center":"h-full min-h-0 w-full",children:[!u&&n,z&&_?_reactdom.createPortal.call(void 0, _jsxruntime.jsx.call(void 0, N,{entity:_.entity,onClose:()=>o.selectPoint(o.primaryDatasetId,null)}),_.container):null]}),r!=null&&_jsxruntime.jsx.call(void 0, "div",{className:"pointer-events-none absolute inset-0",children:_jsxruntime.jsx.call(void 0, "div",{className:"pointer-events-auto",children:r})})]})}var ve="gap";function qt(t,e){if(t<=7)return Array.from({length:t},(s,o)=>o+1);let i=Math.max(2,e-1),n=Math.min(t-1,e+1),r=[1];i>2&&r.push(ve);for(let s=i;s<=n;s+=1)r.push(s);return n<t-1&&r.push(ve),r.push(t),r}function rt(){let t=v(),{results:e,pagination:i}=I();if(i.mode==="infinite")return e.nextCursor==null?null:_jsxruntime.jsx.call(void 0, "button",{type:"button",disabled:i.loading,onClick:()=>{t.loadPage()},children:"Load more"});let n=t.options.pageSize,{pageIndex:r}=i,s=r+1,o=e.total!=null?Math.ceil(e.total/n):null,a=o!=null?s<o:e.nextCursor!=null||e.items.length>=n;if(o!=null?o<=1:r===0&&!a)return null;let l=p=>()=>{t.goToPage(p)};return _jsxruntime.jsxs.call(void 0, "nav",{className:"rle-pagination","aria-label":"Pagination",children:[_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-page-btn rle-page-btn--nav","aria-label":"Previous page",disabled:i.loading||r===0,onClick:l(r-1),children:"\u2039"}),o!=null&&qt(o,s).map((p,d)=>p===ve?_jsxruntime.jsx.call(void 0, "span",{className:"rle-page-ellipsis",children:"\u2026"},`gap-${d}`):_jsxruntime.jsx.call(void 0, "button",{type:"button",className:p===s?"rle-page-btn rle-page-btn--active":"rle-page-btn","aria-label":`Page ${p}`,"aria-current":p===s?"page":void 0,disabled:i.loading,onClick:l(p-1),children:p},p)),_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-page-btn rle-page-btn--nav","aria-label":"Next page",disabled:i.loading||!a,onClick:l(r+1),children:"\u203A"})]})}function st(){let{items:t,total:e}=W(),{ResultHeader:i}=C();return _jsxruntime.jsx.call(void 0, i,{count:t.length,total:e})}function ot(t,e){let i=v(),n=_react.useRef.call(void 0, e);n.current=e,_react.useEffect.call(void 0, ()=>i.on(t,r=>n.current(r)),[i,t])}function lt(t){let{children:e,...i}=t,[n]=_react.useState.call(void 0, ()=>i),r=_react.useCallback.call(void 0, ()=>new re({datasets:n.datasets,filters:n.filters,config:n.config,map:n.map,initialFilters:n.initialFilters,initialResults:n.initialResults,primaryDatasetId:n.primaryDatasetId}),[n]),[s,o]=_react.useState.call(void 0, r),a=_react.useRef.call(void 0, s);return a.current=s,_react.useEffect.call(void 0, ()=>{let l=a.current;return l.isDisposed&&(l=r(),a.current=l,o(l)),n.urlSync&&n.urlSync.start(l),()=>{n.urlSync&&n.urlSync.stop(),l.dispose()}},[n,r]),_jsxruntime.jsx.call(void 0, se.Provider,{value:s,children:e})}function dt({view:t,onViewChange:e}){return _jsxruntime.jsx.call(void 0, "nav",{className:"rle-bottom-nav","aria-label":"Listing navigation",children:_jsxruntime.jsxs.call(void 0, "div",{className:"rle-viewtoggle",role:"group","aria-label":"View",children:[_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:`rle-viewtoggle__btn${t==="list"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":t==="list",onClick:()=>e("list"),children:[_jsxruntime.jsx.call(void 0, Yt,{}),"List"]}),_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:`rle-viewtoggle__btn${t==="map"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":t==="map",onClick:()=>e("map"),children:[_jsxruntime.jsx.call(void 0, ei,{}),"Map"]})]})})}function Yt(){return _jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "line",{x1:"8",y1:"6",x2:"20",y2:"6"}),_jsxruntime.jsx.call(void 0, "line",{x1:"8",y1:"12",x2:"20",y2:"12"}),_jsxruntime.jsx.call(void 0, "line",{x1:"8",y1:"18",x2:"20",y2:"18"}),_jsxruntime.jsx.call(void 0, "line",{x1:"4",y1:"6",x2:"4.01",y2:"6"}),_jsxruntime.jsx.call(void 0, "line",{x1:"4",y1:"12",x2:"4.01",y2:"12"}),_jsxruntime.jsx.call(void 0, "line",{x1:"4",y1:"18",x2:"4.01",y2:"18"})]})}function ei(){return _jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "polygon",{points:"1 6 8 3 16 6 23 3 23 18 16 21 8 18 1 21 1 6"}),_jsxruntime.jsx.call(void 0, "line",{x1:"8",y1:"3",x2:"8",y2:"18"}),_jsxruntime.jsx.call(void 0, "line",{x1:"16",y1:"6",x2:"16",y2:"21"})]})}function j(t){return typeof t!="number"?t:new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(t)}function ti(t){return t?"rle-card rle-card--selected":"rle-card"}function be({item:t,selected:e,onSelect:i}){let n=_nullishCoalesce(t, () => ({})),r=ti(e),s=_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[n.imageUrl?_jsxruntime.jsx.call(void 0, "img",{src:n.imageUrl,alt:_nullishCoalesce(n.title, () => ("")),className:"rle-card-media"}):_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-media rle-card-media--placeholder","aria-hidden":"true"}),_jsxruntime.jsxs.call(void 0, "div",{className:"rle-card-body",children:[n.title&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-title",children:n.title}),n.subtitle&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-address",children:n.subtitle}),n.badge&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-info",children:_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-info-item",children:n.badge})}),n.price!=null&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-price",children:j(n.price)})]})]});return i?_jsxruntime.jsx.call(void 0, "button",{type:"button",onClick:i,"aria-pressed":_nullishCoalesce(e, () => (!1)),className:r,children:s}):_jsxruntime.jsx.call(void 0, "article",{className:r,children:s})}function Le(t){return _jsxruntime.jsxs.call(void 0, "div",{role:"status",className:"rle-empty",children:[_jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",className:"rle-empty-icon","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "circle",{cx:"11",cy:"11",r:"7"}),_jsxruntime.jsx.call(void 0, "path",{d:"m21 21-4.3-4.3"})]}),_jsxruntime.jsx.call(void 0, "p",{className:"rle-empty-title",children:"No results"}),_jsxruntime.jsx.call(void 0, "p",{className:"rle-empty-hint",children:"Try adjusting your filters or search terms."})]})}function Pe({children:t}){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-panel",children:t})}function Te(t){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-loading",role:"status","aria-busy":"true","aria-label":"Loading results",children:Array.from({length:3}).map((e,i)=>_jsxruntime.jsxs.call(void 0, "div",{className:"rle-loading-item",children:[_jsxruntime.jsx.call(void 0, "div",{className:"rle-skeleton",style:{aspectRatio:"4 / 3",width:"100%"}}),_jsxruntime.jsx.call(void 0, "div",{className:"rle-skeleton",style:{height:16,width:"65%"}}),_jsxruntime.jsx.call(void 0, "div",{className:"rle-skeleton",style:{height:12,width:"35%"}})]},i))})}function Fe({point:t}){let e=_nullishCoalesce(t.entity, () => ({}));return _jsxruntime.jsx.call(void 0, "span",{className:"rle-pin",children:e.price!=null?j(e.price):""})}function we({entity:t,onClose:e}){let i=_nullishCoalesce(t, () => ({}));return _jsxruntime.jsxs.call(void 0, "div",{className:"rle-popup",role:"group","aria-label":"Location details",children:[_jsxruntime.jsx.call(void 0, "button",{type:"button",onClick:e,"aria-label":"Close",className:"rle-popup-close",children:_jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "path",{d:"M18 6 6 18"}),_jsxruntime.jsx.call(void 0, "path",{d:"m6 6 12 12"})]})}),_jsxruntime.jsxs.call(void 0, "div",{children:[i.title&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-title",children:i.title}),i.subtitle&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-address",children:i.subtitle}),i.price!=null&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-price",children:j(i.price)})]})]})}function Se({count:t,total:e}){let i=e!=null&&e!==t?`${t} of ${e} results`:`${t} results`;return _jsxruntime.jsx.call(void 0, "div",{className:"rle-result-header",children:i})}function Ce({value:t,onChange:e,placeholder:i}){return _jsxruntime.jsx.call(void 0, "input",{type:"search",value:t,placeholder:i,onChange:n=>e(n.target.value),"aria-label":_nullishCoalesce(i, () => ("Search")),className:"rle-input"})}function Ie({children:t}){return _jsxruntime.jsx.call(void 0, "aside",{className:"rle-sidebar",children:t})}function Ee({children:t}){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-toolbar",children:t})}var ct={BottomNav:dt,Card:be,Marker:Fe,Popup:we,Sidebar:Ie,FilterPanel:Pe,Search:Ce,Empty:Le,Loading:Te,ResultHeader:Se,Toolbar:Ee};function gt({open:t,onOpenChange:e,title:i,children:n,footer:r}){let s=_react.useRef.call(void 0, null),[o,a]=_react.useState.call(void 0, !1),[l,p]=_react.useState.call(void 0, !1);return _react.useEffect.call(void 0, ()=>{if(!t){p(!1),a(!1);return}a(!0);let d=requestAnimationFrame(()=>p(!0));return()=>cancelAnimationFrame(d)},[t]),_react.useEffect.call(void 0, ()=>{if(!o)return;let d=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=d}},[o]),_react.useEffect.call(void 0, ()=>{if(!o)return;_optionalChain([s, 'access', _31 => _31.current, 'optionalAccess', _32 => _32.focus, 'call', _33 => _33()]);function d(m){m.key==="Escape"&&e(!1)}return document.addEventListener("keydown",d),()=>document.removeEventListener("keydown",d)},[o,e]),!o||typeof document>"u"?null:_reactdom.createPortal.call(void 0, _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[_jsxruntime.jsx.call(void 0, "div",{className:`rle-sheet-backdrop${l?" rle-sheet-backdrop--open":""}`,onClick:()=>e(!1),"aria-hidden":"true"}),_jsxruntime.jsxs.call(void 0, "div",{ref:s,className:`rle-sheet${l?" rle-sheet--open":""}`,role:"dialog","aria-modal":"true","aria-label":i,tabIndex:-1,children:[_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__handle","aria-hidden":"true"}),_jsxruntime.jsxs.call(void 0, "div",{className:"rle-sheet__header",children:[i&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__title",children:i}),_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-sheet__close",onClick:()=>e(!1),"aria-label":"Close",children:_jsxruntime.jsx.call(void 0, ci,{})})]}),_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__body",children:n}),r&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__footer",children:r})]})]}),document.body)}function ci(){return _jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "path",{d:"M18 6 6 18"}),_jsxruntime.jsx.call(void 0, "path",{d:"m6 6 12 12"})]})}function ft({search:t,onFiltersClick:e,filterCount:i=0,action:n}){let{Search:r}=C();return _jsxruntime.jsxs.call(void 0, "header",{className:"rle-mobile-header",children:[t&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-mobile-header__search",children:_jsxruntime.jsx.call(void 0, r,{value:t.value,onChange:t.onChange,placeholder:t.placeholder})}),_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:"rle-btn rle-mobile-header__btn",onClick:e,children:[_jsxruntime.jsx.call(void 0, gi,{}),_jsxruntime.jsx.call(void 0, "span",{children:"Filters"}),i>0&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-mobile-header__count",children:i})]}),n&&_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-btn rle-mobile-header__btn rle-mobile-header__btn--icon",onClick:n.onClick,"aria-label":n.label,children:_nullishCoalesce(n.icon, () => (_jsxruntime.jsx.call(void 0, fi,{})))})]})}function gi(){return _jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "line",{x1:"4",y1:"6",x2:"20",y2:"6"}),_jsxruntime.jsx.call(void 0, "circle",{cx:"9",cy:"6",r:"2",fill:"currentColor",stroke:"none"}),_jsxruntime.jsx.call(void 0, "line",{x1:"4",y1:"12",x2:"20",y2:"12"}),_jsxruntime.jsx.call(void 0, "circle",{cx:"15",cy:"12",r:"2",fill:"currentColor",stroke:"none"}),_jsxruntime.jsx.call(void 0, "line",{x1:"4",y1:"18",x2:"20",y2:"18"}),_jsxruntime.jsx.call(void 0, "circle",{cx:"11",cy:"18",r:"2",fill:"currentColor",stroke:"none"})]})}function fi(){return _jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "line",{x1:"12",y1:"5",x2:"12",y2:"19"}),_jsxruntime.jsx.call(void 0, "line",{x1:"5",y1:"12",x2:"19",y2:"12"})]})}var yi=_jsxruntime.jsx.call(void 0, "div",{className:"rle-empty",children:"Map unavailable"});function hi(){let t=_react.useRef.call(void 0, null),[e,i]=_react.useState.call(void 0, !0),[n,r]=_react.useState.call(void 0, !0);return _react.useEffect.call(void 0, ()=>{let s=t.current;if(!s)return;let o=()=>{let{clientWidth:m,scrollLeft:y,scrollWidth:x}=s;i(y<=0),r(y+m>=x-1)},a=0,l=()=>{a||(a=requestAnimationFrame(()=>{a=0,o()}))};o(),s.addEventListener("scroll",o,{passive:!0});let p,d;return typeof ResizeObserver<"u"&&(p=new ResizeObserver(o),p.observe(s)),typeof MutationObserver<"u"&&(d=new MutationObserver(l),d.observe(s,{characterData:!0,childList:!0,subtree:!0})),()=>{s.removeEventListener("scroll",o),_optionalChain([p, 'optionalAccess', _34 => _34.disconnect, 'call', _35 => _35()]),_optionalChain([d, 'optionalAccess', _36 => _36.disconnect, 'call', _37 => _37()]),a&&cancelAnimationFrame(a)}},[]),{atEnd:n,atStart:e,ref:t}}function vi(t,e){if(t===e)return!0;if(typeof t!="object"||t===null||typeof e!="object"||e===null)return!1;let i=t,n=e,r=new Set([...Object.keys(i),...Object.keys(n)]);for(let s of r)if(i[s]!==n[s])return!1;return!0}function ht({search:t,filterBarStart:e,resultsSlot:i,toolbarEnd:n,mobileAction:r,autoFetch:s=!0,initialPage:o,hasMap:a,mapCenter:l,mapZoom:p,mapControls:d,onMapReady:m,mobileSheetFooter:y,className:x}){let F=v(),{BottomNav:V,Search:O}=C(),u=W(),{filters:N,set:z}=oe(),{pagination:T}=I(),P=_nullishCoalesce(a, () => (F.map!=null)),[_,q]=_react.useState.call(void 0, "list"),[M,h]=_react.useState.call(void 0, !1),{atEnd:b,atStart:g,ref:f}=hi(),k=_react.useRef.call(void 0, null);_react.useEffect.call(void 0, ()=>{T.mode==="paged"&&k.current&&(k.current.scrollTop=0)},[T.mode,T.pageIndex]);let[A,R]=_react.useState.call(void 0, N),[bt,Lt]=_react.useState.call(void 0, M);M!==bt&&(Lt(M),M&&R(N));let Me=ge=>R(Tt=>({...Tt,...ge})),[De,Be]=_react.useState.call(void 0, !1),me=_react.useRef.call(void 0, !1);_react.useEffect.call(void 0, ()=>{if(De){if(T.loading){me.current=!0;return}me.current&&(me.current=!1,Be(!1),h(!1))}},[De,T.loading]);let Q=t?{value:String(_nullishCoalesce(N[t.filterKey], () => (""))),onChange:ge=>{z({[t.filterKey]:ge||void 0})},placeholder:t.placeholder}:void 0;_react.useEffect.call(void 0, ()=>{s!==!1&&(o&&o>0?F.goToPage(o):F.applyFilters({}))},[F,s]);let Oe=()=>{Me(F.filters.clearedParams())},_e=()=>{if(vi(A,N)){h(!1);return}Be(!0),F.applyFilters(A)},Pt=F.filters.activeKeys(N).length,Ae=_nullishCoalesce(u.total, () => (u.items.length));return _jsxruntime.jsxs.call(void 0, "div",{className:x?`rle-app ${x}`:"rle-app",children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-filter-bar",children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-filter-bar__scroll",ref:f,children:[Q&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__search",children:_jsxruntime.jsx.call(void 0, O,{value:Q.value,onChange:Q.onChange,placeholder:Q.placeholder})}),e&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__slot",children:e}),_jsxruntime.jsx.call(void 0, ye,{className:"rle-filters-row",groupClassName:"rle-filter-group",hideLabels:!0})]}),!g&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__fade rle-filter-bar__fade--start","aria-hidden":"true"}),!b&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__fade rle-filter-bar__fade--end","aria-hidden":"true"})]}),_jsxruntime.jsx.call(void 0, ft,{search:Q,onFiltersClick:()=>h(!0),filterCount:Pt,action:r}),_jsxruntime.jsxs.call(void 0, "div",{className:`rle-body ${P?"rle-split":"rle-body--list-only"}`,"data-mobile-view":_,children:[_jsxruntime.jsx.call(void 0, "div",{className:"rle-list",ref:k,children:_nullishCoalesce(i, () => (_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-list-header",children:[_jsxruntime.jsx.call(void 0, st,{}),n&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-list-header__toolbar",children:n})]}),_jsxruntime.jsx.call(void 0, Je,{className:"rle-list-grid"}),_jsxruntime.jsx.call(void 0, rt,{})]})))}),P&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-map",children:_jsxruntime.jsx.call(void 0, nt,{center:l,zoom:p,fallback:yi,mapControls:d,onMapReady:m})})]}),P&&_jsxruntime.jsx.call(void 0, V,{view:_,onViewChange:q}),_jsxruntime.jsx.call(void 0, gt,{title:"Filters",open:M,onOpenChange:h,footer:y?y({draft:A,apply:_e,clear:Oe,resultCount:Ae,loading:T.loading}):_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-btn rle-btn--ghost",onClick:Oe,children:"Clear all"}),_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-btn rle-btn--primary rle-sheet__apply",disabled:T.loading,onClick:_e,children:T.loading?_jsxruntime.jsx.call(void 0, "span",{className:"rle-spinner","aria-label":"Updating results"}):`Show ${Ae} results`})]}),children:_jsxruntime.jsx.call(void 0, ye,{className:"rle-filter-stack",groupClassName:"rle-filter-group",draft:A,onDraftChange:Me})})]})}function vt(t){return"provider"in t}function Ti(t){let e=t!=null&&!vt(t),i=e?t.apiKey:void 0,n=e?t.mapId:void 0,r=e?t.mapOptions:void 0,s=e?t.styles:void 0,o=e?t.overlayMarkers:void 0,[a,l]=_react.useState.call(void 0, ()=>!t||vt(t)?{ready:!0,provider:_optionalChain([t, 'optionalAccess', _38 => _38.provider])}:{ready:!1});return _react.useEffect.call(void 0, ()=>{if(!i)return;let p=!1;return Promise.resolve().then(() => _interopRequireWildcard(require("./maps/google/index.cjs"))).then(({googleProvider:d})=>{p||l({ready:!0,provider:d({apiKey:i,mapId:n,mapOptions:r,styles:s,overlayMarkers:o})})}),()=>{p=!0}},[i,n]),a}function Fi({onFiltersChange:t}){let e=_react.useRef.call(void 0, t);return e.current=t,ot("FiltersChanged",i=>{i.type==="FiltersChanged"&&e.current(i.filters)}),null}function qr(t){let{datasets:e,filters:i,map:n,components:r,initialFilters:s,initialResults:o,onFiltersChange:a,mobileAction:l,search:p,filterBarStart:d,resultsSlot:m,toolbarEnd:y,mapControls:x,onMapReady:F,mobileSheetFooter:V,config:O,autoFetch:u,initialPage:N,className:z}=t,{provider:T}=Ti(n),P=[];for(let M of e)P.push(Ve(M));i&&P.push(qe(i)),T&&P.push(Ke(T)),s&&P.push($e(s)),o&&P.push(We(o)),O&&P.push(Ue(O));let _=ze(...P),q={...ct,...r};return _jsxruntime.jsxs.call(void 0, lt,{..._,children:[a&&_jsxruntime.jsx.call(void 0, Fi,{onFiltersChange:a}),_jsxruntime.jsx.call(void 0, Ge,{...q,children:_jsxruntime.jsx.call(void 0, ht,{className:z,search:p,filterBarStart:d,resultsSlot:m,toolbarEnd:y,mobileAction:l,autoFetch:_nullishCoalesce(u, () => (o==null)),hasMap:n!=null,mapCenter:_optionalChain([n, 'optionalAccess', _39 => _39.center]),mapZoom:_optionalChain([n, 'optionalAccess', _40 => _40.zoom]),mapControls:x,onMapReady:F,initialPage:N,mobileSheetFooter:V})})]})}exports.a = ee; exports.b = $; exports.c = te; exports.d = ie; exports.e = He; exports.f = ne; exports.g = re; exports.h = ze; exports.i = Ue; exports.j = Ke; exports.k = Ve; exports.l = qe; exports.m = Hi; exports.n = $e; exports.o = We; exports.p = zi; exports.q = fe; exports.r = Ge; exports.s = C; exports.t = se; exports.u = v; exports.v = I; exports.w = oe; exports.x = ye; exports.y = W; exports.z = Je; exports.A = nt; exports.B = rt; exports.C = st; exports.D = ot; exports.E = lt; exports.F = dt; exports.G = be; exports.H = Le; exports.I = Pe; exports.J = Te; exports.K = Fe; exports.L = we; exports.M = Se; exports.N = Ce; exports.O = Ie; exports.P = Ee; exports.Q = ct; exports.R = gt; exports.S = ht; exports.T = qr;
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
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; } var _class; var _class2;"use client";
2
- var _chunkPLAFA6TTcjs = require('./chunk-PLAFA6TT.cjs');var b=(r=>(r.Paged="paged",r.Infinite="infinite",r))(b||{});var v=(i=>(i.FiltersChanged="FiltersChanged",i.ResultsLoaded="ResultsLoaded",i.PointClicked="PointClicked",i.BoundsChanged="BoundsChanged",i.LayerToggled="LayerToggled",i))(v||{});var h= (_class =class{__init() {this.listeners=new Set}constructor(t={}){;_class.prototype.__init.call(this);this.query={...t}}getQuery(){return{...this.query}}setQuery(t){this.query={...t},this.notify()}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}notify(){for(let t of[...this.listeners])t()}}, _class);function F(e,t){let r=new Set([...Object.keys(e),...Object.keys(t)]);for(let s of r)if(e[s]!==t[s])return!1;return!0}var f= (_class2 =class{__init2() {this.isSyncing=!1}__init3() {this.unsubscribeEngine=null}__init4() {this.unsubscribeHistory=null}constructor(t){;_class2.prototype.__init2.call(this);_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);this.history=t.history,this.toQueryFn=t.toQuery,this.toFiltersFn=t.toFilters,this.hydrateOnStart=_nullishCoalesce(t.hydrateOnStart, () => (!0))}start(t){this.stop(),this.unsubscribeEngine=t.subscribe(()=>{this.isSyncing||this.syncEngineToHistory(t)}),this.unsubscribeHistory=this.history.subscribe(()=>{this.isSyncing||this.withSyncGuard(()=>{this.applyFiltersSafely(t,this.toFiltersFn(this.history.getQuery()))})}),this.hydrateOnStart&&this.withSyncGuard(()=>{this.applyFiltersSafely(t,this.toFiltersFn(this.history.getQuery()))})}stop(){_optionalChain([this, 'access', _ => _.unsubscribeEngine, 'optionalCall', _2 => _2()]),this.unsubscribeEngine=null,_optionalChain([this, 'access', _3 => _3.unsubscribeHistory, 'optionalCall', _4 => _4()]),this.unsubscribeHistory=null}syncEngineToHistory(t){let r=this.toQueryFn(t.state.filters);F(r,this.history.getQuery())||this.withSyncGuard(()=>this.history.setQuery(r))}applyFiltersSafely(t,r){Promise.resolve(t.applyFilters(r)).catch(()=>{})}withSyncGuard(t){this.isSyncing=!0;try{t()}finally{this.isSyncing=!1}}}, _class2);var m=class{constructor(t={}){this.mode=_nullishCoalesce(t.mode, () => ("replace"))}getQuery(){if(typeof window>"u")return{};let t=new URLSearchParams(window.location.search),r={};for(let[s,o]of t)o!==""&&(r[s]=o);return r}setQuery(t){if(typeof window>"u")return;let r=new URLSearchParams;for(let[c,l]of Object.entries(t))l===void 0||l===""||r.set(c,l);let s=r.toString(),o=s?`?${s}`:"";if(o===window.location.search)return;let i=`${window.location.pathname}${o}${window.location.hash}`;this.mode==="push"?window.history.pushState(window.history.state,"",i):window.history.replaceState(window.history.state,"",i)}subscribe(t){return typeof window>"u"?()=>{}:(window.addEventListener("popstate",t),()=>{window.removeEventListener("popstate",t)})}};var _jsxruntime = require('react/jsx-runtime');function st({children:e}){let{Toolbar:t}=_chunkPLAFA6TTcjs.r.call(void 0, );return _jsxruntime.jsx.call(void 0, t,{children:e})}var _react = require('react');function ut(){let e=_chunkPLAFA6TTcjs.t.call(void 0, ),t=_chunkPLAFA6TTcjs.u.call(void 0, ),r=_react.useCallback.call(void 0, n=>e.loadPoints(n),[e]),s=_react.useCallback.call(void 0, (n,p)=>e.selectPoint(n,p),[e]),o=_react.useCallback.call(void 0, n=>e.setHovered(e.primaryDatasetId,n),[e]),i=_react.useCallback.call(void 0, ()=>_optionalChain([e, 'access', _5 => _5.map, 'optionalAccess', _6 => _6.zoomIn, 'call', _7 => _7()]),[e]),c=_react.useCallback.call(void 0, ()=>_optionalChain([e, 'access', _8 => _8.map, 'optionalAccess', _9 => _9.zoomOut, 'call', _10 => _10()]),[e]),l=_react.useCallback.call(void 0, ()=>_optionalChain([e, 'access', _11 => _11.map, 'optionalAccess', _12 => _12.toggleFullscreen, 'call', _13 => _13()]),[e]),g=_react.useCallback.call(void 0, (n,p)=>e.fitBounds(n,p),[e]);return{bounds:t.bounds,points:t.points,hovered:t.hovered,loadPoints:r,selectPoint:s,setHovered:o,zoomIn:i,zoomOut:c,toggleFullscreen:l,fitBounds:g}}function ht(e){let t=_chunkPLAFA6TTcjs.t.call(void 0, ),r=_chunkPLAFA6TTcjs.u.call(void 0, ),s=_react.useCallback.call(void 0, ()=>t.toggleLayer(e),[t,e]);return{visible:_nullishCoalesce(r.layers[e], () => (!0)),points:_nullishCoalesce(r.points[e], () => ([])),toggle:s}}exports.BrowserHistoryPort = m; exports.DatasetRegistry = _chunkPLAFA6TTcjs.c; exports.FallbackPopup = _chunkPLAFA6TTcjs.p; exports.FilterRegistry = _chunkPLAFA6TTcjs.b; exports.ListingApp = _chunkPLAFA6TTcjs.S; exports.ListingComponentsProvider = _chunkPLAFA6TTcjs.q; exports.ListingConfig = _chunkPLAFA6TTcjs.f; exports.ListingEngine = _chunkPLAFA6TTcjs.g; exports.ListingEngineContext = _chunkPLAFA6TTcjs.s; exports.ListingEventType = v; exports.ListingFilters = _chunkPLAFA6TTcjs.w; exports.ListingList = _chunkPLAFA6TTcjs.y; exports.ListingMap = _chunkPLAFA6TTcjs.z; exports.ListingPagination = _chunkPLAFA6TTcjs.A; exports.ListingProvider = _chunkPLAFA6TTcjs.D; exports.ListingResultHeader = _chunkPLAFA6TTcjs.B; exports.ListingStore = _chunkPLAFA6TTcjs.a; exports.ListingToolbar = st; exports.MemoryHistoryPort = h; exports.PaginationMode = b; exports.TypedEmitter = _chunkPLAFA6TTcjs.d; exports.UrlSyncController = f; exports.composeListingProviders = _chunkPLAFA6TTcjs.h; exports.listingDefaultConfig = _chunkPLAFA6TTcjs.e; exports.useListing = _chunkPLAFA6TTcjs.t; exports.useListingComponents = _chunkPLAFA6TTcjs.r; exports.useListingEvent = _chunkPLAFA6TTcjs.C; exports.useListingFilters = _chunkPLAFA6TTcjs.v; exports.useListingLayer = ht; exports.useListingMap = ut; exports.useListingResults = _chunkPLAFA6TTcjs.x; exports.useListingState = _chunkPLAFA6TTcjs.u; exports.withConfig = _chunkPLAFA6TTcjs.i; exports.withDataset = _chunkPLAFA6TTcjs.k; exports.withFilters = _chunkPLAFA6TTcjs.l; exports.withInitialFilters = _chunkPLAFA6TTcjs.n; exports.withMap = _chunkPLAFA6TTcjs.j; exports.withPrimaryDataset = _chunkPLAFA6TTcjs.o; exports.withUrlSync = _chunkPLAFA6TTcjs.m;
2
+ var _chunkX6UVZ2ENcjs = require('./chunk-X6UVZ2EN.cjs');var b=(r=>(r.Paged="paged",r.Infinite="infinite",r))(b||{});var v=(i=>(i.FiltersChanged="FiltersChanged",i.ResultsLoaded="ResultsLoaded",i.PointClicked="PointClicked",i.BoundsChanged="BoundsChanged",i.LayerToggled="LayerToggled",i))(v||{});var h= (_class =class{__init() {this.listeners=new Set}constructor(t={}){;_class.prototype.__init.call(this);this.query={...t}}getQuery(){return{...this.query}}setQuery(t){this.query={...t},this.notify()}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}notify(){for(let t of[...this.listeners])t()}}, _class);function F(e,t){let r=new Set([...Object.keys(e),...Object.keys(t)]);for(let s of r)if(e[s]!==t[s])return!1;return!0}var f= (_class2 =class{__init2() {this.isSyncing=!1}__init3() {this.unsubscribeEngine=null}__init4() {this.unsubscribeHistory=null}constructor(t){;_class2.prototype.__init2.call(this);_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);this.history=t.history,this.toQueryFn=t.toQuery,this.toFiltersFn=t.toFilters,this.hydrateOnStart=_nullishCoalesce(t.hydrateOnStart, () => (!0))}start(t){this.stop(),this.unsubscribeEngine=t.subscribe(()=>{this.isSyncing||this.syncEngineToHistory(t)}),this.unsubscribeHistory=this.history.subscribe(()=>{this.isSyncing||this.withSyncGuard(()=>{this.applyFiltersSafely(t,this.toFiltersFn(this.history.getQuery()))})}),this.hydrateOnStart&&this.withSyncGuard(()=>{this.applyFiltersSafely(t,this.toFiltersFn(this.history.getQuery()))})}stop(){_optionalChain([this, 'access', _ => _.unsubscribeEngine, 'optionalCall', _2 => _2()]),this.unsubscribeEngine=null,_optionalChain([this, 'access', _3 => _3.unsubscribeHistory, 'optionalCall', _4 => _4()]),this.unsubscribeHistory=null}syncEngineToHistory(t){let r=this.toQueryFn(t.state.filters);F(r,this.history.getQuery())||this.withSyncGuard(()=>this.history.setQuery(r))}applyFiltersSafely(t,r){Promise.resolve(t.applyFilters(r)).catch(()=>{})}withSyncGuard(t){this.isSyncing=!0;try{t()}finally{this.isSyncing=!1}}}, _class2);var m=class{constructor(t={}){this.mode=_nullishCoalesce(t.mode, () => ("replace"))}getQuery(){if(typeof window>"u")return{};let t=new URLSearchParams(window.location.search),r={};for(let[s,o]of t)o!==""&&(r[s]=o);return r}setQuery(t){if(typeof window>"u")return;let r=new URLSearchParams;for(let[c,l]of Object.entries(t))l===void 0||l===""||r.set(c,l);let s=r.toString(),o=s?`?${s}`:"";if(o===window.location.search)return;let i=`${window.location.pathname}${o}${window.location.hash}`;this.mode==="push"?window.history.pushState(window.history.state,"",i):window.history.replaceState(window.history.state,"",i)}subscribe(t){return typeof window>"u"?()=>{}:(window.addEventListener("popstate",t),()=>{window.removeEventListener("popstate",t)})}};var _jsxruntime = require('react/jsx-runtime');function it({children:e}){let{Toolbar:t}=_chunkX6UVZ2ENcjs.s.call(void 0, );return _jsxruntime.jsx.call(void 0, t,{children:e})}var _react = require('react');function yt(){let e=_chunkX6UVZ2ENcjs.u.call(void 0, ),t=_chunkX6UVZ2ENcjs.v.call(void 0, ),r=_react.useCallback.call(void 0, n=>e.loadPoints(n),[e]),s=_react.useCallback.call(void 0, (n,p)=>e.selectPoint(n,p),[e]),o=_react.useCallback.call(void 0, n=>e.setHovered(e.primaryDatasetId,n),[e]),i=_react.useCallback.call(void 0, ()=>_optionalChain([e, 'access', _5 => _5.map, 'optionalAccess', _6 => _6.zoomIn, 'call', _7 => _7()]),[e]),c=_react.useCallback.call(void 0, ()=>_optionalChain([e, 'access', _8 => _8.map, 'optionalAccess', _9 => _9.zoomOut, 'call', _10 => _10()]),[e]),l=_react.useCallback.call(void 0, ()=>_optionalChain([e, 'access', _11 => _11.map, 'optionalAccess', _12 => _12.toggleFullscreen, 'call', _13 => _13()]),[e]),g=_react.useCallback.call(void 0, (n,p)=>e.fitBounds(n,p),[e]);return{bounds:t.bounds,points:t.points,hovered:t.hovered,loadPoints:r,selectPoint:s,setHovered:o,zoomIn:i,zoomOut:c,toggleFullscreen:l,fitBounds:g}}function ft(e){let t=_chunkX6UVZ2ENcjs.u.call(void 0, ),r=_chunkX6UVZ2ENcjs.v.call(void 0, ),s=_react.useCallback.call(void 0, ()=>t.toggleLayer(e),[t,e]);return{visible:_nullishCoalesce(r.layers[e], () => (!0)),points:_nullishCoalesce(r.points[e], () => ([])),toggle:s}}exports.BrowserHistoryPort = m; exports.DatasetRegistry = _chunkX6UVZ2ENcjs.c; exports.FallbackPopup = _chunkX6UVZ2ENcjs.q; exports.FilterRegistry = _chunkX6UVZ2ENcjs.b; exports.ListingApp = _chunkX6UVZ2ENcjs.T; exports.ListingComponentsProvider = _chunkX6UVZ2ENcjs.r; exports.ListingConfig = _chunkX6UVZ2ENcjs.f; exports.ListingEngine = _chunkX6UVZ2ENcjs.g; exports.ListingEngineContext = _chunkX6UVZ2ENcjs.t; exports.ListingEventType = v; exports.ListingFilters = _chunkX6UVZ2ENcjs.x; exports.ListingList = _chunkX6UVZ2ENcjs.z; exports.ListingMap = _chunkX6UVZ2ENcjs.A; exports.ListingPagination = _chunkX6UVZ2ENcjs.B; exports.ListingProvider = _chunkX6UVZ2ENcjs.E; exports.ListingResultHeader = _chunkX6UVZ2ENcjs.C; exports.ListingStore = _chunkX6UVZ2ENcjs.a; exports.ListingToolbar = it; exports.MemoryHistoryPort = h; exports.PaginationMode = b; exports.TypedEmitter = _chunkX6UVZ2ENcjs.d; exports.UrlSyncController = f; exports.composeListingProviders = _chunkX6UVZ2ENcjs.h; exports.listingDefaultConfig = _chunkX6UVZ2ENcjs.e; exports.useListing = _chunkX6UVZ2ENcjs.u; exports.useListingComponents = _chunkX6UVZ2ENcjs.s; exports.useListingEvent = _chunkX6UVZ2ENcjs.D; exports.useListingFilters = _chunkX6UVZ2ENcjs.w; exports.useListingLayer = ft; exports.useListingMap = yt; exports.useListingResults = _chunkX6UVZ2ENcjs.y; exports.useListingState = _chunkX6UVZ2ENcjs.v; exports.withConfig = _chunkX6UVZ2ENcjs.i; exports.withDataset = _chunkX6UVZ2ENcjs.k; exports.withFilters = _chunkX6UVZ2ENcjs.l; exports.withInitialFilters = _chunkX6UVZ2ENcjs.n; exports.withInitialResults = _chunkX6UVZ2ENcjs.o; exports.withMap = _chunkX6UVZ2ENcjs.j; exports.withPrimaryDataset = _chunkX6UVZ2ENcjs.p; exports.withUrlSync = _chunkX6UVZ2ENcjs.m;
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { P as Page, B as Bounds, E as EntityId, M as MapPoint, U as Unsubscribe, a as MapProvider, b as MapHandle, F as FitBoundsOptions, Q as QueryParams, L as LatLng } from './map-provider.interface-D3pwkbog.cjs';
2
2
  export { c as EntityAdapter, d as MapInitOptions, e as MapOverlayHandle, f as PageRequest, R as RenderedLayer } from './map-provider.interface-D3pwkbog.cjs';
3
- import { P as PaginationMode, D as DatasetDefinition, I as IListingConfigOptions, F as FilterRegistry, a as IListingToolbarProps } from './listing-app-By6TrXB9.cjs';
4
- export { C as ClusterOptions, b as FallbackPopup, c as FilterControlProps, d as FilterDefinition, e as IListingBottomNavProps, f as IListingCardProps, g as IListingComponents, h as IListingEmptyProps, i as IListingFilterPanelProps, j as IListingLoadingProps, k as IListingMarkerProps, l as IListingPopupProps, m as IListingResultHeaderProps, n as IListingSearchProps, o as IListingSidebarProps, L as ListingApp, p as ListingAppProps, q as ListingComponentsProvider, M as MarkerRenderer, r as MobileSheetFooterContext, u as useListingComponents } from './listing-app-By6TrXB9.cjs';
3
+ import { P as PaginationMode, D as DatasetDefinition, I as IListingConfigOptions, F as FilterRegistry, a as IListingToolbarProps } from './listing-app-DbXiww1I.cjs';
4
+ export { C as ClusterOptions, b as FallbackPopup, c as FilterControlProps, d as FilterDefinition, e as IListingBottomNavProps, f as IListingCardProps, g as IListingComponents, h as IListingEmptyProps, i as IListingFilterPanelProps, j as IListingLoadingProps, k as IListingMarkerProps, l as IListingPopupProps, m as IListingResultHeaderProps, n as IListingSearchProps, o as IListingSidebarProps, L as ListingApp, p as ListingAppProps, q as ListingComponentsProvider, M as MarkerRenderer, r as MobileSheetFooterContext, u as useListingComponents } from './listing-app-DbXiww1I.cjs';
5
5
  import * as react from 'react';
6
6
  import { ReactNode } from 'react';
7
7
 
@@ -27,9 +27,18 @@ interface ListingState<TEntity, TFilters> {
27
27
  layers: Record<string, boolean>;
28
28
  points: Readonly<Record<string, ReadonlyArray<MapPoint<unknown>>>>;
29
29
  }
30
- interface ListingStoreInit<TFilters> {
30
+ interface ListingStoreInit<TEntity, TFilters> {
31
31
  filters: TFilters;
32
32
  mode?: PaginationMode;
33
+ /**
34
+ * First page to start from, instead of the empty list a fetch would replace.
35
+ *
36
+ * Exists so a consumer that already has page one -- typically because it
37
+ * rendered on a server -- can hand it over and have the FIRST render carry
38
+ * real results. Without it the only way to fill the list is the adapter, and
39
+ * an adapter call cannot happen during a server render.
40
+ */
41
+ results?: Page<TEntity>;
33
42
  }
34
43
  type Listener$1 = () => void;
35
44
  type DeepReadonly<T> = T extends (infer U)[] ? ReadonlyArray<DeepReadonly<U>> : T extends object ? {
@@ -38,7 +47,7 @@ type DeepReadonly<T> = T extends (infer U)[] ? ReadonlyArray<DeepReadonly<U>> :
38
47
  declare class ListingStore<TEntity, TFilters> {
39
48
  private state;
40
49
  private readonly listeners;
41
- constructor(init: ListingStoreInit<TFilters>);
50
+ constructor(init: ListingStoreInit<TEntity, TFilters>);
42
51
  getState(): DeepReadonly<ListingState<TEntity, TFilters>>;
43
52
  setFilters(patch: Partial<TFilters>): void;
44
53
  setResults(page: Page<TEntity>): void;
@@ -135,6 +144,8 @@ interface ListingEngineOptions<TFilters> {
135
144
  config?: Partial<IListingConfigOptions>;
136
145
  map?: MapProvider;
137
146
  initialFilters?: TFilters;
147
+ /** First page to start from -- see `ListingStoreInit.results`. */
148
+ initialResults?: Page<unknown>;
138
149
  primaryDatasetId?: string;
139
150
  }
140
151
  /**
@@ -160,6 +171,7 @@ declare class ListingEngine<TEntity, TFilters> {
160
171
  readonly datasets: DatasetRegistry<unknown, TFilters>;
161
172
  readonly primaryDatasetId: string;
162
173
  private readonly store;
174
+ private disposed;
163
175
  private readonly emitter;
164
176
  private readonly config;
165
177
  private debounceTimer;
@@ -238,6 +250,10 @@ declare class ListingEngine<TEntity, TFilters> {
238
250
  toggleLayer(id: string): void;
239
251
  subscribe(cb: () => void): () => void;
240
252
  on(type: ListingEvent<TEntity, TFilters>['type'] | '*', cb: (e: ListingEvent<TEntity, TFilters>) => void): () => void;
253
+ /** True once `dispose()` has run. A disposed engine's emitter is dead, so it
254
+ * can never drive a UI again -- see `ListingProvider`, which uses this to
255
+ * tell a live engine from one Strict Mode already tore down. */
256
+ get isDisposed(): boolean;
241
257
  dispose(): void;
242
258
  private runQuery;
243
259
  private primaryDataset;
@@ -368,6 +384,7 @@ interface IListingProviderProps<TFilters> {
368
384
  map?: MapProvider;
369
385
  urlSync?: UrlSyncController<TFilters>;
370
386
  initialFilters?: TFilters;
387
+ initialResults?: Page<unknown>;
371
388
  primaryDatasetId?: string;
372
389
  }
373
390
  /**
@@ -382,6 +399,14 @@ declare const withDataset: <TEntity, TFilters>(def: DatasetDefinition<TEntity, T
382
399
  declare const withFilters: <TFilters>(fn: (reg: FilterRegistry<TFilters>) => void) => ListingProviderMod<TFilters>;
383
400
  declare const withUrlSync: <TFilters>(controller: UrlSyncController<TFilters>) => ListingProviderMod<TFilters>;
384
401
  declare const withInitialFilters: <TFilters>(filters: TFilters) => ListingProviderMod<TFilters>;
402
+ /**
403
+ * Seeds the first page so the initial render already has results.
404
+ *
405
+ * For server-rendered consumers: pair with `autoFetch={false}` (or the styled
406
+ * layout, which skips its mount fetch automatically when seeded) so the list
407
+ * hydrates from these rows instead of blanking and refetching.
408
+ */
409
+ declare const withInitialResults: <TFilters>(page: Page<unknown>) => ListingProviderMod<TFilters>;
385
410
  declare const withPrimaryDataset: <TFilters>(id: string) => ListingProviderMod<TFilters>;
386
411
 
387
412
  interface BrowserHistoryPortOptions {
@@ -897,6 +922,6 @@ interface IListingProviderComponentProps<TFilters> extends IListingProviderProps
897
922
  * </ListingProvider>
898
923
  * ```
899
924
  */
900
- declare function ListingProvider<TEntity, TFilters>(props: IListingProviderComponentProps<TFilters>): react.JSX.Element | null;
925
+ declare function ListingProvider<TEntity, TFilters>(props: IListingProviderComponentProps<TFilters>): react.JSX.Element;
901
926
 
902
- export { Bounds, BrowserHistoryPort, type BrowserHistoryPortOptions, DatasetDefinition, DatasetRegistry, EntityId, FilterRegistry, FitBoundsOptions, type HistoryPort, IListingConfigOptions, type IListingFiltersProps, type IListingMapProps, type IListingProviderProps, IListingToolbarProps, LatLng, ListingConfig, ListingEngine, ListingEngineContext, type ListingEngineOptions, type ListingEvent, ListingEventType, ListingFilters, ListingList, ListingMap, ListingPagination, ListingProvider, type ListingProviderMod, ListingResultHeader, type ListingState, ListingStore, type ListingStoreInit, ListingToolbar, MapHandle, MapPoint, MapProvider, MemoryHistoryPort, Page, PaginationMode, QueryParams, TypedEmitter, Unsubscribe, UrlSyncController, type UrlSyncEngine, type UrlSyncOptions, composeListingProviders, listingDefaultConfig, useListing, useListingEvent, useListingFilters, useListingLayer, useListingMap, useListingResults, useListingState, withConfig, withDataset, withFilters, withInitialFilters, withMap, withPrimaryDataset, withUrlSync };
927
+ export { Bounds, BrowserHistoryPort, type BrowserHistoryPortOptions, DatasetDefinition, DatasetRegistry, EntityId, FilterRegistry, FitBoundsOptions, type HistoryPort, IListingConfigOptions, type IListingFiltersProps, type IListingMapProps, type IListingProviderProps, IListingToolbarProps, LatLng, ListingConfig, ListingEngine, ListingEngineContext, type ListingEngineOptions, type ListingEvent, ListingEventType, ListingFilters, ListingList, ListingMap, ListingPagination, ListingProvider, type ListingProviderMod, ListingResultHeader, type ListingState, ListingStore, type ListingStoreInit, ListingToolbar, MapHandle, MapPoint, MapProvider, MemoryHistoryPort, Page, PaginationMode, QueryParams, TypedEmitter, Unsubscribe, UrlSyncController, type UrlSyncEngine, type UrlSyncOptions, composeListingProviders, listingDefaultConfig, useListing, useListingEvent, useListingFilters, useListingLayer, useListingMap, useListingResults, useListingState, withConfig, withDataset, withFilters, withInitialFilters, withInitialResults, withMap, withPrimaryDataset, withUrlSync };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { P as Page, B as Bounds, E as EntityId, M as MapPoint, U as Unsubscribe, a as MapProvider, b as MapHandle, F as FitBoundsOptions, Q as QueryParams, L as LatLng } from './map-provider.interface-D3pwkbog.js';
2
2
  export { c as EntityAdapter, d as MapInitOptions, e as MapOverlayHandle, f as PageRequest, R as RenderedLayer } from './map-provider.interface-D3pwkbog.js';
3
- import { P as PaginationMode, D as DatasetDefinition, I as IListingConfigOptions, F as FilterRegistry, a as IListingToolbarProps } from './listing-app-CHC-XAhJ.js';
4
- export { C as ClusterOptions, b as FallbackPopup, c as FilterControlProps, d as FilterDefinition, e as IListingBottomNavProps, f as IListingCardProps, g as IListingComponents, h as IListingEmptyProps, i as IListingFilterPanelProps, j as IListingLoadingProps, k as IListingMarkerProps, l as IListingPopupProps, m as IListingResultHeaderProps, n as IListingSearchProps, o as IListingSidebarProps, L as ListingApp, p as ListingAppProps, q as ListingComponentsProvider, M as MarkerRenderer, r as MobileSheetFooterContext, u as useListingComponents } from './listing-app-CHC-XAhJ.js';
3
+ import { P as PaginationMode, D as DatasetDefinition, I as IListingConfigOptions, F as FilterRegistry, a as IListingToolbarProps } from './listing-app-Cm4F8Gd_.js';
4
+ export { C as ClusterOptions, b as FallbackPopup, c as FilterControlProps, d as FilterDefinition, e as IListingBottomNavProps, f as IListingCardProps, g as IListingComponents, h as IListingEmptyProps, i as IListingFilterPanelProps, j as IListingLoadingProps, k as IListingMarkerProps, l as IListingPopupProps, m as IListingResultHeaderProps, n as IListingSearchProps, o as IListingSidebarProps, L as ListingApp, p as ListingAppProps, q as ListingComponentsProvider, M as MarkerRenderer, r as MobileSheetFooterContext, u as useListingComponents } from './listing-app-Cm4F8Gd_.js';
5
5
  import * as react from 'react';
6
6
  import { ReactNode } from 'react';
7
7
 
@@ -27,9 +27,18 @@ interface ListingState<TEntity, TFilters> {
27
27
  layers: Record<string, boolean>;
28
28
  points: Readonly<Record<string, ReadonlyArray<MapPoint<unknown>>>>;
29
29
  }
30
- interface ListingStoreInit<TFilters> {
30
+ interface ListingStoreInit<TEntity, TFilters> {
31
31
  filters: TFilters;
32
32
  mode?: PaginationMode;
33
+ /**
34
+ * First page to start from, instead of the empty list a fetch would replace.
35
+ *
36
+ * Exists so a consumer that already has page one -- typically because it
37
+ * rendered on a server -- can hand it over and have the FIRST render carry
38
+ * real results. Without it the only way to fill the list is the adapter, and
39
+ * an adapter call cannot happen during a server render.
40
+ */
41
+ results?: Page<TEntity>;
33
42
  }
34
43
  type Listener$1 = () => void;
35
44
  type DeepReadonly<T> = T extends (infer U)[] ? ReadonlyArray<DeepReadonly<U>> : T extends object ? {
@@ -38,7 +47,7 @@ type DeepReadonly<T> = T extends (infer U)[] ? ReadonlyArray<DeepReadonly<U>> :
38
47
  declare class ListingStore<TEntity, TFilters> {
39
48
  private state;
40
49
  private readonly listeners;
41
- constructor(init: ListingStoreInit<TFilters>);
50
+ constructor(init: ListingStoreInit<TEntity, TFilters>);
42
51
  getState(): DeepReadonly<ListingState<TEntity, TFilters>>;
43
52
  setFilters(patch: Partial<TFilters>): void;
44
53
  setResults(page: Page<TEntity>): void;
@@ -135,6 +144,8 @@ interface ListingEngineOptions<TFilters> {
135
144
  config?: Partial<IListingConfigOptions>;
136
145
  map?: MapProvider;
137
146
  initialFilters?: TFilters;
147
+ /** First page to start from -- see `ListingStoreInit.results`. */
148
+ initialResults?: Page<unknown>;
138
149
  primaryDatasetId?: string;
139
150
  }
140
151
  /**
@@ -160,6 +171,7 @@ declare class ListingEngine<TEntity, TFilters> {
160
171
  readonly datasets: DatasetRegistry<unknown, TFilters>;
161
172
  readonly primaryDatasetId: string;
162
173
  private readonly store;
174
+ private disposed;
163
175
  private readonly emitter;
164
176
  private readonly config;
165
177
  private debounceTimer;
@@ -238,6 +250,10 @@ declare class ListingEngine<TEntity, TFilters> {
238
250
  toggleLayer(id: string): void;
239
251
  subscribe(cb: () => void): () => void;
240
252
  on(type: ListingEvent<TEntity, TFilters>['type'] | '*', cb: (e: ListingEvent<TEntity, TFilters>) => void): () => void;
253
+ /** True once `dispose()` has run. A disposed engine's emitter is dead, so it
254
+ * can never drive a UI again -- see `ListingProvider`, which uses this to
255
+ * tell a live engine from one Strict Mode already tore down. */
256
+ get isDisposed(): boolean;
241
257
  dispose(): void;
242
258
  private runQuery;
243
259
  private primaryDataset;
@@ -368,6 +384,7 @@ interface IListingProviderProps<TFilters> {
368
384
  map?: MapProvider;
369
385
  urlSync?: UrlSyncController<TFilters>;
370
386
  initialFilters?: TFilters;
387
+ initialResults?: Page<unknown>;
371
388
  primaryDatasetId?: string;
372
389
  }
373
390
  /**
@@ -382,6 +399,14 @@ declare const withDataset: <TEntity, TFilters>(def: DatasetDefinition<TEntity, T
382
399
  declare const withFilters: <TFilters>(fn: (reg: FilterRegistry<TFilters>) => void) => ListingProviderMod<TFilters>;
383
400
  declare const withUrlSync: <TFilters>(controller: UrlSyncController<TFilters>) => ListingProviderMod<TFilters>;
384
401
  declare const withInitialFilters: <TFilters>(filters: TFilters) => ListingProviderMod<TFilters>;
402
+ /**
403
+ * Seeds the first page so the initial render already has results.
404
+ *
405
+ * For server-rendered consumers: pair with `autoFetch={false}` (or the styled
406
+ * layout, which skips its mount fetch automatically when seeded) so the list
407
+ * hydrates from these rows instead of blanking and refetching.
408
+ */
409
+ declare const withInitialResults: <TFilters>(page: Page<unknown>) => ListingProviderMod<TFilters>;
385
410
  declare const withPrimaryDataset: <TFilters>(id: string) => ListingProviderMod<TFilters>;
386
411
 
387
412
  interface BrowserHistoryPortOptions {
@@ -897,6 +922,6 @@ interface IListingProviderComponentProps<TFilters> extends IListingProviderProps
897
922
  * </ListingProvider>
898
923
  * ```
899
924
  */
900
- declare function ListingProvider<TEntity, TFilters>(props: IListingProviderComponentProps<TFilters>): react.JSX.Element | null;
925
+ declare function ListingProvider<TEntity, TFilters>(props: IListingProviderComponentProps<TFilters>): react.JSX.Element;
901
926
 
902
- export { Bounds, BrowserHistoryPort, type BrowserHistoryPortOptions, DatasetDefinition, DatasetRegistry, EntityId, FilterRegistry, FitBoundsOptions, type HistoryPort, IListingConfigOptions, type IListingFiltersProps, type IListingMapProps, type IListingProviderProps, IListingToolbarProps, LatLng, ListingConfig, ListingEngine, ListingEngineContext, type ListingEngineOptions, type ListingEvent, ListingEventType, ListingFilters, ListingList, ListingMap, ListingPagination, ListingProvider, type ListingProviderMod, ListingResultHeader, type ListingState, ListingStore, type ListingStoreInit, ListingToolbar, MapHandle, MapPoint, MapProvider, MemoryHistoryPort, Page, PaginationMode, QueryParams, TypedEmitter, Unsubscribe, UrlSyncController, type UrlSyncEngine, type UrlSyncOptions, composeListingProviders, listingDefaultConfig, useListing, useListingEvent, useListingFilters, useListingLayer, useListingMap, useListingResults, useListingState, withConfig, withDataset, withFilters, withInitialFilters, withMap, withPrimaryDataset, withUrlSync };
927
+ export { Bounds, BrowserHistoryPort, type BrowserHistoryPortOptions, DatasetDefinition, DatasetRegistry, EntityId, FilterRegistry, FitBoundsOptions, type HistoryPort, IListingConfigOptions, type IListingFiltersProps, type IListingMapProps, type IListingProviderProps, IListingToolbarProps, LatLng, ListingConfig, ListingEngine, ListingEngineContext, type ListingEngineOptions, type ListingEvent, ListingEventType, ListingFilters, ListingList, ListingMap, ListingPagination, ListingProvider, type ListingProviderMod, ListingResultHeader, type ListingState, ListingStore, type ListingStoreInit, ListingToolbar, MapHandle, MapPoint, MapProvider, MemoryHistoryPort, Page, PaginationMode, QueryParams, TypedEmitter, Unsubscribe, UrlSyncController, type UrlSyncEngine, type UrlSyncOptions, composeListingProviders, listingDefaultConfig, useListing, useListingEvent, useListingFilters, useListingLayer, useListingMap, useListingResults, useListingState, withConfig, withDataset, withFilters, withInitialFilters, withInitialResults, withMap, withPrimaryDataset, withUrlSync };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{A as V,B as W,C as X,D as Y,S as P,a as Q,b as x,c as T,d as L,e as O,f as H,g as E,h as k,i as q,j as B,k as C,l as I,m as U,n as z,o as G,p as R,q as $,r as d,s as j,t as u,u as y,v as A,w as D,x as J,y as K,z as N}from"./chunk-XJBDGG2S.js";var b=(r=>(r.Paged="paged",r.Infinite="infinite",r))(b||{});var v=(i=>(i.FiltersChanged="FiltersChanged",i.ResultsLoaded="ResultsLoaded",i.PointClicked="PointClicked",i.BoundsChanged="BoundsChanged",i.LayerToggled="LayerToggled",i))(v||{});var h=class{query;listeners=new Set;constructor(t={}){this.query={...t}}getQuery(){return{...this.query}}setQuery(t){this.query={...t},this.notify()}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}notify(){for(let t of[...this.listeners])t()}};function F(e,t){let r=new Set([...Object.keys(e),...Object.keys(t)]);for(let s of r)if(e[s]!==t[s])return!1;return!0}var f=class{history;toQueryFn;toFiltersFn;hydrateOnStart;isSyncing=!1;unsubscribeEngine=null;unsubscribeHistory=null;constructor(t){this.history=t.history,this.toQueryFn=t.toQuery,this.toFiltersFn=t.toFilters,this.hydrateOnStart=t.hydrateOnStart??!0}start(t){this.stop(),this.unsubscribeEngine=t.subscribe(()=>{this.isSyncing||this.syncEngineToHistory(t)}),this.unsubscribeHistory=this.history.subscribe(()=>{this.isSyncing||this.withSyncGuard(()=>{this.applyFiltersSafely(t,this.toFiltersFn(this.history.getQuery()))})}),this.hydrateOnStart&&this.withSyncGuard(()=>{this.applyFiltersSafely(t,this.toFiltersFn(this.history.getQuery()))})}stop(){this.unsubscribeEngine?.(),this.unsubscribeEngine=null,this.unsubscribeHistory?.(),this.unsubscribeHistory=null}syncEngineToHistory(t){let r=this.toQueryFn(t.state.filters);F(r,this.history.getQuery())||this.withSyncGuard(()=>this.history.setQuery(r))}applyFiltersSafely(t,r){Promise.resolve(t.applyFilters(r)).catch(()=>{})}withSyncGuard(t){this.isSyncing=!0;try{t()}finally{this.isSyncing=!1}}};var m=class{mode;constructor(t={}){this.mode=t.mode??"replace"}getQuery(){if(typeof window>"u")return{};let t=new URLSearchParams(window.location.search),r={};for(let[s,o]of t)o!==""&&(r[s]=o);return r}setQuery(t){if(typeof window>"u")return;let r=new URLSearchParams;for(let[c,l]of Object.entries(t))l===void 0||l===""||r.set(c,l);let s=r.toString(),o=s?`?${s}`:"";if(o===window.location.search)return;let i=`${window.location.pathname}${o}${window.location.hash}`;this.mode==="push"?window.history.pushState(window.history.state,"",i):window.history.replaceState(window.history.state,"",i)}subscribe(t){return typeof window>"u"?()=>{}:(window.addEventListener("popstate",t),()=>{window.removeEventListener("popstate",t)})}};import{jsx as w}from"react/jsx-runtime";function st({children:e}){let{Toolbar:t}=d();return w(t,{children:e})}import{useCallback as a}from"react";function ut(){let e=u(),t=y(),r=a(n=>e.loadPoints(n),[e]),s=a((n,p)=>e.selectPoint(n,p),[e]),o=a(n=>e.setHovered(e.primaryDatasetId,n),[e]),i=a(()=>e.map?.zoomIn(),[e]),c=a(()=>e.map?.zoomOut(),[e]),l=a(()=>e.map?.toggleFullscreen(),[e]),g=a((n,p)=>e.fitBounds(n,p),[e]);return{bounds:t.bounds,points:t.points,hovered:t.hovered,loadPoints:r,selectPoint:s,setHovered:o,zoomIn:i,zoomOut:c,toggleFullscreen:l,fitBounds:g}}import{useCallback as S}from"react";function ht(e){let t=u(),r=y(),s=S(()=>t.toggleLayer(e),[t,e]);return{visible:r.layers[e]??!0,points:r.points[e]??[],toggle:s}}export{m as BrowserHistoryPort,T as DatasetRegistry,R as FallbackPopup,x as FilterRegistry,P as ListingApp,$ as ListingComponentsProvider,H as ListingConfig,E as ListingEngine,j as ListingEngineContext,v as ListingEventType,D as ListingFilters,K as ListingList,N as ListingMap,V as ListingPagination,Y as ListingProvider,W as ListingResultHeader,Q as ListingStore,st as ListingToolbar,h as MemoryHistoryPort,b as PaginationMode,L as TypedEmitter,f as UrlSyncController,k as composeListingProviders,O as listingDefaultConfig,u as useListing,d as useListingComponents,X as useListingEvent,A as useListingFilters,ht as useListingLayer,ut as useListingMap,J as useListingResults,y as useListingState,q as withConfig,C as withDataset,I as withFilters,z as withInitialFilters,B as withMap,G as withPrimaryDataset,U as withUrlSync};
2
+ import{A as V,B as W,C as X,D as Y,E as Z,T as P,a as Q,b as x,c as T,d as L,e as O,f as H,g as E,h as k,i as q,j as B,k as C,l as I,m as U,n as z,o as G,p as R,q as $,r as j,s as d,t as A,u,v as y,w as D,x as J,y as K,z as N}from"./chunk-VQADQ7N7.js";var b=(r=>(r.Paged="paged",r.Infinite="infinite",r))(b||{});var v=(i=>(i.FiltersChanged="FiltersChanged",i.ResultsLoaded="ResultsLoaded",i.PointClicked="PointClicked",i.BoundsChanged="BoundsChanged",i.LayerToggled="LayerToggled",i))(v||{});var h=class{query;listeners=new Set;constructor(t={}){this.query={...t}}getQuery(){return{...this.query}}setQuery(t){this.query={...t},this.notify()}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}notify(){for(let t of[...this.listeners])t()}};function F(e,t){let r=new Set([...Object.keys(e),...Object.keys(t)]);for(let s of r)if(e[s]!==t[s])return!1;return!0}var f=class{history;toQueryFn;toFiltersFn;hydrateOnStart;isSyncing=!1;unsubscribeEngine=null;unsubscribeHistory=null;constructor(t){this.history=t.history,this.toQueryFn=t.toQuery,this.toFiltersFn=t.toFilters,this.hydrateOnStart=t.hydrateOnStart??!0}start(t){this.stop(),this.unsubscribeEngine=t.subscribe(()=>{this.isSyncing||this.syncEngineToHistory(t)}),this.unsubscribeHistory=this.history.subscribe(()=>{this.isSyncing||this.withSyncGuard(()=>{this.applyFiltersSafely(t,this.toFiltersFn(this.history.getQuery()))})}),this.hydrateOnStart&&this.withSyncGuard(()=>{this.applyFiltersSafely(t,this.toFiltersFn(this.history.getQuery()))})}stop(){this.unsubscribeEngine?.(),this.unsubscribeEngine=null,this.unsubscribeHistory?.(),this.unsubscribeHistory=null}syncEngineToHistory(t){let r=this.toQueryFn(t.state.filters);F(r,this.history.getQuery())||this.withSyncGuard(()=>this.history.setQuery(r))}applyFiltersSafely(t,r){Promise.resolve(t.applyFilters(r)).catch(()=>{})}withSyncGuard(t){this.isSyncing=!0;try{t()}finally{this.isSyncing=!1}}};var m=class{mode;constructor(t={}){this.mode=t.mode??"replace"}getQuery(){if(typeof window>"u")return{};let t=new URLSearchParams(window.location.search),r={};for(let[s,o]of t)o!==""&&(r[s]=o);return r}setQuery(t){if(typeof window>"u")return;let r=new URLSearchParams;for(let[c,l]of Object.entries(t))l===void 0||l===""||r.set(c,l);let s=r.toString(),o=s?`?${s}`:"";if(o===window.location.search)return;let i=`${window.location.pathname}${o}${window.location.hash}`;this.mode==="push"?window.history.pushState(window.history.state,"",i):window.history.replaceState(window.history.state,"",i)}subscribe(t){return typeof window>"u"?()=>{}:(window.addEventListener("popstate",t),()=>{window.removeEventListener("popstate",t)})}};import{jsx as w}from"react/jsx-runtime";function it({children:e}){let{Toolbar:t}=d();return w(t,{children:e})}import{useCallback as a}from"react";function yt(){let e=u(),t=y(),r=a(n=>e.loadPoints(n),[e]),s=a((n,p)=>e.selectPoint(n,p),[e]),o=a(n=>e.setHovered(e.primaryDatasetId,n),[e]),i=a(()=>e.map?.zoomIn(),[e]),c=a(()=>e.map?.zoomOut(),[e]),l=a(()=>e.map?.toggleFullscreen(),[e]),g=a((n,p)=>e.fitBounds(n,p),[e]);return{bounds:t.bounds,points:t.points,hovered:t.hovered,loadPoints:r,selectPoint:s,setHovered:o,zoomIn:i,zoomOut:c,toggleFullscreen:l,fitBounds:g}}import{useCallback as S}from"react";function ft(e){let t=u(),r=y(),s=S(()=>t.toggleLayer(e),[t,e]);return{visible:r.layers[e]??!0,points:r.points[e]??[],toggle:s}}export{m as BrowserHistoryPort,T as DatasetRegistry,$ as FallbackPopup,x as FilterRegistry,P as ListingApp,j as ListingComponentsProvider,H as ListingConfig,E as ListingEngine,A as ListingEngineContext,v as ListingEventType,J as ListingFilters,N as ListingList,V as ListingMap,W as ListingPagination,Z as ListingProvider,X as ListingResultHeader,Q as ListingStore,it as ListingToolbar,h as MemoryHistoryPort,b as PaginationMode,L as TypedEmitter,f as UrlSyncController,k as composeListingProviders,O as listingDefaultConfig,u as useListing,d as useListingComponents,Y as useListingEvent,D as useListingFilters,ft as useListingLayer,yt as useListingMap,K as useListingResults,y as useListingState,q as withConfig,C as withDataset,I as withFilters,z as withInitialFilters,G as withInitialResults,B as withMap,R as withPrimaryDataset,U as withUrlSync};
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentType, ReactNode } from 'react';
3
- import { c as EntityAdapter, M as MapPoint, L as LatLng, a as MapProvider } from './map-provider.interface-D3pwkbog.cjs';
3
+ import { c as EntityAdapter, M as MapPoint, L as LatLng, a as MapProvider, P as Page } from './map-provider.interface-D3pwkbog.js';
4
4
 
5
5
  interface FilterControlProps<TValue> {
6
6
  value: TValue;
@@ -198,6 +198,25 @@ interface IStyledListingLayoutProps<TFilters = unknown> {
198
198
  filterBarStart?: ReactNode;
199
199
  /** Extra content rendered in `.rle-list-header` (above the list), to the right of `ListingResultHeader` (e.g. a sort control + save-search). */
200
200
  toolbarEnd?: ReactNode;
201
+ /**
202
+ * Replaces the ENTIRE results column -- header, grid and pagination -- with
203
+ * the given content, inside the same scrolling `.rle-list` container.
204
+ *
205
+ * For the states where a result list is the wrong thing to show at all, not
206
+ * merely a different-looking one: a viewport too wide for individual results
207
+ * to mean anything, an onboarding prompt, a saved-search upsell. `Empty` and
208
+ * `Loading` cannot express those, because both still sit inside the results
209
+ * column and leave its header, sort control and pager in place.
210
+ *
211
+ * Consumers previously had to hide `.rle-list-grid`,
212
+ * `.rle-list-header__toolbar` and `.rle-pagination` with their own CSS,
213
+ * which made three internal class names part of the public contract by
214
+ * accident.
215
+ *
216
+ * The map is unaffected -- give a dataset an empty `getPoints` at that scale
217
+ * if its pins should go too.
218
+ */
219
+ resultsSlot?: ReactNode;
201
220
  /** Optional mobile-header action button (e.g. "Save"), forwarded verbatim to `<MobileHeader action={...} />`. Omit to render just the search + Filters button there. */
202
221
  mobileAction?: IBottomNavAction;
203
222
  /**
@@ -305,7 +324,7 @@ interface IStyledListingLayoutProps<TFilters = unknown> {
305
324
  * default -- pass `autoFetch={false}`
306
325
  * to opt out and drive the first fetch yourself.
307
326
  */
308
- declare function StyledListingLayout<TFilters = unknown>({ search, filterBarStart, toolbarEnd, mobileAction, autoFetch, initialPage, hasMap: hasMapProp, mapCenter, mapZoom, mapControls, onMapReady, mobileSheetFooter, className, }: IStyledListingLayoutProps<TFilters>): react.JSX.Element;
327
+ declare function StyledListingLayout<TFilters = unknown>({ search, filterBarStart, resultsSlot, toolbarEnd, mobileAction, autoFetch, initialPage, hasMap: hasMapProp, mapCenter, mapZoom, mapControls, onMapReady, mobileSheetFooter, className, }: IStyledListingLayoutProps<TFilters>): react.JSX.Element;
309
328
 
310
329
  /**
311
330
  * Two-shape `map` prop: pass a ready `MapProvider`, or the `{ apiKey, mapId? }`
@@ -356,6 +375,16 @@ interface ListingAppProps<TFilters> {
356
375
  * reads `window.location` itself, it only accepts filters as a prop.
357
376
  */
358
377
  initialFilters?: TFilters;
378
+ /**
379
+ * First page of results, so the very first render already has rows.
380
+ *
381
+ * For server rendering: hand over the page the server already fetched and
382
+ * the list renders it immediately -- on the server, and again on the client
383
+ * as hydration -- instead of blanking while an adapter call goes out. The
384
+ * mount fetch is skipped when this is set, so the seeded rows are not
385
+ * replaced a moment later by an identical request.
386
+ */
387
+ initialResults?: Page<unknown>;
359
388
  /**
360
389
  * EVENT OUT: fires with the engine's current filters (`TFilters`, not the
361
390
  * store's `DeepReadonly` wrapper) every time `ListingEventType.FiltersChanged`
@@ -382,6 +411,8 @@ interface ListingAppProps<TFilters> {
382
411
  search?: IStyledListingLayoutProps['search'];
383
412
  /** Forwarded verbatim to `StyledListingLayout`'s `filterBarStart` -- extra content between the search box and the quick-filters row in the desktop filter bar (see that prop's doc comment). */
384
413
  filterBarStart?: IStyledListingLayoutProps['filterBarStart'];
414
+ /** Replaces the entire results column -- see `IStyledListingLayoutProps['resultsSlot']`. */
415
+ resultsSlot?: IStyledListingLayoutProps['resultsSlot'];
385
416
  toolbarEnd?: IStyledListingLayoutProps['toolbarEnd'];
386
417
  /**
387
418
  * Rendered as an absolutely-positioned overlay floating over the map (e.g. zoom/fullscreen
@@ -447,6 +478,6 @@ interface ListingAppProps<TFilters> {
447
478
  * a React Router `setSearchParams`, etc. all work identically from the
448
479
  * consumer's side) instead of assuming `window.history` is the right target.
449
480
  */
450
- declare function ListingApp<TEntity, TFilters>(props: ListingAppProps<TFilters>): react.JSX.Element | null;
481
+ declare function ListingApp<TEntity, TFilters>(props: ListingAppProps<TFilters>): react.JSX.Element;
451
482
 
452
483
  export { BottomNav as B, type ClusterOptions as C, type DatasetDefinition as D, FilterRegistry as F, type IListingConfigOptions as I, ListingApp as L, type MarkerRenderer as M, PaginationMode as P, StyledListingLayout as S, type IListingToolbarProps as a, FallbackPopup as b, type FilterControlProps as c, type FilterDefinition as d, type IListingBottomNavProps as e, type IListingCardProps as f, type IListingComponents as g, type IListingEmptyProps as h, type IListingFilterPanelProps as i, type IListingLoadingProps as j, type IListingMarkerProps as k, type IListingPopupProps as l, type IListingResultHeaderProps as m, type IListingSearchProps as n, type IListingSidebarProps as o, type ListingAppProps as p, ListingComponentsProvider as q, type MobileSheetFooterContext as r, type BottomNavView as s, type IBottomNavAction as t, useListingComponents as u, type IBottomNavProps as v, type IStyledListingLayoutProps as w, type ListingAppMapProp as x };
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentType, ReactNode } from 'react';
3
- import { c as EntityAdapter, M as MapPoint, L as LatLng, a as MapProvider } from './map-provider.interface-D3pwkbog.js';
3
+ import { c as EntityAdapter, M as MapPoint, L as LatLng, a as MapProvider, P as Page } from './map-provider.interface-D3pwkbog.cjs';
4
4
 
5
5
  interface FilterControlProps<TValue> {
6
6
  value: TValue;
@@ -198,6 +198,25 @@ interface IStyledListingLayoutProps<TFilters = unknown> {
198
198
  filterBarStart?: ReactNode;
199
199
  /** Extra content rendered in `.rle-list-header` (above the list), to the right of `ListingResultHeader` (e.g. a sort control + save-search). */
200
200
  toolbarEnd?: ReactNode;
201
+ /**
202
+ * Replaces the ENTIRE results column -- header, grid and pagination -- with
203
+ * the given content, inside the same scrolling `.rle-list` container.
204
+ *
205
+ * For the states where a result list is the wrong thing to show at all, not
206
+ * merely a different-looking one: a viewport too wide for individual results
207
+ * to mean anything, an onboarding prompt, a saved-search upsell. `Empty` and
208
+ * `Loading` cannot express those, because both still sit inside the results
209
+ * column and leave its header, sort control and pager in place.
210
+ *
211
+ * Consumers previously had to hide `.rle-list-grid`,
212
+ * `.rle-list-header__toolbar` and `.rle-pagination` with their own CSS,
213
+ * which made three internal class names part of the public contract by
214
+ * accident.
215
+ *
216
+ * The map is unaffected -- give a dataset an empty `getPoints` at that scale
217
+ * if its pins should go too.
218
+ */
219
+ resultsSlot?: ReactNode;
201
220
  /** Optional mobile-header action button (e.g. "Save"), forwarded verbatim to `<MobileHeader action={...} />`. Omit to render just the search + Filters button there. */
202
221
  mobileAction?: IBottomNavAction;
203
222
  /**
@@ -305,7 +324,7 @@ interface IStyledListingLayoutProps<TFilters = unknown> {
305
324
  * default -- pass `autoFetch={false}`
306
325
  * to opt out and drive the first fetch yourself.
307
326
  */
308
- declare function StyledListingLayout<TFilters = unknown>({ search, filterBarStart, toolbarEnd, mobileAction, autoFetch, initialPage, hasMap: hasMapProp, mapCenter, mapZoom, mapControls, onMapReady, mobileSheetFooter, className, }: IStyledListingLayoutProps<TFilters>): react.JSX.Element;
327
+ declare function StyledListingLayout<TFilters = unknown>({ search, filterBarStart, resultsSlot, toolbarEnd, mobileAction, autoFetch, initialPage, hasMap: hasMapProp, mapCenter, mapZoom, mapControls, onMapReady, mobileSheetFooter, className, }: IStyledListingLayoutProps<TFilters>): react.JSX.Element;
309
328
 
310
329
  /**
311
330
  * Two-shape `map` prop: pass a ready `MapProvider`, or the `{ apiKey, mapId? }`
@@ -356,6 +375,16 @@ interface ListingAppProps<TFilters> {
356
375
  * reads `window.location` itself, it only accepts filters as a prop.
357
376
  */
358
377
  initialFilters?: TFilters;
378
+ /**
379
+ * First page of results, so the very first render already has rows.
380
+ *
381
+ * For server rendering: hand over the page the server already fetched and
382
+ * the list renders it immediately -- on the server, and again on the client
383
+ * as hydration -- instead of blanking while an adapter call goes out. The
384
+ * mount fetch is skipped when this is set, so the seeded rows are not
385
+ * replaced a moment later by an identical request.
386
+ */
387
+ initialResults?: Page<unknown>;
359
388
  /**
360
389
  * EVENT OUT: fires with the engine's current filters (`TFilters`, not the
361
390
  * store's `DeepReadonly` wrapper) every time `ListingEventType.FiltersChanged`
@@ -382,6 +411,8 @@ interface ListingAppProps<TFilters> {
382
411
  search?: IStyledListingLayoutProps['search'];
383
412
  /** Forwarded verbatim to `StyledListingLayout`'s `filterBarStart` -- extra content between the search box and the quick-filters row in the desktop filter bar (see that prop's doc comment). */
384
413
  filterBarStart?: IStyledListingLayoutProps['filterBarStart'];
414
+ /** Replaces the entire results column -- see `IStyledListingLayoutProps['resultsSlot']`. */
415
+ resultsSlot?: IStyledListingLayoutProps['resultsSlot'];
385
416
  toolbarEnd?: IStyledListingLayoutProps['toolbarEnd'];
386
417
  /**
387
418
  * Rendered as an absolutely-positioned overlay floating over the map (e.g. zoom/fullscreen
@@ -447,6 +478,6 @@ interface ListingAppProps<TFilters> {
447
478
  * a React Router `setSearchParams`, etc. all work identically from the
448
479
  * consumer's side) instead of assuming `window.history` is the right target.
449
480
  */
450
- declare function ListingApp<TEntity, TFilters>(props: ListingAppProps<TFilters>): react.JSX.Element | null;
481
+ declare function ListingApp<TEntity, TFilters>(props: ListingAppProps<TFilters>): react.JSX.Element;
451
482
 
452
483
  export { BottomNav as B, type ClusterOptions as C, type DatasetDefinition as D, FilterRegistry as F, type IListingConfigOptions as I, ListingApp as L, type MarkerRenderer as M, PaginationMode as P, StyledListingLayout as S, type IListingToolbarProps as a, FallbackPopup as b, type FilterControlProps as c, type FilterDefinition as d, type IListingBottomNavProps as e, type IListingCardProps as f, type IListingComponents as g, type IListingEmptyProps as h, type IListingFilterPanelProps as i, type IListingLoadingProps as j, type IListingMarkerProps as k, type IListingPopupProps as l, type IListingResultHeaderProps as m, type IListingSearchProps as n, type IListingSidebarProps as o, type ListingAppProps as p, ListingComponentsProvider as q, type MobileSheetFooterContext as r, type BottomNavView as s, type IBottomNavAction as t, useListingComponents as u, type IBottomNavProps as v, type IStyledListingLayoutProps as w, type ListingAppMapProp as x };
@@ -1,2 +1,2 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
2
- var _chunkPLAFA6TTcjs = require('../chunk-PLAFA6TT.cjs');var _jsxruntime = require('react/jsx-runtime');function L({children:o}){return _jsxruntime.jsx.call(void 0, _chunkPLAFA6TTcjs.q,{..._chunkPLAFA6TTcjs.P,children:o})}exports.BottomNav = _chunkPLAFA6TTcjs.E; exports.BottomSheet = _chunkPLAFA6TTcjs.Q; exports.ListingApp = _chunkPLAFA6TTcjs.S; exports.StyledCard = _chunkPLAFA6TTcjs.F; exports.StyledComponentsProviderWithDefaults = L; exports.StyledEmpty = _chunkPLAFA6TTcjs.G; exports.StyledFilterPanel = _chunkPLAFA6TTcjs.H; exports.StyledListingLayout = _chunkPLAFA6TTcjs.R; exports.StyledLoading = _chunkPLAFA6TTcjs.I; exports.StyledMarker = _chunkPLAFA6TTcjs.J; exports.StyledPopup = _chunkPLAFA6TTcjs.K; exports.StyledResultHeader = _chunkPLAFA6TTcjs.L; exports.StyledSearch = _chunkPLAFA6TTcjs.M; exports.StyledSidebar = _chunkPLAFA6TTcjs.N; exports.StyledToolbar = _chunkPLAFA6TTcjs.O; exports.styledDefaultComponents = _chunkPLAFA6TTcjs.P;
2
+ var _chunkX6UVZ2ENcjs = require('../chunk-X6UVZ2EN.cjs');var _jsxruntime = require('react/jsx-runtime');function L({children:o}){return _jsxruntime.jsx.call(void 0, _chunkX6UVZ2ENcjs.r,{..._chunkX6UVZ2ENcjs.Q,children:o})}exports.BottomNav = _chunkX6UVZ2ENcjs.F; exports.BottomSheet = _chunkX6UVZ2ENcjs.R; exports.ListingApp = _chunkX6UVZ2ENcjs.T; exports.StyledCard = _chunkX6UVZ2ENcjs.G; exports.StyledComponentsProviderWithDefaults = L; exports.StyledEmpty = _chunkX6UVZ2ENcjs.H; exports.StyledFilterPanel = _chunkX6UVZ2ENcjs.I; exports.StyledListingLayout = _chunkX6UVZ2ENcjs.S; exports.StyledLoading = _chunkX6UVZ2ENcjs.J; exports.StyledMarker = _chunkX6UVZ2ENcjs.K; exports.StyledPopup = _chunkX6UVZ2ENcjs.L; exports.StyledResultHeader = _chunkX6UVZ2ENcjs.M; exports.StyledSearch = _chunkX6UVZ2ENcjs.N; exports.StyledSidebar = _chunkX6UVZ2ENcjs.O; exports.StyledToolbar = _chunkX6UVZ2ENcjs.P; exports.styledDefaultComponents = _chunkX6UVZ2ENcjs.Q;
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { f as IListingCardProps, h as IListingEmptyProps, i as IListingFilterPanelProps, j as IListingLoadingProps, k as IListingMarkerProps, l as IListingPopupProps, m as IListingResultHeaderProps, n as IListingSearchProps, o as IListingSidebarProps, a as IListingToolbarProps, g as IListingComponents } from '../listing-app-By6TrXB9.cjs';
4
- export { B as BottomNav, s as BottomNavView, t as IBottomNavAction, v as IBottomNavProps, w as IStyledListingLayoutProps, L as ListingApp, x as ListingAppMapProp, p as ListingAppProps, r as MobileSheetFooterContext, S as StyledListingLayout } from '../listing-app-By6TrXB9.cjs';
3
+ import { f as IListingCardProps, h as IListingEmptyProps, i as IListingFilterPanelProps, j as IListingLoadingProps, k as IListingMarkerProps, l as IListingPopupProps, m as IListingResultHeaderProps, n as IListingSearchProps, o as IListingSidebarProps, a as IListingToolbarProps, g as IListingComponents } from '../listing-app-DbXiww1I.cjs';
4
+ export { B as BottomNav, s as BottomNavView, t as IBottomNavAction, v as IBottomNavProps, w as IStyledListingLayoutProps, L as ListingApp, x as ListingAppMapProp, p as ListingAppProps, r as MobileSheetFooterContext, S as StyledListingLayout } from '../listing-app-DbXiww1I.cjs';
5
5
  import '../map-provider.interface-D3pwkbog.cjs';
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { f as IListingCardProps, h as IListingEmptyProps, i as IListingFilterPanelProps, j as IListingLoadingProps, k as IListingMarkerProps, l as IListingPopupProps, m as IListingResultHeaderProps, n as IListingSearchProps, o as IListingSidebarProps, a as IListingToolbarProps, g as IListingComponents } from '../listing-app-CHC-XAhJ.js';
4
- export { B as BottomNav, s as BottomNavView, t as IBottomNavAction, v as IBottomNavProps, w as IStyledListingLayoutProps, L as ListingApp, x as ListingAppMapProp, p as ListingAppProps, r as MobileSheetFooterContext, S as StyledListingLayout } from '../listing-app-CHC-XAhJ.js';
3
+ import { f as IListingCardProps, h as IListingEmptyProps, i as IListingFilterPanelProps, j as IListingLoadingProps, k as IListingMarkerProps, l as IListingPopupProps, m as IListingResultHeaderProps, n as IListingSearchProps, o as IListingSidebarProps, a as IListingToolbarProps, g as IListingComponents } from '../listing-app-Cm4F8Gd_.js';
4
+ export { B as BottomNav, s as BottomNavView, t as IBottomNavAction, v as IBottomNavProps, w as IStyledListingLayoutProps, L as ListingApp, x as ListingAppMapProp, p as ListingAppProps, r as MobileSheetFooterContext, S as StyledListingLayout } from '../listing-app-Cm4F8Gd_.js';
5
5
  import '../map-provider.interface-D3pwkbog.js';
6
6
 
7
7
  /**
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{E as r,F as p,G as i,H as y,I as d,J as l,K as n,L as m,M as s,N as a,O as S,P as t,Q as f,R as P,S as u,q as e}from"../chunk-XJBDGG2S.js";import{jsx as g}from"react/jsx-runtime";function L({children:o}){return g(e,{...t,children:o})}export{r as BottomNav,f as BottomSheet,u as ListingApp,p as StyledCard,L as StyledComponentsProviderWithDefaults,i as StyledEmpty,y as StyledFilterPanel,P as StyledListingLayout,d as StyledLoading,l as StyledMarker,n as StyledPopup,m as StyledResultHeader,s as StyledSearch,a as StyledSidebar,S as StyledToolbar,t as styledDefaultComponents};
2
+ import{F as r,G as p,H as i,I as y,J as d,K as l,L as n,M as m,N as s,O as a,P as S,Q as t,R as f,S as P,T as u,r as e}from"../chunk-VQADQ7N7.js";import{jsx as g}from"react/jsx-runtime";function L({children:o}){return g(e,{...t,children:o})}export{r as BottomNav,f as BottomSheet,u as ListingApp,p as StyledCard,L as StyledComponentsProviderWithDefaults,i as StyledEmpty,y as StyledFilterPanel,P as StyledListingLayout,d as StyledLoading,l as StyledMarker,n as StyledPopup,m as StyledResultHeader,s as StyledSearch,a as StyledSidebar,S as StyledToolbar,t as styledDefaultComponents};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-listing-engine",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "license": "MIT",
5
5
  "description": "Headless, composable listing engine for React: filterable list + Google-Maps multi-layer map, with pluggable data adapters, a filter/dataset registry, injectable components, and a Tailwind-free styled adapter.",
6
6
  "funding": [
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } 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; } var _class; var _class2; var _class3; var _class4; var _class5;"use client";
2
- var ee= (_class =class{__init() {this.listeners=new Set}constructor(e){;_class.prototype.__init.call(this);this.state=this.freezeState({filters:{...e.filters},results:{items:[],nextCursor:null},bounds:null,selection:null,hovered:null,pagination:{mode:_nullishCoalesce(e.mode, () => ("paged")),loading:!1,pageIndex:0},layers:{},points:{}})}getState(){return this.state}setFilters(e){this.setState({filters:{...this.state.filters,...e}})}setResults(e){this.setState({results:{items:[...e.items],nextCursor:e.nextCursor,total:e.total}})}appendResults(e){this.setState({results:{items:[...this.state.results.items,...e.items],nextCursor:e.nextCursor,total:e.total}})}setBounds(e){this.setState({bounds:e?{...e}:null})}setSelection(e){this.setState({selection:e})}setHovered(e){this.setState({hovered:e})}setLayerVisible(e,i){this.setState({layers:{...this.state.layers,[e]:i}})}setLoading(e){this.setState({pagination:{...this.state.pagination,loading:e}})}setPageIndex(e){this.setState({pagination:{...this.state.pagination,pageIndex:e}})}setPoints(e,i){this.setState({points:{...this.state.points,[e]:[...i]}})}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}setState(e){this.state=this.freezeState({...this.state,...e}),this.notify()}notify(){for(let e of this.listeners)e()}freezeState(e){Object.freeze(e.filters),Object.freeze(e.results.items),Object.freeze(e.results),e.bounds&&Object.freeze(e.bounds),Object.freeze(e.pagination),Object.freeze(e.layers);for(let i of Object.values(e.points))Object.freeze(i);return Object.freeze(e.points),Object.freeze(e)}}, _class);var $= (_class2 =class{constructor() { _class2.prototype.__init2.call(this); }__init2() {this.defs=new Map}add(e){if(this.defs.has(e.key))throw new Error(`FilterRegistry: filter "${e.key}" is already registered`);return this.defs.set(e.key,{...e}),this}remove(e){return this.defs.delete(e),this}replace(e,i){if(!this.defs.has(e))throw new Error(`FilterRegistry: cannot replace unregistered filter "${e}"`);return this.defs.set(e,{...i,key:e}),this}reorder(e){let i=this.list(),n=e.filter(s=>this.defs.has(s));n.forEach((s,o)=>{this.defs.get(s).order=o});let r=new Set(n);return i.filter(s=>!r.has(s.key)).forEach((s,o)=>{s.order=n.length+o}),this}list(){return[...this.defs.values()].sort((e,i)=>e.order-i.order)}has(e){return this.defs.has(e)}toFilters(e){return this.list().filter(n=>Object.hasOwn(e,n.key)).map(n=>n.toParams(e[n.key])).reduce((n,r)=>({...n,...r}),{})}activeKeys(e){return this.list().filter(i=>_optionalChain([i, 'access', _2 => _2.isActive, 'optionalCall', _3 => _3(e)])).map(i=>i.key)}clearedParams(){return this.list().reduce((e,i)=>Object.assign(e,i.toParams(i.fromParams({}))),{})}}, _class2);var te= (_class3 =class{constructor() { _class3.prototype.__init3.call(this); }__init3() {this.defs=new Map}add(e){if(this.defs.has(e.id))throw new Error(`DatasetRegistry: dataset "${e.id}" is already registered`);return this.defs.set(e.id,{...e}),this}get(e){return this.defs.get(e)}has(e){return this.defs.has(e)}list(){return[...this.defs.values()]}visibleIds(){return this.list().filter(e=>_optionalChain([e, 'access', _4 => _4.visible, 'optionalCall', _5 => _5()])!==!1).map(e=>e.id)}}, _class3);var ie= (_class4 =class{constructor() { _class4.prototype.__init4.call(this); }__init4() {this.map=new Map}dispose(){this.map.clear()}emit(e){let i=this.map.get(e.type);if(i)for(let r of[...i])r(e);let n=this.map.get("*");if(n)for(let r of[...n])r(e)}on(e,i){let n=this.map.get(e);return n||(n=new Set,this.map.set(e,n)),n.add(i),()=>{n.delete(i)}}}, _class4);var Ae={pagination:"paged",pageSize:20,debounceMs:250};var ne=class{constructor(e){this.options=Object.freeze({...Ae,...e})}};var re= (_class5 =class{__init5() {this.emitter=new ie}__init6() {this.debounceTimer=null}__init7() {this.debounceResolve=null}__init8() {this.queryToken=0}__init9() {this.pointsToken=0}__init10() {this.mapHandle=null}constructor(e){;_class5.prototype.__init5.call(this);_class5.prototype.__init6.call(this);_class5.prototype.__init7.call(this);_class5.prototype.__init8.call(this);_class5.prototype.__init9.call(this);_class5.prototype.__init10.call(this);this.datasets=e.datasets,this.filters=_nullishCoalesce(e.filters, () => (new $)),this.map=e.map,this.config=new ne(e.config);let i=_nullishCoalesce(e.primaryDatasetId, () => (_optionalChain([this, 'access', _6 => _6.datasets, 'access', _7 => _7.list, 'call', _8 => _8(), 'access', _9 => _9[0], 'optionalAccess', _10 => _10.id])));if(i==null||!this.datasets.has(i))throw new Error(`ListingEngine: primary dataset "${_nullishCoalesce(i, () => (""))}" is not registered \u2014 pass a valid primaryDatasetId or register at least one dataset`);this.primaryDatasetId=i,this.store=new ee({filters:_nullishCoalesce(e.initialFilters, () => ({})),mode:this.config.options.pagination})}get state(){return this.store.getState()}get options(){return this.config.options}applyFilters(e){this.store.setFilters(e),this.emitter.emit({type:"FiltersChanged",filters:this.currentFilters()}),this.clearDebounce();let i=++this.queryToken,n=this.config.options.debounceMs;return n<=0?this.runQuery(i):new Promise(r=>{this.debounceResolve=r,this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.debounceResolve=null,r(this.runQuery(i))},n)})}async loadPage(){let e=this.state.results.nextCursor;if(e===null)return;let i=++this.queryToken,n=this.primaryDataset();this.store.setLoading(!0);try{let r=await n.adapter.list(this.currentFilters(),{cursor:e,limit:this.config.options.pageSize});if(i!==this.queryToken)return;this.config.options.pagination==="infinite"?this.store.appendResults(r):this.store.setResults(r),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:r.items.length})}finally{i===this.queryToken&&this.store.setLoading(!1)}}async goToPage(e){if(e<0)return;let i=++this.queryToken,n=this.primaryDataset();this.store.setLoading(!0);try{let r=await n.adapter.list(this.currentFilters(),{offset:e*this.config.options.pageSize,limit:this.config.options.pageSize});if(i!==this.queryToken)return;this.store.setResults(r),this.store.setPageIndex(e),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:r.items.length})}finally{i===this.queryToken&&this.store.setLoading(!1)}}async loadPoints(e){this.store.setBounds(e),this.emitter.emit({type:"BoundsChanged",bounds:e});let i=this.currentFilters(),n=++this.pointsToken;await Promise.allSettled(this.datasets.visibleIds().map(async r=>{let s=this.datasets.get(r);if(!s)return;let o=await s.adapter.getPoints(i,e);n===this.pointsToken&&this.store.setPoints(r,o)}))}setMapHandle(e){this.mapHandle=e}fitBounds(e,i){!this.map||!this.mapHandle||this.map.fitBounds(this.mapHandle,e,i)}selectPoint(e,i){this.store.setSelection(i);let n=_optionalChain([this, 'access', _11 => _11.state, 'access', _12 => _12.points, 'access', _13 => _13[e], 'optionalAccess', _14 => _14.find, 'call', _15 => _15(r=>r.id===i)]);n&&this.emitter.emit({type:"PointClicked",datasetId:e,id:n.id,entity:n.entity})}setHovered(e,i){this.store.setHovered(i)}toggleLayer(e){let n=!(_nullishCoalesce(this.state.layers[e], () => (!0)));this.store.setLayerVisible(e,n),this.emitter.emit({type:"LayerToggled",datasetId:e,visible:n})}subscribe(e){return this.store.subscribe(e)}on(e,i){return this.emitter.on(e,i)}dispose(){this.clearDebounce(),this.emitter.dispose(),this.mapHandle=null}async runQuery(e){if(e!==this.queryToken)return;let i=this.primaryDataset();this.store.setLoading(!0);try{let n=await i.adapter.list(this.currentFilters(),{cursor:null,limit:this.config.options.pageSize});if(e!==this.queryToken)return;this.store.setResults(n),this.store.setPageIndex(0),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:n.items.length})}finally{e===this.queryToken&&this.store.setLoading(!1)}}primaryDataset(){return this.datasets.get(this.primaryDatasetId)}currentFilters(){return this.store.getState().filters}clearDebounce(){this.debounceTimer!==null&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.debounceResolve!==null&&(this.debounceResolve(),this.debounceResolve=null)}}, _class5);function ze(...t){let e={config:{},filters:new $,datasets:new te};for(let i of t)i(e);return e}var Ue=t=>e=>{e.config={...e.config,...t}},Ke= exports.j =t=>e=>{e.map=t},Ve= exports.k =t=>e=>{e.datasets.add(t)},qe= exports.l =t=>e=>{t(e.filters)},Bi= exports.m =t=>e=>{e.urlSync=t},$e= exports.n =t=>e=>{e.initialFilters=t},Oi= exports.o =t=>e=>{e.primaryDatasetId=t};var _react = require('react');var _jsxruntime = require('react/jsx-runtime');function Tt(t){return String(_nullishCoalesce(_optionalChain([t, 'optionalAccess', _16 => _16.title]), () => ("")))}var Ft=({item:t})=>_jsxruntime.jsx.call(void 0, "div",{children:Tt(t)}),kt=()=>_jsxruntime.jsx.call(void 0, "div",{}),fe= exports.p =()=>_jsxruntime.jsx.call(void 0, "div",{}),Ct=({children:t})=>_jsxruntime.jsx.call(void 0, "div",{children:t}),St=({children:t})=>_jsxruntime.jsx.call(void 0, "div",{children:t}),wt=({value:t,onChange:e,placeholder:i})=>_jsxruntime.jsx.call(void 0, "input",{type:"search",value:t,placeholder:i,onChange:n=>e(n.target.value),"aria-label":_nullishCoalesce(i, () => ("Search"))}),It=()=>_jsxruntime.jsx.call(void 0, "div",{role:"status",children:"No results"}),Et=()=>_jsxruntime.jsx.call(void 0, "div",{role:"status","aria-busy":"true",children:"Loading\u2026"}),xt=({count:t})=>_jsxruntime.jsxs.call(void 0, "div",{children:[t," results"]}),Nt=({children:t})=>_jsxruntime.jsx.call(void 0, "div",{children:t}),Mt=({view:t,onViewChange:e})=>_jsxruntime.jsxs.call(void 0, "nav",{"aria-label":"Listing navigation",children:[_jsxruntime.jsx.call(void 0, "button",{type:"button","aria-pressed":t==="list",onClick:()=>e("list"),children:"List"}),_jsxruntime.jsx.call(void 0, "button",{type:"button","aria-pressed":t==="map",onClick:()=>e("map"),children:"Map"})]}),C={BottomNav:Mt,Card:Ft,Marker:kt,Popup:fe,Sidebar:Ct,FilterPanel:St,Search:wt,Empty:It,Loading:Et,ResultHeader:xt,Toolbar:Nt},We=_react.createContext.call(void 0, C);function je(t){let{BottomNav:e,Card:i,Marker:n,Popup:r,Sidebar:s,FilterPanel:o,Search:a,Empty:p,Loading:d,ResultHeader:l,Toolbar:c,children:y}=t,v={BottomNav:_nullishCoalesce(e, () => (C.BottomNav)),Card:_nullishCoalesce(i, () => (C.Card)),Marker:_nullishCoalesce(n, () => (C.Marker)),Popup:_nullishCoalesce(r, () => (C.Popup)),Sidebar:_nullishCoalesce(s, () => (C.Sidebar)),FilterPanel:_nullishCoalesce(o, () => (C.FilterPanel)),Search:_nullishCoalesce(a, () => (C.Search)),Empty:_nullishCoalesce(p, () => (C.Empty)),Loading:_nullishCoalesce(d, () => (C.Loading)),ResultHeader:_nullishCoalesce(l, () => (C.ResultHeader)),Toolbar:_nullishCoalesce(c, () => (C.Toolbar))};return _jsxruntime.jsx.call(void 0, We.Provider,{value:v,children:y})}function w(){return _react.useContext.call(void 0, We)}var se=_react.createContext.call(void 0, null);function h(){let t=_react.useContext.call(void 0, se);if(t===null)throw new Error("useListing must be used within a <ListingProvider>");return t}function I(){let t=h(),e=_react.useCallback.call(void 0, n=>t.subscribe(n),[t]),i=_react.useCallback.call(void 0, ()=>t.state,[t]);return _react.useSyncExternalStore.call(void 0, e,i,i)}function oe(){let t=h(),e=I(),i=_react.useCallback.call(void 0, r=>t.applyFilters(r),[t]),n=_react.useCallback.call(void 0, (r,s)=>t.applyFilters({[r]:s}),[t]);return{filters:e.filters,set:i,setField:n}}function ye({className:t,groupClassName:e,hideLabels:i,draft:n,onDraftChange:r}={}){let s=h(),{FilterPanel:o}=w(),{filters:a}=oe(),p=n!==void 0&&r!==void 0,d=p?n:a;return _jsxruntime.jsx.call(void 0, o,{children:_jsxruntime.jsx.call(void 0, "div",{className:_nullishCoalesce(t, () => ("space-y-5")),children:s.filters.list().map(l=>{if(typeof l.render=="string")return _jsxruntime.jsx.call(void 0, "div",{"data-filter":l.key,className:e},l.key);let c=l.render;return _jsxruntime.jsxs.call(void 0, "div",{className:e,children:[l.label&&!i&&_jsxruntime.jsx.call(void 0, "div",{className:"mb-1.5 text-[13px] font-medium text-foreground",children:l.label}),_jsxruntime.jsx.call(void 0, c,{value:l.fromParams(d),onChange:y=>p?r(l.toParams(y)):void s.applyFilters(l.toParams(y))})]},l.key)})})})}function W(){return I().results}function _t(t,e){if(t&&typeof t=="object"&&"id"in t){let i=t.id;if(typeof i=="string"||typeof i=="number")return i}return e}function Xe({className:t}={}){let e=h(),{items:i}=W(),{pagination:n,selection:r}=I(),{Card:s,Empty:o,Loading:a}=w();return n.loading&&i.length===0?_jsxruntime.jsx.call(void 0, a,{}):i.length===0?_jsxruntime.jsx.call(void 0, o,{}):_jsxruntime.jsx.call(void 0, "div",{role:"list",className:t,children:i.map((p,d)=>{let l=_t(p,d);return _jsxruntime.jsx.call(void 0, s,{item:p,selected:r===l,onSelect:()=>e.selectPoint(e.primaryDatasetId,l)},l)})})}var _reactdom = require('react-dom');var At={west:-179.9,south:-85,east:179.9,north:85},Ye=.1,et=.02;function zt(t){if(t.length===0)return null;let e=t[0].lng,i=t[0].lng,n=t[0].lat,r=t[0].lat;for(let{lat:a,lng:p}of t)p<e&&(e=p),p>i&&(i=p),a<n&&(n=a),a>r&&(r=a);let s=r>n?(r-n)*Ye:et,o=i>e?(i-e)*Ye:et;return{west:e-o,east:i+o,south:n-s,north:r+s}}function it(t){let{center:e,zoom:i,fallback:n,mapControls:r,onMapReady:s}=t,o=h(),a=I(),p=_react.useRef.call(void 0, s);p.current=s;let d=_react.useRef.call(void 0, null),l=_react.useRef.call(void 0, null),c=_react.useRef.call(void 0, null),[y,v]=_react.useState.call(void 0, !1),O=_react.useRef.call(void 0, !1),K=_react.useRef.call(void 0, !1),D=_react.useRef.call(void 0, !1),u=o.map;_react.useEffect.call(void 0, ()=>{let T=c.current;if(!u||!T)return;let L=[];for(let f of Object.keys(a.points)){if(a.layers[f]===!1)continue;let m=o.datasets.get(f),F=_nullishCoalesce(a.points[f], () => ([])),q={id:f,markers:F.map(N=>({id:N.id,position:N.position,iconUrl:_optionalChain([m, 'optionalAccess', _17 => _17.marker, 'access', _18 => _18.iconUrl, 'optionalCall', _19 => _19(N.entity)]),element:_optionalChain([m, 'optionalAccess', _20 => _20.marker, 'access', _21 => _21.element, 'optionalCall', _22 => _22(N.entity)])})),clustering:_optionalChain([m, 'optionalAccess', _23 => _23.clustering]),onMarkerClick:N=>o.selectPoint(f,N)};L.push(u.renderLayer(T,q))}return()=>{L.forEach(f=>f())}},[o,u,y,a.points,a.layers]),_react.useEffect.call(void 0, ()=>{if(!d.current||!u)return;let T=d.current,L=!1,f=null;return(async()=>{let m=await u.mount(T,{center:e,zoom:i,fullscreenTarget:_nullishCoalesce(l.current, () => (void 0))});if(L){u.destroy(m);return}c.current=m,o.setMapHandle(m),f=u.onBoundsChange(m,F=>{D.current?D.current=!1:K.current=!0,o.loadPoints(F)}),v(!0),_optionalChain([p, 'access', _24 => _24.current, 'optionalCall', _25 => _25(_nullishCoalesce(m.nativeMap, () => (m.raw)))]),o.loadPoints(At)})(),()=>{L=!0,_optionalChain([f, 'optionalCall', _26 => _26()]),c.current&&(u.destroy(c.current),c.current=null,o.setMapHandle(null),_optionalChain([p, 'access', _27 => _27.current, 'optionalCall', _28 => _28(null)])),v(!1)}},[o,u]),_react.useEffect.call(void 0, ()=>{let T=c.current;if(!u||!T||e||O.current||K.current)return;let L=[];for(let m of Object.keys(a.points))if(a.layers[m]!==!1)for(let F of _nullishCoalesce(a.points[m], () => ([])))L.push(F.position);let f=zt(L);f&&(O.current=!0,D.current=!0,u.fitBounds(T,f))},[u,e,y,a.points,a.layers]),_react.useEffect.call(void 0, ()=>{_optionalChain([u, 'optionalAccess', _29 => _29.updateMarkerStates, 'call', _30 => _30(a.selection,a.hovered)])},[u,y,a.selection,a.hovered]);let{Popup:V}=w(),b=V!==fe,k=_nullishCoalesce(a.points[o.primaryDatasetId], () => ([])),_=a.selection!=null?k.find(T=>T.id===a.selection):void 0,[H,x]=_react.useState.call(void 0, null),A=_react.useRef.call(void 0, _);return A.current=_,_react.useEffect.call(void 0, ()=>{let T=c.current;if(!u||!T||!b)return;let L=A.current;if(!L)return;let f=u.mountOverlay(L.position);x({entity:L.entity,position:L.position,container:f.container});let m=()=>o.selectPoint(o.primaryDatasetId,null),F=N=>{N.key==="Escape"&&m()};document.addEventListener("keydown",F);let q=u.onMapClick(m);return()=>{document.removeEventListener("keydown",F),q(),f.unmount(),x(null)}},[o,u,y,a.selection,b]),_jsxruntime.jsxs.call(void 0, "div",{ref:l,className:"relative h-full min-h-0 w-full",children:[_jsxruntime.jsxs.call(void 0, "div",{ref:d,className:!u&&n?"flex h-full min-h-0 w-full items-center justify-center":"h-full min-h-0 w-full",children:[!u&&n,b&&H?_reactdom.createPortal.call(void 0, _jsxruntime.jsx.call(void 0, V,{entity:H.entity,onClose:()=>o.selectPoint(o.primaryDatasetId,null)}),H.container):null]}),r!=null&&_jsxruntime.jsx.call(void 0, "div",{className:"pointer-events-none absolute inset-0",children:_jsxruntime.jsx.call(void 0, "div",{className:"pointer-events-auto",children:r})})]})}var he="gap";function Ut(t,e){if(t<=7)return Array.from({length:t},(s,o)=>o+1);let i=Math.max(2,e-1),n=Math.min(t-1,e+1),r=[1];i>2&&r.push(he);for(let s=i;s<=n;s+=1)r.push(s);return n<t-1&&r.push(he),r.push(t),r}function nt(){let t=h(),{results:e,pagination:i}=I();if(i.mode==="infinite")return e.nextCursor==null?null:_jsxruntime.jsx.call(void 0, "button",{type:"button",disabled:i.loading,onClick:()=>{t.loadPage()},children:"Load more"});let n=t.options.pageSize,{pageIndex:r}=i,s=r+1,o=e.total!=null?Math.ceil(e.total/n):null,a=o!=null?s<o:e.nextCursor!=null||e.items.length>=n;if(o!=null?o<=1:r===0&&!a)return null;let p=d=>()=>{t.goToPage(d)};return _jsxruntime.jsxs.call(void 0, "nav",{className:"rle-pagination","aria-label":"Pagination",children:[_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-page-btn rle-page-btn--nav","aria-label":"Previous page",disabled:i.loading||r===0,onClick:p(r-1),children:"\u2039"}),o!=null&&Ut(o,s).map((d,l)=>d===he?_jsxruntime.jsx.call(void 0, "span",{className:"rle-page-ellipsis",children:"\u2026"},`gap-${l}`):_jsxruntime.jsx.call(void 0, "button",{type:"button",className:d===s?"rle-page-btn rle-page-btn--active":"rle-page-btn","aria-label":`Page ${d}`,"aria-current":d===s?"page":void 0,disabled:i.loading,onClick:p(d-1),children:d},d)),_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-page-btn rle-page-btn--nav","aria-label":"Next page",disabled:i.loading||!a,onClick:p(r+1),children:"\u203A"})]})}function rt(){let{items:t,total:e}=W(),{ResultHeader:i}=w();return _jsxruntime.jsx.call(void 0, i,{count:t.length,total:e})}function st(t,e){let i=h(),n=_react.useRef.call(void 0, e);n.current=e,_react.useEffect.call(void 0, ()=>i.on(t,r=>n.current(r)),[i,t])}function at(t){let{children:e,...i}=t,[n]=_react.useState.call(void 0, ()=>i),[r,s]=_react.useState.call(void 0, null);return _react.useEffect.call(void 0, ()=>{let o=new re({datasets:n.datasets,filters:n.filters,config:n.config,map:n.map,initialFilters:n.initialFilters,primaryDatasetId:n.primaryDatasetId});return n.urlSync&&n.urlSync.start(o),s(o),()=>{n.urlSync&&n.urlSync.stop(),o.dispose(),s(a=>a===o?null:a)}},[n]),r?_jsxruntime.jsx.call(void 0, se.Provider,{value:r,children:e}):null}function lt({view:t,onViewChange:e}){return _jsxruntime.jsx.call(void 0, "nav",{className:"rle-bottom-nav","aria-label":"Listing navigation",children:_jsxruntime.jsxs.call(void 0, "div",{className:"rle-viewtoggle",role:"group","aria-label":"View",children:[_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:`rle-viewtoggle__btn${t==="list"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":t==="list",onClick:()=>e("list"),children:[_jsxruntime.jsx.call(void 0, Gt,{}),"List"]}),_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:`rle-viewtoggle__btn${t==="map"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":t==="map",onClick:()=>e("map"),children:[_jsxruntime.jsx.call(void 0, Qt,{}),"Map"]})]})})}function Gt(){return _jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "line",{x1:"8",y1:"6",x2:"20",y2:"6"}),_jsxruntime.jsx.call(void 0, "line",{x1:"8",y1:"12",x2:"20",y2:"12"}),_jsxruntime.jsx.call(void 0, "line",{x1:"8",y1:"18",x2:"20",y2:"18"}),_jsxruntime.jsx.call(void 0, "line",{x1:"4",y1:"6",x2:"4.01",y2:"6"}),_jsxruntime.jsx.call(void 0, "line",{x1:"4",y1:"12",x2:"4.01",y2:"12"}),_jsxruntime.jsx.call(void 0, "line",{x1:"4",y1:"18",x2:"4.01",y2:"18"})]})}function Qt(){return _jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "polygon",{points:"1 6 8 3 16 6 23 3 23 18 16 21 8 18 1 21 1 6"}),_jsxruntime.jsx.call(void 0, "line",{x1:"8",y1:"3",x2:"8",y2:"18"}),_jsxruntime.jsx.call(void 0, "line",{x1:"16",y1:"6",x2:"16",y2:"21"})]})}function j(t){return typeof t!="number"?t:new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(t)}function Zt(t){return t?"rle-card rle-card--selected":"rle-card"}function be({item:t,selected:e,onSelect:i}){let n=_nullishCoalesce(t, () => ({})),r=Zt(e),s=_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[n.imageUrl?_jsxruntime.jsx.call(void 0, "img",{src:n.imageUrl,alt:_nullishCoalesce(n.title, () => ("")),className:"rle-card-media"}):_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-media rle-card-media--placeholder","aria-hidden":"true"}),_jsxruntime.jsxs.call(void 0, "div",{className:"rle-card-body",children:[n.title&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-title",children:n.title}),n.subtitle&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-address",children:n.subtitle}),n.badge&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-info",children:_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-info-item",children:n.badge})}),n.price!=null&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-price",children:j(n.price)})]})]});return i?_jsxruntime.jsx.call(void 0, "button",{type:"button",onClick:i,"aria-pressed":_nullishCoalesce(e, () => (!1)),className:r,children:s}):_jsxruntime.jsx.call(void 0, "article",{className:r,children:s})}function Le(t){return _jsxruntime.jsxs.call(void 0, "div",{role:"status",className:"rle-empty",children:[_jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",className:"rle-empty-icon","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "circle",{cx:"11",cy:"11",r:"7"}),_jsxruntime.jsx.call(void 0, "path",{d:"m21 21-4.3-4.3"})]}),_jsxruntime.jsx.call(void 0, "p",{className:"rle-empty-title",children:"No results"}),_jsxruntime.jsx.call(void 0, "p",{className:"rle-empty-hint",children:"Try adjusting your filters or search terms."})]})}function Pe({children:t}){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-panel",children:t})}function Te(t){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-loading",role:"status","aria-busy":"true","aria-label":"Loading results",children:Array.from({length:3}).map((e,i)=>_jsxruntime.jsxs.call(void 0, "div",{className:"rle-loading-item",children:[_jsxruntime.jsx.call(void 0, "div",{className:"rle-skeleton",style:{aspectRatio:"4 / 3",width:"100%"}}),_jsxruntime.jsx.call(void 0, "div",{className:"rle-skeleton",style:{height:16,width:"65%"}}),_jsxruntime.jsx.call(void 0, "div",{className:"rle-skeleton",style:{height:12,width:"35%"}})]},i))})}function Fe({point:t}){let e=_nullishCoalesce(t.entity, () => ({}));return _jsxruntime.jsx.call(void 0, "span",{className:"rle-pin",children:e.price!=null?j(e.price):""})}function Ce({entity:t,onClose:e}){let i=_nullishCoalesce(t, () => ({}));return _jsxruntime.jsxs.call(void 0, "div",{className:"rle-popup",role:"group","aria-label":"Location details",children:[_jsxruntime.jsx.call(void 0, "button",{type:"button",onClick:e,"aria-label":"Close",className:"rle-popup-close",children:_jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "path",{d:"M18 6 6 18"}),_jsxruntime.jsx.call(void 0, "path",{d:"m6 6 12 12"})]})}),_jsxruntime.jsxs.call(void 0, "div",{children:[i.title&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-title",children:i.title}),i.subtitle&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-address",children:i.subtitle}),i.price!=null&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-price",children:j(i.price)})]})]})}function Se({count:t,total:e}){let i=e!=null&&e!==t?`${t} of ${e} results`:`${t} results`;return _jsxruntime.jsx.call(void 0, "div",{className:"rle-result-header",children:i})}function we({value:t,onChange:e,placeholder:i}){return _jsxruntime.jsx.call(void 0, "input",{type:"search",value:t,placeholder:i,onChange:n=>e(n.target.value),"aria-label":_nullishCoalesce(i, () => ("Search")),className:"rle-input"})}function Ie({children:t}){return _jsxruntime.jsx.call(void 0, "aside",{className:"rle-sidebar",children:t})}function Ee({children:t}){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-toolbar",children:t})}var ut={BottomNav:lt,Card:be,Marker:Fe,Popup:Ce,Sidebar:Ie,FilterPanel:Pe,Search:we,Empty:Le,Loading:Te,ResultHeader:Se,Toolbar:Ee};function mt({open:t,onOpenChange:e,title:i,children:n,footer:r}){let s=_react.useRef.call(void 0, null),[o,a]=_react.useState.call(void 0, !1),[p,d]=_react.useState.call(void 0, !1);return _react.useEffect.call(void 0, ()=>{if(!t){d(!1),a(!1);return}a(!0);let l=requestAnimationFrame(()=>d(!0));return()=>cancelAnimationFrame(l)},[t]),_react.useEffect.call(void 0, ()=>{if(!o)return;let l=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=l}},[o]),_react.useEffect.call(void 0, ()=>{if(!o)return;_optionalChain([s, 'access', _31 => _31.current, 'optionalAccess', _32 => _32.focus, 'call', _33 => _33()]);function l(c){c.key==="Escape"&&e(!1)}return document.addEventListener("keydown",l),()=>document.removeEventListener("keydown",l)},[o,e]),!o||typeof document>"u"?null:_reactdom.createPortal.call(void 0, _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[_jsxruntime.jsx.call(void 0, "div",{className:`rle-sheet-backdrop${p?" rle-sheet-backdrop--open":""}`,onClick:()=>e(!1),"aria-hidden":"true"}),_jsxruntime.jsxs.call(void 0, "div",{ref:s,className:`rle-sheet${p?" rle-sheet--open":""}`,role:"dialog","aria-modal":"true","aria-label":i,tabIndex:-1,children:[_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__handle","aria-hidden":"true"}),_jsxruntime.jsxs.call(void 0, "div",{className:"rle-sheet__header",children:[i&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__title",children:i}),_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-sheet__close",onClick:()=>e(!1),"aria-label":"Close",children:_jsxruntime.jsx.call(void 0, ai,{})})]}),_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__body",children:n}),r&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__footer",children:r})]})]}),document.body)}function ai(){return _jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "path",{d:"M18 6 6 18"}),_jsxruntime.jsx.call(void 0, "path",{d:"m6 6 12 12"})]})}function gt({search:t,onFiltersClick:e,filterCount:i=0,action:n}){let{Search:r}=w();return _jsxruntime.jsxs.call(void 0, "header",{className:"rle-mobile-header",children:[t&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-mobile-header__search",children:_jsxruntime.jsx.call(void 0, r,{value:t.value,onChange:t.onChange,placeholder:t.placeholder})}),_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:"rle-btn rle-mobile-header__btn",onClick:e,children:[_jsxruntime.jsx.call(void 0, di,{}),_jsxruntime.jsx.call(void 0, "span",{children:"Filters"}),i>0&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-mobile-header__count",children:i})]}),n&&_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-btn rle-mobile-header__btn rle-mobile-header__btn--icon",onClick:n.onClick,"aria-label":n.label,children:_nullishCoalesce(n.icon, () => (_jsxruntime.jsx.call(void 0, pi,{})))})]})}function di(){return _jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "line",{x1:"4",y1:"6",x2:"20",y2:"6"}),_jsxruntime.jsx.call(void 0, "circle",{cx:"9",cy:"6",r:"2",fill:"currentColor",stroke:"none"}),_jsxruntime.jsx.call(void 0, "line",{x1:"4",y1:"12",x2:"20",y2:"12"}),_jsxruntime.jsx.call(void 0, "circle",{cx:"15",cy:"12",r:"2",fill:"currentColor",stroke:"none"}),_jsxruntime.jsx.call(void 0, "line",{x1:"4",y1:"18",x2:"20",y2:"18"}),_jsxruntime.jsx.call(void 0, "circle",{cx:"11",cy:"18",r:"2",fill:"currentColor",stroke:"none"})]})}function pi(){return _jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "line",{x1:"12",y1:"5",x2:"12",y2:"19"}),_jsxruntime.jsx.call(void 0, "line",{x1:"5",y1:"12",x2:"19",y2:"12"})]})}var ui=_jsxruntime.jsx.call(void 0, "div",{className:"rle-empty",children:"Map unavailable"});function ci(){let t=_react.useRef.call(void 0, null),[e,i]=_react.useState.call(void 0, !0),[n,r]=_react.useState.call(void 0, !0);return _react.useEffect.call(void 0, ()=>{let s=t.current;if(!s)return;let o=()=>{let{clientWidth:c,scrollLeft:y,scrollWidth:v}=s;i(y<=0),r(y+c>=v-1)},a=0,p=()=>{a||(a=requestAnimationFrame(()=>{a=0,o()}))};o(),s.addEventListener("scroll",o,{passive:!0});let d,l;return typeof ResizeObserver<"u"&&(d=new ResizeObserver(o),d.observe(s)),typeof MutationObserver<"u"&&(l=new MutationObserver(p),l.observe(s,{characterData:!0,childList:!0,subtree:!0})),()=>{s.removeEventListener("scroll",o),_optionalChain([d, 'optionalAccess', _34 => _34.disconnect, 'call', _35 => _35()]),_optionalChain([l, 'optionalAccess', _36 => _36.disconnect, 'call', _37 => _37()]),a&&cancelAnimationFrame(a)}},[]),{atEnd:n,atStart:e,ref:t}}function mi(t,e){if(t===e)return!0;if(typeof t!="object"||t===null||typeof e!="object"||e===null)return!1;let i=t,n=e,r=new Set([...Object.keys(i),...Object.keys(n)]);for(let s of r)if(i[s]!==n[s])return!1;return!0}function ft({search:t,filterBarStart:e,toolbarEnd:i,mobileAction:n,autoFetch:r=!0,initialPage:s,hasMap:o,mapCenter:a,mapZoom:p,mapControls:d,onMapReady:l,mobileSheetFooter:c,className:y}){let v=h(),{BottomNav:O,Search:K}=w(),D=W(),{filters:u,set:V}=oe(),{pagination:b}=I(),k=_nullishCoalesce(o, () => (v.map!=null)),[_,H]=_react.useState.call(void 0, "list"),[x,A]=_react.useState.call(void 0, !1),{atEnd:T,atStart:L,ref:f}=ci(),m=_react.useRef.call(void 0, null);_react.useEffect.call(void 0, ()=>{b.mode==="paged"&&m.current&&(m.current.scrollTop=0)},[b.mode,b.pageIndex]);let[F,q]=_react.useState.call(void 0, u),[N,vt]=_react.useState.call(void 0, x);x!==N&&(vt(x),x&&q(u));let Re=ge=>q(bt=>({...bt,...ge})),[De,Be]=_react.useState.call(void 0, !1),me=_react.useRef.call(void 0, !1);_react.useEffect.call(void 0, ()=>{if(De){if(b.loading){me.current=!0;return}me.current&&(me.current=!1,Be(!1),A(!1))}},[De,b.loading]);let Q=t?{value:String(_nullishCoalesce(u[t.filterKey], () => (""))),onChange:ge=>{V({[t.filterKey]:ge||void 0})},placeholder:t.placeholder}:void 0;_react.useEffect.call(void 0, ()=>{r!==!1&&(s&&s>0?v.goToPage(s):v.applyFilters({}))},[v,r]);let Oe=()=>{Re(v.filters.clearedParams())},_e=()=>{if(mi(F,u)){A(!1);return}Be(!0),v.applyFilters(F)},ht=v.filters.activeKeys(u).length,He=_nullishCoalesce(D.total, () => (D.items.length));return _jsxruntime.jsxs.call(void 0, "div",{className:y?`rle-app ${y}`:"rle-app",children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-filter-bar",children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-filter-bar__scroll",ref:f,children:[Q&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__search",children:_jsxruntime.jsx.call(void 0, K,{value:Q.value,onChange:Q.onChange,placeholder:Q.placeholder})}),e&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__slot",children:e}),_jsxruntime.jsx.call(void 0, ye,{className:"rle-filters-row",groupClassName:"rle-filter-group",hideLabels:!0})]}),!L&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__fade rle-filter-bar__fade--start","aria-hidden":"true"}),!T&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__fade rle-filter-bar__fade--end","aria-hidden":"true"})]}),_jsxruntime.jsx.call(void 0, gt,{search:Q,onFiltersClick:()=>A(!0),filterCount:ht,action:n}),_jsxruntime.jsxs.call(void 0, "div",{className:`rle-body ${k?"rle-split":"rle-body--list-only"}`,"data-mobile-view":_,children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-list",ref:m,children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-list-header",children:[_jsxruntime.jsx.call(void 0, rt,{}),i&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-list-header__toolbar",children:i})]}),_jsxruntime.jsx.call(void 0, Xe,{className:"rle-list-grid"}),_jsxruntime.jsx.call(void 0, nt,{})]}),k&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-map",children:_jsxruntime.jsx.call(void 0, it,{center:a,zoom:p,fallback:ui,mapControls:d,onMapReady:l})})]}),k&&_jsxruntime.jsx.call(void 0, O,{view:_,onViewChange:H}),_jsxruntime.jsx.call(void 0, mt,{title:"Filters",open:x,onOpenChange:A,footer:c?c({draft:F,apply:_e,clear:Oe,resultCount:He,loading:b.loading}):_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-btn rle-btn--ghost",onClick:Oe,children:"Clear all"}),_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-btn rle-btn--primary rle-sheet__apply",disabled:b.loading,onClick:_e,children:b.loading?_jsxruntime.jsx.call(void 0, "span",{className:"rle-spinner","aria-label":"Updating results"}):`Show ${He} results`})]}),children:_jsxruntime.jsx.call(void 0, ye,{className:"rle-filter-stack",groupClassName:"rle-filter-group",draft:F,onDraftChange:Re})})]})}function yt(t){return"provider"in t}function hi(t){let e=t!=null&&!yt(t),i=e?t.apiKey:void 0,n=e?t.mapId:void 0,r=e?t.mapOptions:void 0,s=e?t.styles:void 0,o=e?t.overlayMarkers:void 0,[a,p]=_react.useState.call(void 0, ()=>!t||yt(t)?{ready:!0,provider:_optionalChain([t, 'optionalAccess', _38 => _38.provider])}:{ready:!1});return _react.useEffect.call(void 0, ()=>{if(!i)return;let d=!1;return Promise.resolve().then(() => _interopRequireWildcard(require("./maps/google/index.cjs"))).then(({googleProvider:l})=>{d||p({ready:!0,provider:l({apiKey:i,mapId:n,mapOptions:r,styles:s,overlayMarkers:o})})}),()=>{d=!0}},[i,n]),a}function bi({onFiltersChange:t}){let e=_react.useRef.call(void 0, t);return e.current=t,st("FiltersChanged",i=>{i.type==="FiltersChanged"&&e.current(i.filters)}),null}function zr(t){let{datasets:e,filters:i,map:n,components:r,initialFilters:s,onFiltersChange:o,mobileAction:a,search:p,filterBarStart:d,toolbarEnd:l,mapControls:c,onMapReady:y,mobileSheetFooter:v,config:O,autoFetch:K,initialPage:D,className:u}=t,{ready:V,provider:b}=hi(n);if(!V)return null;let k=[];for(let x of e)k.push(Ve(x));i&&k.push(qe(i)),b&&k.push(Ke(b)),s&&k.push($e(s)),O&&k.push(Ue(O));let _=ze(...k),H={...ut,...r};return _jsxruntime.jsxs.call(void 0, at,{..._,children:[o&&_jsxruntime.jsx.call(void 0, bi,{onFiltersChange:o}),_jsxruntime.jsx.call(void 0, je,{...H,children:_jsxruntime.jsx.call(void 0, ft,{className:u,search:p,filterBarStart:d,toolbarEnd:l,mobileAction:a,autoFetch:K,mapCenter:_optionalChain([n, 'optionalAccess', _39 => _39.center]),mapZoom:_optionalChain([n, 'optionalAccess', _40 => _40.zoom]),mapControls:c,onMapReady:y,initialPage:D,mobileSheetFooter:v})})]})}exports.a = ee; exports.b = $; exports.c = te; exports.d = ie; exports.e = Ae; exports.f = ne; exports.g = re; exports.h = ze; exports.i = Ue; exports.j = Ke; exports.k = Ve; exports.l = qe; exports.m = Bi; exports.n = $e; exports.o = Oi; exports.p = fe; exports.q = je; exports.r = w; exports.s = se; exports.t = h; exports.u = I; exports.v = oe; exports.w = ye; exports.x = W; exports.y = Xe; exports.z = it; exports.A = nt; exports.B = rt; exports.C = st; exports.D = at; exports.E = lt; exports.F = be; exports.G = Le; exports.H = Pe; exports.I = Te; exports.J = Fe; exports.K = Ce; exports.L = Se; exports.M = we; exports.N = Ie; exports.O = Ee; exports.P = ut; exports.Q = mt; exports.R = ft; exports.S = zr;
@@ -1,2 +0,0 @@
1
- "use client";
2
- var ee=class{state;listeners=new Set;constructor(e){this.state=this.freezeState({filters:{...e.filters},results:{items:[],nextCursor:null},bounds:null,selection:null,hovered:null,pagination:{mode:e.mode??"paged",loading:!1,pageIndex:0},layers:{},points:{}})}getState(){return this.state}setFilters(e){this.setState({filters:{...this.state.filters,...e}})}setResults(e){this.setState({results:{items:[...e.items],nextCursor:e.nextCursor,total:e.total}})}appendResults(e){this.setState({results:{items:[...this.state.results.items,...e.items],nextCursor:e.nextCursor,total:e.total}})}setBounds(e){this.setState({bounds:e?{...e}:null})}setSelection(e){this.setState({selection:e})}setHovered(e){this.setState({hovered:e})}setLayerVisible(e,i){this.setState({layers:{...this.state.layers,[e]:i}})}setLoading(e){this.setState({pagination:{...this.state.pagination,loading:e}})}setPageIndex(e){this.setState({pagination:{...this.state.pagination,pageIndex:e}})}setPoints(e,i){this.setState({points:{...this.state.points,[e]:[...i]}})}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}setState(e){this.state=this.freezeState({...this.state,...e}),this.notify()}notify(){for(let e of this.listeners)e()}freezeState(e){Object.freeze(e.filters),Object.freeze(e.results.items),Object.freeze(e.results),e.bounds&&Object.freeze(e.bounds),Object.freeze(e.pagination),Object.freeze(e.layers);for(let i of Object.values(e.points))Object.freeze(i);return Object.freeze(e.points),Object.freeze(e)}};var $=class{defs=new Map;add(e){if(this.defs.has(e.key))throw new Error(`FilterRegistry: filter "${e.key}" is already registered`);return this.defs.set(e.key,{...e}),this}remove(e){return this.defs.delete(e),this}replace(e,i){if(!this.defs.has(e))throw new Error(`FilterRegistry: cannot replace unregistered filter "${e}"`);return this.defs.set(e,{...i,key:e}),this}reorder(e){let i=this.list(),n=e.filter(s=>this.defs.has(s));n.forEach((s,o)=>{this.defs.get(s).order=o});let r=new Set(n);return i.filter(s=>!r.has(s.key)).forEach((s,o)=>{s.order=n.length+o}),this}list(){return[...this.defs.values()].sort((e,i)=>e.order-i.order)}has(e){return this.defs.has(e)}toFilters(e){return this.list().filter(n=>Object.hasOwn(e,n.key)).map(n=>n.toParams(e[n.key])).reduce((n,r)=>({...n,...r}),{})}activeKeys(e){return this.list().filter(i=>i.isActive?.(e)).map(i=>i.key)}clearedParams(){return this.list().reduce((e,i)=>Object.assign(e,i.toParams(i.fromParams({}))),{})}};var te=class{defs=new Map;add(e){if(this.defs.has(e.id))throw new Error(`DatasetRegistry: dataset "${e.id}" is already registered`);return this.defs.set(e.id,{...e}),this}get(e){return this.defs.get(e)}has(e){return this.defs.has(e)}list(){return[...this.defs.values()]}visibleIds(){return this.list().filter(e=>e.visible?.()!==!1).map(e=>e.id)}};var ie=class{map=new Map;dispose(){this.map.clear()}emit(e){let i=this.map.get(e.type);if(i)for(let r of[...i])r(e);let n=this.map.get("*");if(n)for(let r of[...n])r(e)}on(e,i){let n=this.map.get(e);return n||(n=new Set,this.map.set(e,n)),n.add(i),()=>{n.delete(i)}}};var Ae={pagination:"paged",pageSize:20,debounceMs:250};var ne=class{options;constructor(e){this.options=Object.freeze({...Ae,...e})}};var re=class{filters;map;datasets;primaryDatasetId;store;emitter=new ie;config;debounceTimer=null;debounceResolve=null;queryToken=0;pointsToken=0;mapHandle=null;constructor(e){this.datasets=e.datasets,this.filters=e.filters??new $,this.map=e.map,this.config=new ne(e.config);let i=e.primaryDatasetId??this.datasets.list()[0]?.id;if(i==null||!this.datasets.has(i))throw new Error(`ListingEngine: primary dataset "${i??""}" is not registered \u2014 pass a valid primaryDatasetId or register at least one dataset`);this.primaryDatasetId=i,this.store=new ee({filters:e.initialFilters??{},mode:this.config.options.pagination})}get state(){return this.store.getState()}get options(){return this.config.options}applyFilters(e){this.store.setFilters(e),this.emitter.emit({type:"FiltersChanged",filters:this.currentFilters()}),this.clearDebounce();let i=++this.queryToken,n=this.config.options.debounceMs;return n<=0?this.runQuery(i):new Promise(r=>{this.debounceResolve=r,this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.debounceResolve=null,r(this.runQuery(i))},n)})}async loadPage(){let e=this.state.results.nextCursor;if(e===null)return;let i=++this.queryToken,n=this.primaryDataset();this.store.setLoading(!0);try{let r=await n.adapter.list(this.currentFilters(),{cursor:e,limit:this.config.options.pageSize});if(i!==this.queryToken)return;this.config.options.pagination==="infinite"?this.store.appendResults(r):this.store.setResults(r),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:r.items.length})}finally{i===this.queryToken&&this.store.setLoading(!1)}}async goToPage(e){if(e<0)return;let i=++this.queryToken,n=this.primaryDataset();this.store.setLoading(!0);try{let r=await n.adapter.list(this.currentFilters(),{offset:e*this.config.options.pageSize,limit:this.config.options.pageSize});if(i!==this.queryToken)return;this.store.setResults(r),this.store.setPageIndex(e),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:r.items.length})}finally{i===this.queryToken&&this.store.setLoading(!1)}}async loadPoints(e){this.store.setBounds(e),this.emitter.emit({type:"BoundsChanged",bounds:e});let i=this.currentFilters(),n=++this.pointsToken;await Promise.allSettled(this.datasets.visibleIds().map(async r=>{let s=this.datasets.get(r);if(!s)return;let o=await s.adapter.getPoints(i,e);n===this.pointsToken&&this.store.setPoints(r,o)}))}setMapHandle(e){this.mapHandle=e}fitBounds(e,i){!this.map||!this.mapHandle||this.map.fitBounds(this.mapHandle,e,i)}selectPoint(e,i){this.store.setSelection(i);let n=this.state.points[e]?.find(r=>r.id===i);n&&this.emitter.emit({type:"PointClicked",datasetId:e,id:n.id,entity:n.entity})}setHovered(e,i){this.store.setHovered(i)}toggleLayer(e){let n=!(this.state.layers[e]??!0);this.store.setLayerVisible(e,n),this.emitter.emit({type:"LayerToggled",datasetId:e,visible:n})}subscribe(e){return this.store.subscribe(e)}on(e,i){return this.emitter.on(e,i)}dispose(){this.clearDebounce(),this.emitter.dispose(),this.mapHandle=null}async runQuery(e){if(e!==this.queryToken)return;let i=this.primaryDataset();this.store.setLoading(!0);try{let n=await i.adapter.list(this.currentFilters(),{cursor:null,limit:this.config.options.pageSize});if(e!==this.queryToken)return;this.store.setResults(n),this.store.setPageIndex(0),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:n.items.length})}finally{e===this.queryToken&&this.store.setLoading(!1)}}primaryDataset(){return this.datasets.get(this.primaryDatasetId)}currentFilters(){return this.store.getState().filters}clearDebounce(){this.debounceTimer!==null&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.debounceResolve!==null&&(this.debounceResolve(),this.debounceResolve=null)}};function ze(...t){let e={config:{},filters:new $,datasets:new te};for(let i of t)i(e);return e}var Ue=t=>e=>{e.config={...e.config,...t}},Ke=t=>e=>{e.map=t},Ve=t=>e=>{e.datasets.add(t)},qe=t=>e=>{t(e.filters)},Bi=t=>e=>{e.urlSync=t},$e=t=>e=>{e.initialFilters=t},Oi=t=>e=>{e.primaryDatasetId=t};import{createContext as Lt,useContext as Pt}from"react";import{jsx as S,jsxs as Ge}from"react/jsx-runtime";function Tt(t){return String(t?.title??"")}var Ft=({item:t})=>S("div",{children:Tt(t)}),kt=()=>S("div",{}),fe=()=>S("div",{}),Ct=({children:t})=>S("div",{children:t}),St=({children:t})=>S("div",{children:t}),wt=({value:t,onChange:e,placeholder:i})=>S("input",{type:"search",value:t,placeholder:i,onChange:n=>e(n.target.value),"aria-label":i??"Search"}),It=()=>S("div",{role:"status",children:"No results"}),Et=()=>S("div",{role:"status","aria-busy":"true",children:"Loading\u2026"}),xt=({count:t})=>Ge("div",{children:[t," results"]}),Nt=({children:t})=>S("div",{children:t}),Mt=({view:t,onViewChange:e})=>Ge("nav",{"aria-label":"Listing navigation",children:[S("button",{type:"button","aria-pressed":t==="list",onClick:()=>e("list"),children:"List"}),S("button",{type:"button","aria-pressed":t==="map",onClick:()=>e("map"),children:"Map"})]}),C={BottomNav:Mt,Card:Ft,Marker:kt,Popup:fe,Sidebar:Ct,FilterPanel:St,Search:wt,Empty:It,Loading:Et,ResultHeader:xt,Toolbar:Nt},We=Lt(C);function je(t){let{BottomNav:e,Card:i,Marker:n,Popup:r,Sidebar:s,FilterPanel:o,Search:a,Empty:p,Loading:d,ResultHeader:l,Toolbar:c,children:y}=t,v={BottomNav:e??C.BottomNav,Card:i??C.Card,Marker:n??C.Marker,Popup:r??C.Popup,Sidebar:s??C.Sidebar,FilterPanel:o??C.FilterPanel,Search:a??C.Search,Empty:p??C.Empty,Loading:d??C.Loading,ResultHeader:l??C.ResultHeader,Toolbar:c??C.Toolbar};return S(We.Provider,{value:v,children:y})}function w(){return Pt(We)}import{createContext as Rt}from"react";var se=Rt(null);import{useContext as Dt}from"react";function h(){let t=Dt(se);if(t===null)throw new Error("useListing must be used within a <ListingProvider>");return t}import{useCallback as Qe,useSyncExternalStore as Bt}from"react";function I(){let t=h(),e=Qe(n=>t.subscribe(n),[t]),i=Qe(()=>t.state,[t]);return Bt(e,i,i)}import{useCallback as Ze}from"react";function oe(){let t=h(),e=I(),i=Ze(r=>t.applyFilters(r),[t]),n=Ze((r,s)=>t.applyFilters({[r]:s}),[t]);return{filters:e.filters,set:i,setField:n}}import{jsx as Z,jsxs as Ot}from"react/jsx-runtime";function ye({className:t,groupClassName:e,hideLabels:i,draft:n,onDraftChange:r}={}){let s=h(),{FilterPanel:o}=w(),{filters:a}=oe(),p=n!==void 0&&r!==void 0,d=p?n:a;return Z(o,{children:Z("div",{className:t??"space-y-5",children:s.filters.list().map(l=>{if(typeof l.render=="string")return Z("div",{"data-filter":l.key,className:e},l.key);let c=l.render;return Ot("div",{className:e,children:[l.label&&!i&&Z("div",{className:"mb-1.5 text-[13px] font-medium text-foreground",children:l.label}),Z(c,{value:l.fromParams(d),onChange:y=>p?r(l.toParams(y)):void s.applyFilters(l.toParams(y))})]},l.key)})})})}function W(){return I().results}import{jsx as ae}from"react/jsx-runtime";function _t(t,e){if(t&&typeof t=="object"&&"id"in t){let i=t.id;if(typeof i=="string"||typeof i=="number")return i}return e}function Xe({className:t}={}){let e=h(),{items:i}=W(),{pagination:n,selection:r}=I(),{Card:s,Empty:o,Loading:a}=w();return n.loading&&i.length===0?ae(a,{}):i.length===0?ae(o,{}):ae("div",{role:"list",className:t,children:i.map((p,d)=>{let l=_t(p,d);return ae(s,{item:p,selected:r===l,onSelect:()=>e.selectPoint(e.primaryDatasetId,l)},l)})})}import{useEffect as X,useRef as B,useState as Je}from"react";import{createPortal as Ht}from"react-dom";import{jsx as ve,jsxs as tt}from"react/jsx-runtime";var At={west:-179.9,south:-85,east:179.9,north:85},Ye=.1,et=.02;function zt(t){if(t.length===0)return null;let e=t[0].lng,i=t[0].lng,n=t[0].lat,r=t[0].lat;for(let{lat:a,lng:p}of t)p<e&&(e=p),p>i&&(i=p),a<n&&(n=a),a>r&&(r=a);let s=r>n?(r-n)*Ye:et,o=i>e?(i-e)*Ye:et;return{west:e-o,east:i+o,south:n-s,north:r+s}}function it(t){let{center:e,zoom:i,fallback:n,mapControls:r,onMapReady:s}=t,o=h(),a=I(),p=B(s);p.current=s;let d=B(null),l=B(null),c=B(null),[y,v]=Je(!1),O=B(!1),K=B(!1),D=B(!1),u=o.map;X(()=>{let T=c.current;if(!u||!T)return;let L=[];for(let f of Object.keys(a.points)){if(a.layers[f]===!1)continue;let m=o.datasets.get(f),F=a.points[f]??[],q={id:f,markers:F.map(N=>({id:N.id,position:N.position,iconUrl:m?.marker.iconUrl?.(N.entity),element:m?.marker.element?.(N.entity)})),clustering:m?.clustering,onMarkerClick:N=>o.selectPoint(f,N)};L.push(u.renderLayer(T,q))}return()=>{L.forEach(f=>f())}},[o,u,y,a.points,a.layers]),X(()=>{if(!d.current||!u)return;let T=d.current,L=!1,f=null;return(async()=>{let m=await u.mount(T,{center:e,zoom:i,fullscreenTarget:l.current??void 0});if(L){u.destroy(m);return}c.current=m,o.setMapHandle(m),f=u.onBoundsChange(m,F=>{D.current?D.current=!1:K.current=!0,o.loadPoints(F)}),v(!0),p.current?.(m.nativeMap??m.raw),o.loadPoints(At)})(),()=>{L=!0,f?.(),c.current&&(u.destroy(c.current),c.current=null,o.setMapHandle(null),p.current?.(null)),v(!1)}},[o,u]),X(()=>{let T=c.current;if(!u||!T||e||O.current||K.current)return;let L=[];for(let m of Object.keys(a.points))if(a.layers[m]!==!1)for(let F of a.points[m]??[])L.push(F.position);let f=zt(L);f&&(O.current=!0,D.current=!0,u.fitBounds(T,f))},[u,e,y,a.points,a.layers]),X(()=>{u?.updateMarkerStates(a.selection,a.hovered)},[u,y,a.selection,a.hovered]);let{Popup:V}=w(),b=V!==fe,k=a.points[o.primaryDatasetId]??[],_=a.selection!=null?k.find(T=>T.id===a.selection):void 0,[H,x]=Je(null),A=B(_);return A.current=_,X(()=>{let T=c.current;if(!u||!T||!b)return;let L=A.current;if(!L)return;let f=u.mountOverlay(L.position);x({entity:L.entity,position:L.position,container:f.container});let m=()=>o.selectPoint(o.primaryDatasetId,null),F=N=>{N.key==="Escape"&&m()};document.addEventListener("keydown",F);let q=u.onMapClick(m);return()=>{document.removeEventListener("keydown",F),q(),f.unmount(),x(null)}},[o,u,y,a.selection,b]),tt("div",{ref:l,className:"relative h-full min-h-0 w-full",children:[tt("div",{ref:d,className:!u&&n?"flex h-full min-h-0 w-full items-center justify-center":"h-full min-h-0 w-full",children:[!u&&n,b&&H?Ht(ve(V,{entity:H.entity,onClose:()=>o.selectPoint(o.primaryDatasetId,null)}),H.container):null]}),r!=null&&ve("div",{className:"pointer-events-none absolute inset-0",children:ve("div",{className:"pointer-events-auto",children:r})})]})}import{jsx as J,jsxs as Kt}from"react/jsx-runtime";var he="gap";function Ut(t,e){if(t<=7)return Array.from({length:t},(s,o)=>o+1);let i=Math.max(2,e-1),n=Math.min(t-1,e+1),r=[1];i>2&&r.push(he);for(let s=i;s<=n;s+=1)r.push(s);return n<t-1&&r.push(he),r.push(t),r}function nt(){let t=h(),{results:e,pagination:i}=I();if(i.mode==="infinite")return e.nextCursor==null?null:J("button",{type:"button",disabled:i.loading,onClick:()=>{t.loadPage()},children:"Load more"});let n=t.options.pageSize,{pageIndex:r}=i,s=r+1,o=e.total!=null?Math.ceil(e.total/n):null,a=o!=null?s<o:e.nextCursor!=null||e.items.length>=n;if(o!=null?o<=1:r===0&&!a)return null;let p=d=>()=>{t.goToPage(d)};return Kt("nav",{className:"rle-pagination","aria-label":"Pagination",children:[J("button",{type:"button",className:"rle-page-btn rle-page-btn--nav","aria-label":"Previous page",disabled:i.loading||r===0,onClick:p(r-1),children:"\u2039"}),o!=null&&Ut(o,s).map((d,l)=>d===he?J("span",{className:"rle-page-ellipsis",children:"\u2026"},`gap-${l}`):J("button",{type:"button",className:d===s?"rle-page-btn rle-page-btn--active":"rle-page-btn","aria-label":`Page ${d}`,"aria-current":d===s?"page":void 0,disabled:i.loading,onClick:p(d-1),children:d},d)),J("button",{type:"button",className:"rle-page-btn rle-page-btn--nav","aria-label":"Next page",disabled:i.loading||!a,onClick:p(r+1),children:"\u203A"})]})}import{jsx as Vt}from"react/jsx-runtime";function rt(){let{items:t,total:e}=W(),{ResultHeader:i}=w();return Vt(i,{count:t.length,total:e})}import{useEffect as qt,useRef as $t}from"react";function st(t,e){let i=h(),n=$t(e);n.current=e,qt(()=>i.on(t,r=>n.current(r)),[i,t])}import{useEffect as Wt,useState as ot}from"react";import{jsx as jt}from"react/jsx-runtime";function at(t){let{children:e,...i}=t,[n]=ot(()=>i),[r,s]=ot(null);return Wt(()=>{let o=new re({datasets:n.datasets,filters:n.filters,config:n.config,map:n.map,initialFilters:n.initialFilters,primaryDatasetId:n.primaryDatasetId});return n.urlSync&&n.urlSync.start(o),s(o),()=>{n.urlSync&&n.urlSync.stop(),o.dispose(),s(a=>a===o?null:a)}},[n]),r?jt(se.Provider,{value:r,children:e}):null}import{jsx as E,jsxs as Y}from"react/jsx-runtime";function lt({view:t,onViewChange:e}){return E("nav",{className:"rle-bottom-nav","aria-label":"Listing navigation",children:Y("div",{className:"rle-viewtoggle",role:"group","aria-label":"View",children:[Y("button",{type:"button",className:`rle-viewtoggle__btn${t==="list"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":t==="list",onClick:()=>e("list"),children:[E(Gt,{}),"List"]}),Y("button",{type:"button",className:`rle-viewtoggle__btn${t==="map"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":t==="map",onClick:()=>e("map"),children:[E(Qt,{}),"Map"]})]})})}function Gt(){return Y("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[E("line",{x1:"8",y1:"6",x2:"20",y2:"6"}),E("line",{x1:"8",y1:"12",x2:"20",y2:"12"}),E("line",{x1:"8",y1:"18",x2:"20",y2:"18"}),E("line",{x1:"4",y1:"6",x2:"4.01",y2:"6"}),E("line",{x1:"4",y1:"12",x2:"4.01",y2:"12"}),E("line",{x1:"4",y1:"18",x2:"4.01",y2:"18"})]})}function Qt(){return Y("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[E("polygon",{points:"1 6 8 3 16 6 23 3 23 18 16 21 8 18 1 21 1 6"}),E("line",{x1:"8",y1:"3",x2:"8",y2:"18"}),E("line",{x1:"16",y1:"6",x2:"16",y2:"21"})]})}function j(t){return typeof t!="number"?t:new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(t)}import{Fragment as Xt,jsx as M,jsxs as dt}from"react/jsx-runtime";function Zt(t){return t?"rle-card rle-card--selected":"rle-card"}function be({item:t,selected:e,onSelect:i}){let n=t??{},r=Zt(e),s=dt(Xt,{children:[n.imageUrl?M("img",{src:n.imageUrl,alt:n.title??"",className:"rle-card-media"}):M("div",{className:"rle-card-media rle-card-media--placeholder","aria-hidden":"true"}),dt("div",{className:"rle-card-body",children:[n.title&&M("span",{className:"rle-card-title",children:n.title}),n.subtitle&&M("span",{className:"rle-card-address",children:n.subtitle}),n.badge&&M("div",{className:"rle-card-info",children:M("span",{className:"rle-card-info-item",children:n.badge})}),n.price!=null&&M("span",{className:"rle-card-price",children:j(n.price)})]})]});return i?M("button",{type:"button",onClick:i,"aria-pressed":e??!1,className:r,children:s}):M("article",{className:r,children:s})}import{jsx as le,jsxs as pt}from"react/jsx-runtime";function Le(t){return pt("div",{role:"status",className:"rle-empty",children:[pt("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",className:"rle-empty-icon","aria-hidden":"true",children:[le("circle",{cx:"11",cy:"11",r:"7"}),le("path",{d:"m21 21-4.3-4.3"})]}),le("p",{className:"rle-empty-title",children:"No results"}),le("p",{className:"rle-empty-hint",children:"Try adjusting your filters or search terms."})]})}import{jsx as Jt}from"react/jsx-runtime";function Pe({children:t}){return Jt("div",{className:"rle-filter-panel",children:t})}import{jsx as de,jsxs as Yt}from"react/jsx-runtime";function Te(t){return de("div",{className:"rle-loading",role:"status","aria-busy":"true","aria-label":"Loading results",children:Array.from({length:3}).map((e,i)=>Yt("div",{className:"rle-loading-item",children:[de("div",{className:"rle-skeleton",style:{aspectRatio:"4 / 3",width:"100%"}}),de("div",{className:"rle-skeleton",style:{height:16,width:"65%"}}),de("div",{className:"rle-skeleton",style:{height:12,width:"35%"}})]},i))})}import{jsx as ei}from"react/jsx-runtime";function Fe({point:t}){let e=t.entity??{};return ei("span",{className:"rle-pin",children:e.price!=null?j(e.price):""})}import{jsx as G,jsxs as ke}from"react/jsx-runtime";function Ce({entity:t,onClose:e}){let i=t??{};return ke("div",{className:"rle-popup",role:"group","aria-label":"Location details",children:[G("button",{type:"button",onClick:e,"aria-label":"Close",className:"rle-popup-close",children:ke("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[G("path",{d:"M18 6 6 18"}),G("path",{d:"m6 6 12 12"})]})}),ke("div",{children:[i.title&&G("div",{className:"rle-card-title",children:i.title}),i.subtitle&&G("div",{className:"rle-card-address",children:i.subtitle}),i.price!=null&&G("div",{className:"rle-card-price",children:j(i.price)})]})]})}import{jsx as ti}from"react/jsx-runtime";function Se({count:t,total:e}){let i=e!=null&&e!==t?`${t} of ${e} results`:`${t} results`;return ti("div",{className:"rle-result-header",children:i})}import{jsx as ii}from"react/jsx-runtime";function we({value:t,onChange:e,placeholder:i}){return ii("input",{type:"search",value:t,placeholder:i,onChange:n=>e(n.target.value),"aria-label":i??"Search",className:"rle-input"})}import{jsx as ni}from"react/jsx-runtime";function Ie({children:t}){return ni("aside",{className:"rle-sidebar",children:t})}import{jsx as ri}from"react/jsx-runtime";function Ee({children:t}){return ri("div",{className:"rle-toolbar",children:t})}var ut={BottomNav:lt,Card:be,Marker:Fe,Popup:Ce,Sidebar:Ie,FilterPanel:Pe,Search:we,Empty:Le,Loading:Te,ResultHeader:Se,Toolbar:Ee};import{useEffect as xe,useRef as si,useState as ct}from"react";import{createPortal as oi}from"react-dom";import{Fragment as li,jsx as R,jsxs as pe}from"react/jsx-runtime";function mt({open:t,onOpenChange:e,title:i,children:n,footer:r}){let s=si(null),[o,a]=ct(!1),[p,d]=ct(!1);return xe(()=>{if(!t){d(!1),a(!1);return}a(!0);let l=requestAnimationFrame(()=>d(!0));return()=>cancelAnimationFrame(l)},[t]),xe(()=>{if(!o)return;let l=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=l}},[o]),xe(()=>{if(!o)return;s.current?.focus();function l(c){c.key==="Escape"&&e(!1)}return document.addEventListener("keydown",l),()=>document.removeEventListener("keydown",l)},[o,e]),!o||typeof document>"u"?null:oi(pe(li,{children:[R("div",{className:`rle-sheet-backdrop${p?" rle-sheet-backdrop--open":""}`,onClick:()=>e(!1),"aria-hidden":"true"}),pe("div",{ref:s,className:`rle-sheet${p?" rle-sheet--open":""}`,role:"dialog","aria-modal":"true","aria-label":i,tabIndex:-1,children:[R("div",{className:"rle-sheet__handle","aria-hidden":"true"}),pe("div",{className:"rle-sheet__header",children:[i&&R("div",{className:"rle-sheet__title",children:i}),R("button",{type:"button",className:"rle-sheet__close",onClick:()=>e(!1),"aria-label":"Close",children:R(ai,{})})]}),R("div",{className:"rle-sheet__body",children:n}),r&&R("div",{className:"rle-sheet__footer",children:r})]})]}),document.body)}function ai(){return pe("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[R("path",{d:"M18 6 6 18"}),R("path",{d:"m6 6 12 12"})]})}import{useEffect as ce,useRef as Ne,useState as U}from"react";import{jsx as P,jsxs as ue}from"react/jsx-runtime";function gt({search:t,onFiltersClick:e,filterCount:i=0,action:n}){let{Search:r}=w();return ue("header",{className:"rle-mobile-header",children:[t&&P("div",{className:"rle-mobile-header__search",children:P(r,{value:t.value,onChange:t.onChange,placeholder:t.placeholder})}),ue("button",{type:"button",className:"rle-btn rle-mobile-header__btn",onClick:e,children:[P(di,{}),P("span",{children:"Filters"}),i>0&&P("span",{className:"rle-mobile-header__count",children:i})]}),n&&P("button",{type:"button",className:"rle-btn rle-mobile-header__btn rle-mobile-header__btn--icon",onClick:n.onClick,"aria-label":n.label,children:n.icon??P(pi,{})})]})}function di(){return ue("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[P("line",{x1:"4",y1:"6",x2:"20",y2:"6"}),P("circle",{cx:"9",cy:"6",r:"2",fill:"currentColor",stroke:"none"}),P("line",{x1:"4",y1:"12",x2:"20",y2:"12"}),P("circle",{cx:"15",cy:"12",r:"2",fill:"currentColor",stroke:"none"}),P("line",{x1:"4",y1:"18",x2:"20",y2:"18"}),P("circle",{cx:"11",cy:"18",r:"2",fill:"currentColor",stroke:"none"})]})}function pi(){return ue("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[P("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),P("line",{x1:"5",y1:"12",x2:"19",y2:"12"})]})}import{Fragment as gi,jsx as g,jsxs as z}from"react/jsx-runtime";var ui=g("div",{className:"rle-empty",children:"Map unavailable"});function ci(){let t=Ne(null),[e,i]=U(!0),[n,r]=U(!0);return ce(()=>{let s=t.current;if(!s)return;let o=()=>{let{clientWidth:c,scrollLeft:y,scrollWidth:v}=s;i(y<=0),r(y+c>=v-1)},a=0,p=()=>{a||(a=requestAnimationFrame(()=>{a=0,o()}))};o(),s.addEventListener("scroll",o,{passive:!0});let d,l;return typeof ResizeObserver<"u"&&(d=new ResizeObserver(o),d.observe(s)),typeof MutationObserver<"u"&&(l=new MutationObserver(p),l.observe(s,{characterData:!0,childList:!0,subtree:!0})),()=>{s.removeEventListener("scroll",o),d?.disconnect(),l?.disconnect(),a&&cancelAnimationFrame(a)}},[]),{atEnd:n,atStart:e,ref:t}}function mi(t,e){if(t===e)return!0;if(typeof t!="object"||t===null||typeof e!="object"||e===null)return!1;let i=t,n=e,r=new Set([...Object.keys(i),...Object.keys(n)]);for(let s of r)if(i[s]!==n[s])return!1;return!0}function ft({search:t,filterBarStart:e,toolbarEnd:i,mobileAction:n,autoFetch:r=!0,initialPage:s,hasMap:o,mapCenter:a,mapZoom:p,mapControls:d,onMapReady:l,mobileSheetFooter:c,className:y}){let v=h(),{BottomNav:O,Search:K}=w(),D=W(),{filters:u,set:V}=oe(),{pagination:b}=I(),k=o??v.map!=null,[_,H]=U("list"),[x,A]=U(!1),{atEnd:T,atStart:L,ref:f}=ci(),m=Ne(null);ce(()=>{b.mode==="paged"&&m.current&&(m.current.scrollTop=0)},[b.mode,b.pageIndex]);let[F,q]=U(u),[N,vt]=U(x);x!==N&&(vt(x),x&&q(u));let Re=ge=>q(bt=>({...bt,...ge})),[De,Be]=U(!1),me=Ne(!1);ce(()=>{if(De){if(b.loading){me.current=!0;return}me.current&&(me.current=!1,Be(!1),A(!1))}},[De,b.loading]);let Q=t?{value:String(u[t.filterKey]??""),onChange:ge=>{V({[t.filterKey]:ge||void 0})},placeholder:t.placeholder}:void 0;ce(()=>{r!==!1&&(s&&s>0?v.goToPage(s):v.applyFilters({}))},[v,r]);let Oe=()=>{Re(v.filters.clearedParams())},_e=()=>{if(mi(F,u)){A(!1);return}Be(!0),v.applyFilters(F)},ht=v.filters.activeKeys(u).length,He=D.total??D.items.length;return z("div",{className:y?`rle-app ${y}`:"rle-app",children:[z("div",{className:"rle-filter-bar",children:[z("div",{className:"rle-filter-bar__scroll",ref:f,children:[Q&&g("div",{className:"rle-filter-bar__search",children:g(K,{value:Q.value,onChange:Q.onChange,placeholder:Q.placeholder})}),e&&g("div",{className:"rle-filter-bar__slot",children:e}),g(ye,{className:"rle-filters-row",groupClassName:"rle-filter-group",hideLabels:!0})]}),!L&&g("div",{className:"rle-filter-bar__fade rle-filter-bar__fade--start","aria-hidden":"true"}),!T&&g("div",{className:"rle-filter-bar__fade rle-filter-bar__fade--end","aria-hidden":"true"})]}),g(gt,{search:Q,onFiltersClick:()=>A(!0),filterCount:ht,action:n}),z("div",{className:`rle-body ${k?"rle-split":"rle-body--list-only"}`,"data-mobile-view":_,children:[z("div",{className:"rle-list",ref:m,children:[z("div",{className:"rle-list-header",children:[g(rt,{}),i&&g("div",{className:"rle-list-header__toolbar",children:i})]}),g(Xe,{className:"rle-list-grid"}),g(nt,{})]}),k&&g("div",{className:"rle-map",children:g(it,{center:a,zoom:p,fallback:ui,mapControls:d,onMapReady:l})})]}),k&&g(O,{view:_,onViewChange:H}),g(mt,{title:"Filters",open:x,onOpenChange:A,footer:c?c({draft:F,apply:_e,clear:Oe,resultCount:He,loading:b.loading}):z(gi,{children:[g("button",{type:"button",className:"rle-btn rle-btn--ghost",onClick:Oe,children:"Clear all"}),g("button",{type:"button",className:"rle-btn rle-btn--primary rle-sheet__apply",disabled:b.loading,onClick:_e,children:b.loading?g("span",{className:"rle-spinner","aria-label":"Updating results"}):`Show ${He} results`})]}),children:g(ye,{className:"rle-filter-stack",groupClassName:"rle-filter-group",draft:F,onDraftChange:Re})})]})}import{useEffect as fi,useRef as yi,useState as vi}from"react";import{jsx as Me,jsxs as Li}from"react/jsx-runtime";function yt(t){return"provider"in t}function hi(t){let e=t!=null&&!yt(t),i=e?t.apiKey:void 0,n=e?t.mapId:void 0,r=e?t.mapOptions:void 0,s=e?t.styles:void 0,o=e?t.overlayMarkers:void 0,[a,p]=vi(()=>!t||yt(t)?{ready:!0,provider:t?.provider}:{ready:!1});return fi(()=>{if(!i)return;let d=!1;return import("./maps/google/index.js").then(({googleProvider:l})=>{d||p({ready:!0,provider:l({apiKey:i,mapId:n,mapOptions:r,styles:s,overlayMarkers:o})})}),()=>{d=!0}},[i,n]),a}function bi({onFiltersChange:t}){let e=yi(t);return e.current=t,st("FiltersChanged",i=>{i.type==="FiltersChanged"&&e.current(i.filters)}),null}function zr(t){let{datasets:e,filters:i,map:n,components:r,initialFilters:s,onFiltersChange:o,mobileAction:a,search:p,filterBarStart:d,toolbarEnd:l,mapControls:c,onMapReady:y,mobileSheetFooter:v,config:O,autoFetch:K,initialPage:D,className:u}=t,{ready:V,provider:b}=hi(n);if(!V)return null;let k=[];for(let x of e)k.push(Ve(x));i&&k.push(qe(i)),b&&k.push(Ke(b)),s&&k.push($e(s)),O&&k.push(Ue(O));let _=ze(...k),H={...ut,...r};return Li(at,{..._,children:[o&&Me(bi,{onFiltersChange:o}),Me(je,{...H,children:Me(ft,{className:u,search:p,filterBarStart:d,toolbarEnd:l,mobileAction:a,autoFetch:K,mapCenter:n?.center,mapZoom:n?.zoom,mapControls:c,onMapReady:y,initialPage:D,mobileSheetFooter:v})})]})}export{ee as a,$ as b,te as c,ie as d,Ae as e,ne as f,re as g,ze as h,Ue as i,Ke as j,Ve as k,qe as l,Bi as m,$e as n,Oi as o,fe as p,je as q,w as r,se as s,h as t,I as u,oe as v,ye as w,W as x,Xe as y,it as z,nt as A,rt as B,st as C,at as D,lt as E,be as F,Le as G,Pe as H,Te as I,Fe as J,Ce as K,Se as L,we as M,Ie as N,Ee as O,ut as P,mt as Q,ft as R,zr as S};