react-listing-engine 0.6.6 → 0.6.7
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/README.md +2 -2
- package/dist/chunk-4CZJODMK.cjs +2 -0
- package/dist/chunk-GSWGCJCO.js +2 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/{listing-app-4Vs_SMNl.d.cts → listing-app-BtNNEkX1.d.cts} +42 -30
- package/dist/{listing-app-CkEGdUV9.d.ts → listing-app-IG1awue3.d.ts} +42 -30
- package/dist/styled/index.cjs +1 -1
- package/dist/styled/index.d.cts +2 -2
- package/dist/styled/index.d.ts +2 -2
- package/dist/styled/index.js +1 -1
- package/dist/styles.css +31 -99
- package/package.json +10 -19
- package/dist/chunk-OXSYNZAJ.js +0 -2
- package/dist/chunk-PE27NATS.cjs +0 -2
package/README.md
CHANGED
|
@@ -73,8 +73,8 @@ The engine is layered so you can go as deep as you need and stop:
|
|
|
73
73
|
|
|
74
74
|
1. **Data** — implement `EntityAdapter<TEntity, TFilters>` against your own API. Nothing in the engine assumes a specific backend or entity shape.
|
|
75
75
|
2. **Structure** — compose the provider with `composeListingProviders(withMap(...), withDataset(...), withFilters(...), withUrlSync(...), withInitialFilters(...), withPrimaryDataset(...), withConfig(...))`. Mutate filters via `FilterRegistry` (`add`/`remove`/`reorder`/`replace`) and layers via `DatasetRegistry` (`add`/`get`/`has`/`list`/`visibleIds`).
|
|
76
|
-
3. **Presentation** — swap any slot via `ListingComponentsProvider` (or start from `
|
|
77
|
-
4. **Layout** — skip `
|
|
76
|
+
3. **Presentation** — swap any slot via `ListingComponentsProvider` (or start from `react-listing-engine/styled`'s `StyledComponentsProviderWithDefaults` for the styled look and override only what you need). Injectable slots: `Card`, `Marker`, `Popup`, `Sidebar`, `FilterPanel`, `Search`, `Empty`, `Loading`, `ResultHeader`, `Toolbar`. `Marker`/`Popup` are defined but not yet wired into the map's render output (see the Features note above) — every other slot renders as described.
|
|
77
|
+
4. **Layout** — skip `StyledListingLayout` entirely and arrange the structure-only compound components yourself: `ListingList`, `ListingMap`, `ListingFilters`, `ListingResultHeader`, `ListingToolbar`, `ListingPagination`.
|
|
78
78
|
|
|
79
79
|
## Google Maps setup
|
|
80
80
|
|
|
@@ -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 H= (_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,pagination:{mode:_nullishCoalesce(e.mode, () => ("paged")),loading:!1},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})}setLayerVisible(e,i){this.setState({layers:{...this.state.layers,[e]:i}})}setLoading(e){this.setState({pagination:{...this.state.pagination,loading: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 N= (_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(),r=e.filter(s=>this.defs.has(s));r.forEach((s,o)=>{this.defs.get(s).order=o});let n=new Set(r);return i.filter(s=>!n.has(s.key)).forEach((s,o)=>{s.order=r.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(r=>Object.hasOwn(e,r.key)).map(r=>r.toParams(e[r.key])).reduce((r,n)=>({...r,...n}),{})}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 z= (_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 U= (_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 n of[...i])n(e);let r=this.map.get("*");if(r)for(let n of[...r])n(e)}on(e,i){let r=this.map.get(e);return r||(r=new Set,this.map.set(e,r)),r.add(i),()=>{r.delete(i)}}}, _class4);var ge={pagination:"paged",pageSize:20,debounceMs:250};var V=class{constructor(e){this.options=Object.freeze({...ge,...e})}};var K= (_class5 =class{__init5() {this.emitter=new U}__init6() {this.debounceTimer=null}__init7() {this.debounceResolve=null}__init8() {this.queryToken=0}__init9() {this.pointsToken=0}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);this.datasets=e.datasets,this.filters=_nullishCoalesce(e.filters, () => (new N)),this.map=e.map,this.config=new V(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 H({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,r=this.config.options.debounceMs;return r<=0?this.runQuery(i):new Promise(n=>{this.debounceResolve=n,this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.debounceResolve=null,n(this.runQuery(i))},r)})}async loadPage(){let e=this.state.results.nextCursor;if(e===null)return;let i=++this.queryToken,r=this.primaryDataset();this.store.setLoading(!0);try{let n=await r.adapter.list(this.currentFilters(),{cursor:e,limit:this.config.options.pageSize});if(i!==this.queryToken)return;this.config.options.pagination==="infinite"?this.store.appendResults(n):this.store.setResults(n),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:n.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(),r=++this.pointsToken;await Promise.allSettled(this.datasets.visibleIds().map(async n=>{let s=this.datasets.get(n);if(!s)return;let o=await s.adapter.getPoints(i,e);r===this.pointsToken&&this.store.setPoints(n,o)}))}selectPoint(e,i){this.store.setSelection(i);let r=_optionalChain([this, 'access', _11 => _11.state, 'access', _12 => _12.points, 'access', _13 => _13[e], 'optionalAccess', _14 => _14.find, 'call', _15 => _15(n=>n.id===i)]);r&&this.emitter.emit({type:"PointClicked",datasetId:e,id:i,entity:r.entity})}toggleLayer(e){let r=!(_nullishCoalesce(this.state.layers[e], () => (!0)));this.store.setLayerVisible(e,r),this.emitter.emit({type:"LayerToggled",datasetId:e,visible:r})}subscribe(e){return this.store.subscribe(e)}on(e,i){return this.emitter.on(e,i)}dispose(){this.clearDebounce(),this.emitter.dispose()}async runQuery(e){if(e!==this.queryToken)return;let i=this.primaryDataset();this.store.setLoading(!0);try{let r=await i.adapter.list(this.currentFilters(),{cursor:null,limit:this.config.options.pageSize});if(e!==this.queryToken)return;this.store.setResults(r),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:r.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 fe(...t){let e={config:{},filters:new N,datasets:new z};for(let i of t)i(e);return e}var ye=t=>e=>{e.config={...e.config,...t}},he= exports.j =t=>e=>{e.map=t},ve= exports.k =t=>e=>{e.datasets.add(t)},Le= exports.l =t=>e=>{t(e.filters)},pi= exports.m =t=>e=>{e.urlSync=t},be= exports.n =t=>e=>{e.initialFilters=t},ci= exports.o =t=>e=>{e.primaryDatasetId=t};var _react = require('react');var _jsxruntime = require('react/jsx-runtime');function Ze(t){return String(_nullishCoalesce(_optionalChain([t, 'optionalAccess', _16 => _16.title]), () => ("")))}var Xe=({item:t})=>_jsxruntime.jsx.call(void 0, "div",{children:Ze(t)}),Je=()=>_jsxruntime.jsx.call(void 0, "div",{}),Ye=()=>_jsxruntime.jsx.call(void 0, "div",{}),et=({children:t})=>_jsxruntime.jsx.call(void 0, "div",{children:t}),tt=({children:t})=>_jsxruntime.jsx.call(void 0, "div",{children:t}),it=({value:t,onChange:e,placeholder:i})=>_jsxruntime.jsx.call(void 0, "input",{type:"search",value:t,placeholder:i,onChange:r=>e(r.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"}),st=({count:t})=>_jsxruntime.jsxs.call(void 0, "div",{children:[t," results"]}),ot=({children:t})=>_jsxruntime.jsx.call(void 0, "div",{children:t}),P={Card:Xe,Marker:Je,Popup:Ye,Sidebar:et,FilterPanel:tt,Search:it,Empty:rt,Loading:nt,ResultHeader:st,Toolbar:ot},Te=_react.createContext.call(void 0, P);function Pe(t){let{Card:e,Marker:i,Popup:r,Sidebar:n,FilterPanel:s,Search:o,Empty:a,Loading:l,ResultHeader:c,Toolbar:d,children:v}=t,L={Card:_nullishCoalesce(e, () => (P.Card)),Marker:_nullishCoalesce(i, () => (P.Marker)),Popup:_nullishCoalesce(r, () => (P.Popup)),Sidebar:_nullishCoalesce(n, () => (P.Sidebar)),FilterPanel:_nullishCoalesce(s, () => (P.FilterPanel)),Search:_nullishCoalesce(o, () => (P.Search)),Empty:_nullishCoalesce(a, () => (P.Empty)),Loading:_nullishCoalesce(l, () => (P.Loading)),ResultHeader:_nullishCoalesce(c, () => (P.ResultHeader)),Toolbar:_nullishCoalesce(d, () => (P.Toolbar))};return _jsxruntime.jsx.call(void 0, Te.Provider,{value:L,children:v})}function F(){return _react.useContext.call(void 0, Te)}var $=_react.createContext.call(void 0, null);function y(){let t=_react.useContext.call(void 0, $);if(t===null)throw new Error("useListing must be used within a <ListingProvider>");return t}function S(){let t=y(),e=_react.useCallback.call(void 0, r=>t.subscribe(r),[t]),i=_react.useCallback.call(void 0, ()=>t.state,[t]);return _react.useSyncExternalStore.call(void 0, e,i,i)}function W(){let t=y(),e=S(),i=_react.useCallback.call(void 0, n=>t.applyFilters(n),[t]),r=_react.useCallback.call(void 0, (n,s)=>t.applyFilters({[n]:s}),[t]);return{filters:e.filters,set:i,setField:r}}function Y({className:t,groupClassName:e,hideLabels:i}={}){let r=y(),{FilterPanel:n}=F(),{filters:s}=W();return _jsxruntime.jsx.call(void 0, n,{children:_jsxruntime.jsx.call(void 0, "div",{className:_nullishCoalesce(t, () => ("space-y-5")),children:r.filters.list().map(o=>{if(typeof o.render=="string")return _jsxruntime.jsx.call(void 0, "div",{"data-filter":o.key,className:e},o.key);let a=o.render;return _jsxruntime.jsxs.call(void 0, "div",{className:e,children:[o.label&&!i&&_jsxruntime.jsx.call(void 0, "div",{className:"mb-1.5 text-[13px] font-medium text-foreground",children:o.label}),_jsxruntime.jsx.call(void 0, a,{value:o.fromParams(s),onChange:l=>{r.applyFilters(o.toParams(l))}})]},o.key)})})})}function R(){return S().results}function ut(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 Se({className:t}={}){let e=y(),{items:i}=R(),{pagination:r,selection:n}=S(),{Card:s,Empty:o,Loading:a}=F();return r.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,c)=>{let d=ut(l,c);return _jsxruntime.jsx.call(void 0, s,{item:l,selected:n===d,onSelect:()=>e.selectPoint(e.primaryDatasetId,d)},d)})})}var gt={west:-179.9,south:-85,east:179.9,north:85},Ie=.1,we=.02;function ft(t){if(t.length===0)return null;let e=t[0].lng,i=t[0].lng,r=t[0].lat,n=t[0].lat;for(let{lat:a,lng:l}of t)l<e&&(e=l),l>i&&(i=l),a<r&&(r=a),a>n&&(n=a);let s=n>r?(n-r)*Ie:we,o=i>e?(i-e)*Ie:we;return{west:e-o,east:i+o,south:r-s,north:n+s}}function ke(t){let{center:e,zoom:i,fallback:r}=t,n=y(),s=S(),o=_react.useRef.call(void 0, null),a=_react.useRef.call(void 0, null),[l,c]=_react.useState.call(void 0, !1),d=_react.useRef.call(void 0, !1),v=_react.useRef.call(void 0, !1),L=_react.useRef.call(void 0, !1),p=n.map;return _react.useEffect.call(void 0, ()=>{let b=a.current;if(!p||!b)return;let u=[];for(let m of Object.keys(s.points)){if(s.layers[m]===!1)continue;let f=n.datasets.get(m),I=_nullishCoalesce(s.points[m], () => ([])),J={id:m,markers:I.map(E=>({id:E.id,position:E.position,iconUrl:_optionalChain([f, 'optionalAccess', _17 => _17.marker, 'access', _18 => _18.iconUrl, 'optionalCall', _19 => _19(E.entity)]),element:_optionalChain([f, 'optionalAccess', _20 => _20.marker, 'access', _21 => _21.element, 'optionalCall', _22 => _22(E.entity)])})),clustering:_optionalChain([f, 'optionalAccess', _23 => _23.clustering]),onMarkerClick:E=>n.selectPoint(m,E)};u.push(p.renderLayer(b,J))}return()=>{u.forEach(m=>m())}},[n,p,l,s.points,s.layers]),_react.useEffect.call(void 0, ()=>{if(!o.current||!p)return;let b=o.current,u=!1,m=null;return(async()=>{let f=await p.mount(b,{center:e,zoom:i});if(u){p.destroy(f);return}a.current=f,m=p.onBoundsChange(f,I=>{L.current?L.current=!1:v.current=!0,n.loadPoints(I)}),c(!0),n.loadPoints(gt)})(),()=>{u=!0,_optionalChain([m, 'optionalCall', _24 => _24()]),a.current&&(p.destroy(a.current),a.current=null),c(!1)}},[n,p]),_react.useEffect.call(void 0, ()=>{let b=a.current;if(!p||!b||e||d.current||v.current)return;let u=[];for(let f of Object.keys(s.points))if(s.layers[f]!==!1)for(let I of _nullishCoalesce(s.points[f], () => ([])))u.push(I.position);let m=ft(u);m&&(d.current=!0,L.current=!0,p.fitBounds(b,m))},[p,e,l,s.points,s.layers]),_jsxruntime.jsx.call(void 0, "div",{ref:o,className:!p&&r?"flex h-full min-h-0 w-full items-center justify-center":"h-full min-h-0 w-full",children:!p&&r})}function Ee(){let t=y(),{results:e,pagination:i}=S();return e.nextCursor==null?null:_jsxruntime.jsx.call(void 0, "button",{type:"button",disabled:i.loading,onClick:()=>{t.loadPage()},children:"Load more"})}function xe(){let{items:t,total:e}=R(),{ResultHeader:i}=F();return _jsxruntime.jsx.call(void 0, i,{count:t.length,total:e})}function Ne(t,e){let i=y(),r=_react.useRef.call(void 0, e);r.current=e,_react.useEffect.call(void 0, ()=>i.on(t,n=>r.current(n)),[i,t])}function Me(t){let{children:e,...i}=t,[r]=_react.useState.call(void 0, ()=>i),[n,s]=_react.useState.call(void 0, null);return _react.useEffect.call(void 0, ()=>{let o=new K({datasets:r.datasets,filters:r.filters,config:r.config,map:r.map,initialFilters:r.initialFilters,primaryDatasetId:r.primaryDatasetId});return r.urlSync&&r.urlSync.start(o),s(o),()=>{r.urlSync&&r.urlSync.stop(),o.dispose(),s(a=>a===o?null:a)}},[r]),n?_jsxruntime.jsx.call(void 0, $.Provider,{value:n,children:e}):null}function M(t){return typeof t!="number"?t:new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(t)}function Ft(t){return t?"rle-card rle-card--selected":"rle-card"}function te({item:t,selected:e,onSelect:i}){let r=_nullishCoalesce(t, () => ({})),n=Ft(e),s=_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[r.imageUrl?_jsxruntime.jsx.call(void 0, "img",{src:r.imageUrl,alt:_nullishCoalesce(r.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:[r.title&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-title",children:r.title}),r.subtitle&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-address",children:r.subtitle}),r.badge&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-info",children:_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-info-item",children:r.badge})}),r.price!=null&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-price",children:M(r.price)})]})]});return i?_jsxruntime.jsx.call(void 0, "button",{type:"button",onClick:i,"aria-pressed":_nullishCoalesce(e, () => (!1)),className:n,children:s}):_jsxruntime.jsx.call(void 0, "article",{className:n,children:s})}function ie(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 re({children:t}){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-panel",children:t})}function ne(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 se({point:t}){let e=_nullishCoalesce(t.entity, () => ({}));return _jsxruntime.jsx.call(void 0, "span",{className:"rle-pin",children:e.price!=null?M(e.price):""})}function ae({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:M(i.price)})]})]})}function le({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 de({value:t,onChange:e,placeholder:i}){return _jsxruntime.jsx.call(void 0, "input",{type:"search",value:t,placeholder:i,onChange:r=>e(r.target.value),"aria-label":_nullishCoalesce(i, () => ("Search")),className:"rle-input"})}function pe({children:t}){return _jsxruntime.jsx.call(void 0, "aside",{className:"rle-sidebar",children:t})}function ce({children:t}){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-toolbar",children:t})}var Oe={Card:te,Marker:se,Popup:ae,Sidebar:pe,FilterPanel:re,Search:de,Empty:ie,Loading:ne,ResultHeader:le,Toolbar:ce};function Be({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, Rt,{}),"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, Mt,{}),"Map"]})]})})}function Rt(){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 Mt(){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"})]})}var _reactdom = require('react-dom');function He({open:t,onOpenChange:e,title:i,children:r,footer:n}){let s=_react.useRef.call(void 0, null),[o,a]=_react.useState.call(void 0, !1),[l,c]=_react.useState.call(void 0, !1);return _react.useEffect.call(void 0, ()=>{if(!t){c(!1),a(!1);return}a(!0);let d=requestAnimationFrame(()=>c(!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', _25 => _25.current, 'optionalAccess', _26 => _26.focus, 'call', _27 => _27()]);function d(v){v.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, Ot,{})})]}),_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__body",children:r}),n&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__footer",children:n})]})]}),document.body)}function Ot(){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 ze({search:t,onFiltersClick:e,filterCount:i=0,action:r}){let{Search:n}=F();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, n,{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, At,{}),_jsxruntime.jsx.call(void 0, "span",{children:"Filters"}),i>0&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-mobile-header__count",children:i})]}),r&&_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-btn rle-mobile-header__btn rle-mobile-header__btn--icon",onClick:r.onClick,"aria-label":r.label,children:_nullishCoalesce(r.icon, () => (_jsxruntime.jsx.call(void 0, Ht,{})))})]})}function At(){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 Ht(){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 Ut=_jsxruntime.jsx.call(void 0, "div",{className:"rle-empty",children:"Map unavailable"});function Vt(){let t=_react.useRef.call(void 0, null),[e,i]=_react.useState.call(void 0, !0),[r,n]=_react.useState.call(void 0, !0);return _react.useEffect.call(void 0, ()=>{let s=t.current;if(!s)return;let o=()=>{let{clientWidth:v,scrollLeft:L,scrollWidth:p}=s;i(L<=0),n(L+v>=p-1)},a=0,l=()=>{a||(a=requestAnimationFrame(()=>{a=0,o()}))};o(),s.addEventListener("scroll",o,{passive:!0});let c,d;return typeof ResizeObserver<"u"&&(c=new ResizeObserver(o),c.observe(s)),typeof MutationObserver<"u"&&(d=new MutationObserver(l),d.observe(s,{characterData:!0,childList:!0,subtree:!0})),()=>{s.removeEventListener("scroll",o),_optionalChain([c, 'optionalAccess', _28 => _28.disconnect, 'call', _29 => _29()]),_optionalChain([d, 'optionalAccess', _30 => _30.disconnect, 'call', _31 => _31()]),a&&cancelAnimationFrame(a)}},[]),{atEnd:r,atStart:e,ref:t}}function Ve({search:t,toolbarEnd:e,mobileAction:i,autoFetch:r=!0,hasMap:n,mapCenter:s,mapZoom:o,className:a}){let l=y(),{Search:c}=F(),d=R(),{filters:v,set:L}=W(),p=_nullishCoalesce(n, () => (l.map!=null)),[b,u]=_react.useState.call(void 0, "list"),[m,f]=_react.useState.call(void 0, !1),{atEnd:I,atStart:J,ref:E}=Vt(),_=t?{value:String(_nullishCoalesce(v[t.filterKey], () => (""))),onChange:je=>{L({[t.filterKey]:je||void 0})},placeholder:t.placeholder}:void 0;_react.useEffect.call(void 0, ()=>{r!==!1&&l.applyFilters({})},[l,r]);let $e=()=>{L(l.filters.clearedParams())},We=l.filters.activeKeys(v).length,qe=_nullishCoalesce(d.total, () => (d.items.length));return _jsxruntime.jsxs.call(void 0, "div",{className:a?`rle-app ${a}`:"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:E,children:[_&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__search",children:_jsxruntime.jsx.call(void 0, c,{value:_.value,onChange:_.onChange,placeholder:_.placeholder})}),_jsxruntime.jsx.call(void 0, Y,{className:"rle-filters-row",groupClassName:"rle-filter-group",hideLabels:!0})]}),!J&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__fade rle-filter-bar__fade--start","aria-hidden":"true"}),!I&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__fade rle-filter-bar__fade--end","aria-hidden":"true"})]}),_jsxruntime.jsx.call(void 0, ze,{search:_,onFiltersClick:()=>f(!0),filterCount:We,action:i}),_jsxruntime.jsxs.call(void 0, "div",{className:`rle-body ${p?"rle-split":"rle-body--list-only"}`,"data-mobile-view":b,children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-list",children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-list-header",children:[_jsxruntime.jsx.call(void 0, xe,{}),e&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-list-header__toolbar",children:e})]}),_jsxruntime.jsx.call(void 0, Se,{className:"rle-list-grid"}),_jsxruntime.jsx.call(void 0, Ee,{})]}),p&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-map",children:_jsxruntime.jsx.call(void 0, ke,{center:s,zoom:o,fallback:Ut})})]}),p&&_jsxruntime.jsx.call(void 0, Be,{view:b,onViewChange:u}),_jsxruntime.jsx.call(void 0, He,{title:"Filters",open:m,onOpenChange:f,footer:_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-btn rle-btn--ghost",onClick:$e,children:"Clear all"}),_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:"rle-btn rle-btn--primary",onClick:()=>f(!1),children:["Show ",qe," results"]})]}),children:_jsxruntime.jsx.call(void 0, Y,{className:"rle-filter-stack",groupClassName:"rle-filter-group"})})]})}function Ke(t){return"provider"in t}function jt(t){let e=t!=null&&!Ke(t),i=e?t.apiKey:void 0,r=e?t.mapId:void 0,[n,s]=_react.useState.call(void 0, ()=>!t||Ke(t)?{ready:!0,provider:_optionalChain([t, 'optionalAccess', _32 => _32.provider])}:{ready:!1});return _react.useEffect.call(void 0, ()=>{if(!i)return;let o=!1;return Promise.resolve().then(() => _interopRequireWildcard(require("./maps/google/index.cjs"))).then(({googleProvider:a})=>{o||s({ready:!0,provider:a({apiKey:i,mapId:r})})}),()=>{o=!0}},[i,r]),n}function Qt({onFiltersChange:t}){let e=_react.useRef.call(void 0, t);return e.current=t,Ne("FiltersChanged",i=>{i.type==="FiltersChanged"&&e.current(i.filters)}),null}function mn(t){let{datasets:e,filters:i,map:r,components:n,initialFilters:s,onFiltersChange:o,mobileAction:a,search:l,toolbarEnd:c,config:d,autoFetch:v,className:L}=t,{ready:p,provider:b}=jt(r);if(!p)return null;let u=[];for(let I of e)u.push(ve(I));i&&u.push(Le(i)),b&&u.push(he(b)),s&&u.push(be(s)),d&&u.push(ye(d));let m=fe(...u),f={...Oe,...n};return _jsxruntime.jsxs.call(void 0, Me,{...m,children:[o&&_jsxruntime.jsx.call(void 0, Qt,{onFiltersChange:o}),_jsxruntime.jsx.call(void 0, Pe,{...f,children:_jsxruntime.jsx.call(void 0, Ve,{className:L,search:l,toolbarEnd:c,mobileAction:a,autoFetch:v,mapCenter:_optionalChain([r, 'optionalAccess', _33 => _33.center]),mapZoom:_optionalChain([r, 'optionalAccess', _34 => _34.zoom])})})]})}exports.a = H; exports.b = N; exports.c = z; exports.d = U; exports.e = ge; exports.f = V; exports.g = K; exports.h = fe; exports.i = ye; exports.j = he; exports.k = ve; exports.l = Le; exports.m = pi; exports.n = be; exports.o = ci; exports.p = Pe; exports.q = F; exports.r = $; exports.s = y; exports.t = S; exports.u = W; exports.v = Y; exports.w = R; exports.x = Se; exports.y = ke; exports.z = Ee; exports.A = xe; exports.B = Ne; exports.C = Me; exports.D = te; exports.E = ie; exports.F = re; exports.G = ne; exports.H = se; exports.I = ae; exports.J = le; exports.K = de; exports.L = pe; exports.M = ce; exports.N = Oe; exports.O = Be; exports.P = He; exports.Q = Ve; exports.R = mn;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var H=class{state;listeners=new Set;constructor(e){this.state=this.freezeState({filters:{...e.filters},results:{items:[],nextCursor:null},bounds:null,selection:null,pagination:{mode:e.mode??"paged",loading:!1},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})}setLayerVisible(e,i){this.setState({layers:{...this.state.layers,[e]:i}})}setLoading(e){this.setState({pagination:{...this.state.pagination,loading: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 N=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(),r=e.filter(s=>this.defs.has(s));r.forEach((s,o)=>{this.defs.get(s).order=o});let n=new Set(r);return i.filter(s=>!n.has(s.key)).forEach((s,o)=>{s.order=r.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(r=>Object.hasOwn(e,r.key)).map(r=>r.toParams(e[r.key])).reduce((r,n)=>({...r,...n}),{})}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 z=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 U=class{map=new Map;dispose(){this.map.clear()}emit(e){let i=this.map.get(e.type);if(i)for(let n of[...i])n(e);let r=this.map.get("*");if(r)for(let n of[...r])n(e)}on(e,i){let r=this.map.get(e);return r||(r=new Set,this.map.set(e,r)),r.add(i),()=>{r.delete(i)}}};var ge={pagination:"paged",pageSize:20,debounceMs:250};var V=class{options;constructor(e){this.options=Object.freeze({...ge,...e})}};var K=class{filters;map;datasets;primaryDatasetId;store;emitter=new U;config;debounceTimer=null;debounceResolve=null;queryToken=0;pointsToken=0;constructor(e){this.datasets=e.datasets,this.filters=e.filters??new N,this.map=e.map,this.config=new V(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 H({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,r=this.config.options.debounceMs;return r<=0?this.runQuery(i):new Promise(n=>{this.debounceResolve=n,this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.debounceResolve=null,n(this.runQuery(i))},r)})}async loadPage(){let e=this.state.results.nextCursor;if(e===null)return;let i=++this.queryToken,r=this.primaryDataset();this.store.setLoading(!0);try{let n=await r.adapter.list(this.currentFilters(),{cursor:e,limit:this.config.options.pageSize});if(i!==this.queryToken)return;this.config.options.pagination==="infinite"?this.store.appendResults(n):this.store.setResults(n),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:n.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(),r=++this.pointsToken;await Promise.allSettled(this.datasets.visibleIds().map(async n=>{let s=this.datasets.get(n);if(!s)return;let o=await s.adapter.getPoints(i,e);r===this.pointsToken&&this.store.setPoints(n,o)}))}selectPoint(e,i){this.store.setSelection(i);let r=this.state.points[e]?.find(n=>n.id===i);r&&this.emitter.emit({type:"PointClicked",datasetId:e,id:i,entity:r.entity})}toggleLayer(e){let r=!(this.state.layers[e]??!0);this.store.setLayerVisible(e,r),this.emitter.emit({type:"LayerToggled",datasetId:e,visible:r})}subscribe(e){return this.store.subscribe(e)}on(e,i){return this.emitter.on(e,i)}dispose(){this.clearDebounce(),this.emitter.dispose()}async runQuery(e){if(e!==this.queryToken)return;let i=this.primaryDataset();this.store.setLoading(!0);try{let r=await i.adapter.list(this.currentFilters(),{cursor:null,limit:this.config.options.pageSize});if(e!==this.queryToken)return;this.store.setResults(r),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:r.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 fe(...t){let e={config:{},filters:new N,datasets:new z};for(let i of t)i(e);return e}var ye=t=>e=>{e.config={...e.config,...t}},he=t=>e=>{e.map=t},ve=t=>e=>{e.datasets.add(t)},Le=t=>e=>{t(e.filters)},pi=t=>e=>{e.urlSync=t},be=t=>e=>{e.initialFilters=t},ci=t=>e=>{e.primaryDatasetId=t};import{createContext as Qe,useContext as Ge}from"react";import{jsx as C,jsxs as at}from"react/jsx-runtime";function Ze(t){return String(t?.title??"")}var Xe=({item:t})=>C("div",{children:Ze(t)}),Je=()=>C("div",{}),Ye=()=>C("div",{}),et=({children:t})=>C("div",{children:t}),tt=({children:t})=>C("div",{children:t}),it=({value:t,onChange:e,placeholder:i})=>C("input",{type:"search",value:t,placeholder:i,onChange:r=>e(r.target.value),"aria-label":i??"Search"}),rt=()=>C("div",{role:"status",children:"No results"}),nt=()=>C("div",{role:"status","aria-busy":"true",children:"Loading\u2026"}),st=({count:t})=>at("div",{children:[t," results"]}),ot=({children:t})=>C("div",{children:t}),P={Card:Xe,Marker:Je,Popup:Ye,Sidebar:et,FilterPanel:tt,Search:it,Empty:rt,Loading:nt,ResultHeader:st,Toolbar:ot},Te=Qe(P);function Pe(t){let{Card:e,Marker:i,Popup:r,Sidebar:n,FilterPanel:s,Search:o,Empty:a,Loading:l,ResultHeader:c,Toolbar:d,children:v}=t,L={Card:e??P.Card,Marker:i??P.Marker,Popup:r??P.Popup,Sidebar:n??P.Sidebar,FilterPanel:s??P.FilterPanel,Search:o??P.Search,Empty:a??P.Empty,Loading:l??P.Loading,ResultHeader:c??P.ResultHeader,Toolbar:d??P.Toolbar};return C(Te.Provider,{value:L,children:v})}function F(){return Ge(Te)}import{createContext as lt}from"react";var $=lt(null);import{useContext as dt}from"react";function y(){let t=dt($);if(t===null)throw new Error("useListing must be used within a <ListingProvider>");return t}import{useCallback as Fe,useSyncExternalStore as pt}from"react";function S(){let t=y(),e=Fe(r=>t.subscribe(r),[t]),i=Fe(()=>t.state,[t]);return pt(e,i,i)}import{useCallback as Ce}from"react";function W(){let t=y(),e=S(),i=Ce(n=>t.applyFilters(n),[t]),r=Ce((n,s)=>t.applyFilters({[n]:s}),[t]);return{filters:e.filters,set:i,setField:r}}import{jsx as O,jsxs as ct}from"react/jsx-runtime";function Y({className:t,groupClassName:e,hideLabels:i}={}){let r=y(),{FilterPanel:n}=F(),{filters:s}=W();return O(n,{children:O("div",{className:t??"space-y-5",children:r.filters.list().map(o=>{if(typeof o.render=="string")return O("div",{"data-filter":o.key,className:e},o.key);let a=o.render;return ct("div",{className:e,children:[o.label&&!i&&O("div",{className:"mb-1.5 text-[13px] font-medium text-foreground",children:o.label}),O(a,{value:o.fromParams(s),onChange:l=>{r.applyFilters(o.toParams(l))}})]},o.key)})})})}function R(){return S().results}import{jsx as q}from"react/jsx-runtime";function ut(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 Se({className:t}={}){let e=y(),{items:i}=R(),{pagination:r,selection:n}=S(),{Card:s,Empty:o,Loading:a}=F();return r.loading&&i.length===0?q(a,{}):i.length===0?q(o,{}):q("div",{role:"list",className:t,children:i.map((l,c)=>{let d=ut(l,c);return q(s,{item:l,selected:n===d,onSelect:()=>e.selectPoint(e.primaryDatasetId,d)},d)})})}import{useEffect as ee,useRef as B,useState as mt}from"react";import{jsx as yt}from"react/jsx-runtime";var gt={west:-179.9,south:-85,east:179.9,north:85},Ie=.1,we=.02;function ft(t){if(t.length===0)return null;let e=t[0].lng,i=t[0].lng,r=t[0].lat,n=t[0].lat;for(let{lat:a,lng:l}of t)l<e&&(e=l),l>i&&(i=l),a<r&&(r=a),a>n&&(n=a);let s=n>r?(n-r)*Ie:we,o=i>e?(i-e)*Ie:we;return{west:e-o,east:i+o,south:r-s,north:n+s}}function ke(t){let{center:e,zoom:i,fallback:r}=t,n=y(),s=S(),o=B(null),a=B(null),[l,c]=mt(!1),d=B(!1),v=B(!1),L=B(!1),p=n.map;return ee(()=>{let b=a.current;if(!p||!b)return;let u=[];for(let m of Object.keys(s.points)){if(s.layers[m]===!1)continue;let f=n.datasets.get(m),I=s.points[m]??[],J={id:m,markers:I.map(E=>({id:E.id,position:E.position,iconUrl:f?.marker.iconUrl?.(E.entity),element:f?.marker.element?.(E.entity)})),clustering:f?.clustering,onMarkerClick:E=>n.selectPoint(m,E)};u.push(p.renderLayer(b,J))}return()=>{u.forEach(m=>m())}},[n,p,l,s.points,s.layers]),ee(()=>{if(!o.current||!p)return;let b=o.current,u=!1,m=null;return(async()=>{let f=await p.mount(b,{center:e,zoom:i});if(u){p.destroy(f);return}a.current=f,m=p.onBoundsChange(f,I=>{L.current?L.current=!1:v.current=!0,n.loadPoints(I)}),c(!0),n.loadPoints(gt)})(),()=>{u=!0,m?.(),a.current&&(p.destroy(a.current),a.current=null),c(!1)}},[n,p]),ee(()=>{let b=a.current;if(!p||!b||e||d.current||v.current)return;let u=[];for(let f of Object.keys(s.points))if(s.layers[f]!==!1)for(let I of s.points[f]??[])u.push(I.position);let m=ft(u);m&&(d.current=!0,L.current=!0,p.fitBounds(b,m))},[p,e,l,s.points,s.layers]),yt("div",{ref:o,className:!p&&r?"flex h-full min-h-0 w-full items-center justify-center":"h-full min-h-0 w-full",children:!p&&r})}import{jsx as ht}from"react/jsx-runtime";function Ee(){let t=y(),{results:e,pagination:i}=S();return e.nextCursor==null?null:ht("button",{type:"button",disabled:i.loading,onClick:()=>{t.loadPage()},children:"Load more"})}import{jsx as vt}from"react/jsx-runtime";function xe(){let{items:t,total:e}=R(),{ResultHeader:i}=F();return vt(i,{count:t.length,total:e})}import{useEffect as Lt,useRef as bt}from"react";function Ne(t,e){let i=y(),r=bt(e);r.current=e,Lt(()=>i.on(t,n=>r.current(n)),[i,t])}import{useEffect as Tt,useState as Re}from"react";import{jsx as Pt}from"react/jsx-runtime";function Me(t){let{children:e,...i}=t,[r]=Re(()=>i),[n,s]=Re(null);return Tt(()=>{let o=new K({datasets:r.datasets,filters:r.filters,config:r.config,map:r.map,initialFilters:r.initialFilters,primaryDatasetId:r.primaryDatasetId});return r.urlSync&&r.urlSync.start(o),s(o),()=>{r.urlSync&&r.urlSync.stop(),o.dispose(),s(a=>a===o?null:a)}},[r]),n?Pt($.Provider,{value:n,children:e}):null}function M(t){return typeof t!="number"?t:new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(t)}import{Fragment as Ct,jsx as w,jsxs as De}from"react/jsx-runtime";function Ft(t){return t?"rle-card rle-card--selected":"rle-card"}function te({item:t,selected:e,onSelect:i}){let r=t??{},n=Ft(e),s=De(Ct,{children:[r.imageUrl?w("img",{src:r.imageUrl,alt:r.title??"",className:"rle-card-media"}):w("div",{className:"rle-card-media rle-card-media--placeholder","aria-hidden":"true"}),De("div",{className:"rle-card-body",children:[r.title&&w("span",{className:"rle-card-title",children:r.title}),r.subtitle&&w("span",{className:"rle-card-address",children:r.subtitle}),r.badge&&w("div",{className:"rle-card-info",children:w("span",{className:"rle-card-info-item",children:r.badge})}),r.price!=null&&w("span",{className:"rle-card-price",children:M(r.price)})]})]});return i?w("button",{type:"button",onClick:i,"aria-pressed":e??!1,className:n,children:s}):w("article",{className:n,children:s})}import{jsx as j,jsxs as _e}from"react/jsx-runtime";function ie(t){return _e("div",{role:"status",className:"rle-empty",children:[_e("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:[j("circle",{cx:"11",cy:"11",r:"7"}),j("path",{d:"m21 21-4.3-4.3"})]}),j("p",{className:"rle-empty-title",children:"No results"}),j("p",{className:"rle-empty-hint",children:"Try adjusting your filters or search terms."})]})}import{jsx as St}from"react/jsx-runtime";function re({children:t}){return St("div",{className:"rle-filter-panel",children:t})}import{jsx as Q,jsxs as It}from"react/jsx-runtime";function ne(t){return Q("div",{className:"rle-loading",role:"status","aria-busy":"true","aria-label":"Loading results",children:Array.from({length:3}).map((e,i)=>It("div",{className:"rle-loading-item",children:[Q("div",{className:"rle-skeleton",style:{aspectRatio:"4 / 3",width:"100%"}}),Q("div",{className:"rle-skeleton",style:{height:16,width:"65%"}}),Q("div",{className:"rle-skeleton",style:{height:12,width:"35%"}})]},i))})}import{jsx as wt}from"react/jsx-runtime";function se({point:t}){let e=t.entity??{};return wt("span",{className:"rle-pin",children:e.price!=null?M(e.price):""})}import{jsx as D,jsxs as oe}from"react/jsx-runtime";function ae({entity:t,onClose:e}){let i=t??{};return oe("div",{className:"rle-popup",role:"group","aria-label":"Location details",children:[D("button",{type:"button",onClick:e,"aria-label":"Close",className:"rle-popup-close",children:oe("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:[D("path",{d:"M18 6 6 18"}),D("path",{d:"m6 6 12 12"})]})}),oe("div",{children:[i.title&&D("div",{className:"rle-card-title",children:i.title}),i.subtitle&&D("div",{className:"rle-card-address",children:i.subtitle}),i.price!=null&&D("div",{className:"rle-card-price",children:M(i.price)})]})]})}import{jsx as kt}from"react/jsx-runtime";function le({count:t,total:e}){let i=e!=null&&e!==t?`${t} of ${e} results`:`${t} results`;return kt("div",{className:"rle-result-header",children:i})}import{jsx as Et}from"react/jsx-runtime";function de({value:t,onChange:e,placeholder:i}){return Et("input",{type:"search",value:t,placeholder:i,onChange:r=>e(r.target.value),"aria-label":i??"Search",className:"rle-input"})}import{jsx as xt}from"react/jsx-runtime";function pe({children:t}){return xt("aside",{className:"rle-sidebar",children:t})}import{jsx as Nt}from"react/jsx-runtime";function ce({children:t}){return Nt("div",{className:"rle-toolbar",children:t})}var Oe={Card:te,Marker:se,Popup:ae,Sidebar:pe,FilterPanel:re,Search:de,Empty:ie,Loading:ne,ResultHeader:le,Toolbar:ce};import{jsx as T,jsxs as A}from"react/jsx-runtime";function Be({view:t,onViewChange:e}){return T("nav",{className:"rle-bottom-nav","aria-label":"Listing navigation",children:A("div",{className:"rle-viewtoggle",role:"group","aria-label":"View",children:[A("button",{type:"button",className:`rle-viewtoggle__btn${t==="list"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":t==="list",onClick:()=>e("list"),children:[T(Rt,{}),"List"]}),A("button",{type:"button",className:`rle-viewtoggle__btn${t==="map"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":t==="map",onClick:()=>e("map"),children:[T(Mt,{}),"Map"]})]})})}function Rt(){return A("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:[T("line",{x1:"8",y1:"6",x2:"20",y2:"6"}),T("line",{x1:"8",y1:"12",x2:"20",y2:"12"}),T("line",{x1:"8",y1:"18",x2:"20",y2:"18"}),T("line",{x1:"4",y1:"6",x2:"4.01",y2:"6"}),T("line",{x1:"4",y1:"12",x2:"4.01",y2:"12"}),T("line",{x1:"4",y1:"18",x2:"4.01",y2:"18"})]})}function Mt(){return A("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:[T("polygon",{points:"1 6 8 3 16 6 23 3 23 18 16 21 8 18 1 21 1 6"}),T("line",{x1:"8",y1:"3",x2:"8",y2:"18"}),T("line",{x1:"16",y1:"6",x2:"16",y2:"21"})]})}import{useEffect as ue,useRef as Dt,useState as Ae}from"react";import{createPortal as _t}from"react-dom";import{Fragment as Bt,jsx as k,jsxs as G}from"react/jsx-runtime";function He({open:t,onOpenChange:e,title:i,children:r,footer:n}){let s=Dt(null),[o,a]=Ae(!1),[l,c]=Ae(!1);return ue(()=>{if(!t){c(!1),a(!1);return}a(!0);let d=requestAnimationFrame(()=>c(!0));return()=>cancelAnimationFrame(d)},[t]),ue(()=>{if(!o)return;let d=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=d}},[o]),ue(()=>{if(!o)return;s.current?.focus();function d(v){v.key==="Escape"&&e(!1)}return document.addEventListener("keydown",d),()=>document.removeEventListener("keydown",d)},[o,e]),!o||typeof document>"u"?null:_t(G(Bt,{children:[k("div",{className:`rle-sheet-backdrop${l?" rle-sheet-backdrop--open":""}`,onClick:()=>e(!1),"aria-hidden":"true"}),G("div",{ref:s,className:`rle-sheet${l?" rle-sheet--open":""}`,role:"dialog","aria-modal":"true","aria-label":i,tabIndex:-1,children:[k("div",{className:"rle-sheet__handle","aria-hidden":"true"}),G("div",{className:"rle-sheet__header",children:[i&&k("div",{className:"rle-sheet__title",children:i}),k("button",{type:"button",className:"rle-sheet__close",onClick:()=>e(!1),"aria-label":"Close",children:k(Ot,{})})]}),k("div",{className:"rle-sheet__body",children:r}),n&&k("div",{className:"rle-sheet__footer",children:n})]})]}),document.body)}function Ot(){return G("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:[k("path",{d:"M18 6 6 18"}),k("path",{d:"m6 6 12 12"})]})}import{useEffect as Ue,useRef as zt,useState as X}from"react";import{jsx as h,jsxs as Z}from"react/jsx-runtime";function ze({search:t,onFiltersClick:e,filterCount:i=0,action:r}){let{Search:n}=F();return Z("header",{className:"rle-mobile-header",children:[t&&h("div",{className:"rle-mobile-header__search",children:h(n,{value:t.value,onChange:t.onChange,placeholder:t.placeholder})}),Z("button",{type:"button",className:"rle-btn rle-mobile-header__btn",onClick:e,children:[h(At,{}),h("span",{children:"Filters"}),i>0&&h("span",{className:"rle-mobile-header__count",children:i})]}),r&&h("button",{type:"button",className:"rle-btn rle-mobile-header__btn rle-mobile-header__btn--icon",onClick:r.onClick,"aria-label":r.label,children:r.icon??h(Ht,{})})]})}function At(){return Z("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:[h("line",{x1:"4",y1:"6",x2:"20",y2:"6"}),h("circle",{cx:"9",cy:"6",r:"2",fill:"currentColor",stroke:"none"}),h("line",{x1:"4",y1:"12",x2:"20",y2:"12"}),h("circle",{cx:"15",cy:"12",r:"2",fill:"currentColor",stroke:"none"}),h("line",{x1:"4",y1:"18",x2:"20",y2:"18"}),h("circle",{cx:"11",cy:"18",r:"2",fill:"currentColor",stroke:"none"})]})}function Ht(){return Z("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:[h("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),h("line",{x1:"5",y1:"12",x2:"19",y2:"12"})]})}import{Fragment as Kt,jsx as g,jsxs as x}from"react/jsx-runtime";var Ut=g("div",{className:"rle-empty",children:"Map unavailable"});function Vt(){let t=zt(null),[e,i]=X(!0),[r,n]=X(!0);return Ue(()=>{let s=t.current;if(!s)return;let o=()=>{let{clientWidth:v,scrollLeft:L,scrollWidth:p}=s;i(L<=0),n(L+v>=p-1)},a=0,l=()=>{a||(a=requestAnimationFrame(()=>{a=0,o()}))};o(),s.addEventListener("scroll",o,{passive:!0});let c,d;return typeof ResizeObserver<"u"&&(c=new ResizeObserver(o),c.observe(s)),typeof MutationObserver<"u"&&(d=new MutationObserver(l),d.observe(s,{characterData:!0,childList:!0,subtree:!0})),()=>{s.removeEventListener("scroll",o),c?.disconnect(),d?.disconnect(),a&&cancelAnimationFrame(a)}},[]),{atEnd:r,atStart:e,ref:t}}function Ve({search:t,toolbarEnd:e,mobileAction:i,autoFetch:r=!0,hasMap:n,mapCenter:s,mapZoom:o,className:a}){let l=y(),{Search:c}=F(),d=R(),{filters:v,set:L}=W(),p=n??l.map!=null,[b,u]=X("list"),[m,f]=X(!1),{atEnd:I,atStart:J,ref:E}=Vt(),_=t?{value:String(v[t.filterKey]??""),onChange:je=>{L({[t.filterKey]:je||void 0})},placeholder:t.placeholder}:void 0;Ue(()=>{r!==!1&&l.applyFilters({})},[l,r]);let $e=()=>{L(l.filters.clearedParams())},We=l.filters.activeKeys(v).length,qe=d.total??d.items.length;return x("div",{className:a?`rle-app ${a}`:"rle-app",children:[x("div",{className:"rle-filter-bar",children:[x("div",{className:"rle-filter-bar__scroll",ref:E,children:[_&&g("div",{className:"rle-filter-bar__search",children:g(c,{value:_.value,onChange:_.onChange,placeholder:_.placeholder})}),g(Y,{className:"rle-filters-row",groupClassName:"rle-filter-group",hideLabels:!0})]}),!J&&g("div",{className:"rle-filter-bar__fade rle-filter-bar__fade--start","aria-hidden":"true"}),!I&&g("div",{className:"rle-filter-bar__fade rle-filter-bar__fade--end","aria-hidden":"true"})]}),g(ze,{search:_,onFiltersClick:()=>f(!0),filterCount:We,action:i}),x("div",{className:`rle-body ${p?"rle-split":"rle-body--list-only"}`,"data-mobile-view":b,children:[x("div",{className:"rle-list",children:[x("div",{className:"rle-list-header",children:[g(xe,{}),e&&g("div",{className:"rle-list-header__toolbar",children:e})]}),g(Se,{className:"rle-list-grid"}),g(Ee,{})]}),p&&g("div",{className:"rle-map",children:g(ke,{center:s,zoom:o,fallback:Ut})})]}),p&&g(Be,{view:b,onViewChange:u}),g(He,{title:"Filters",open:m,onOpenChange:f,footer:x(Kt,{children:[g("button",{type:"button",className:"rle-btn rle-btn--ghost",onClick:$e,children:"Clear all"}),x("button",{type:"button",className:"rle-btn rle-btn--primary",onClick:()=>f(!1),children:["Show ",qe," results"]})]}),children:g(Y,{className:"rle-filter-stack",groupClassName:"rle-filter-group"})})]})}import{useEffect as $t,useRef as Wt,useState as qt}from"react";import{jsx as me,jsxs as Gt}from"react/jsx-runtime";function Ke(t){return"provider"in t}function jt(t){let e=t!=null&&!Ke(t),i=e?t.apiKey:void 0,r=e?t.mapId:void 0,[n,s]=qt(()=>!t||Ke(t)?{ready:!0,provider:t?.provider}:{ready:!1});return $t(()=>{if(!i)return;let o=!1;return import("./maps/google/index.js").then(({googleProvider:a})=>{o||s({ready:!0,provider:a({apiKey:i,mapId:r})})}),()=>{o=!0}},[i,r]),n}function Qt({onFiltersChange:t}){let e=Wt(t);return e.current=t,Ne("FiltersChanged",i=>{i.type==="FiltersChanged"&&e.current(i.filters)}),null}function mn(t){let{datasets:e,filters:i,map:r,components:n,initialFilters:s,onFiltersChange:o,mobileAction:a,search:l,toolbarEnd:c,config:d,autoFetch:v,className:L}=t,{ready:p,provider:b}=jt(r);if(!p)return null;let u=[];for(let I of e)u.push(ve(I));i&&u.push(Le(i)),b&&u.push(he(b)),s&&u.push(be(s)),d&&u.push(ye(d));let m=fe(...u),f={...Oe,...n};return Gt(Me,{...m,children:[o&&me(Qt,{onFiltersChange:o}),me(Pe,{...f,children:me(Ve,{className:L,search:l,toolbarEnd:c,mobileAction:a,autoFetch:v,mapCenter:r?.center,mapZoom:r?.zoom})})]})}export{H as a,N as b,z as c,U as d,ge as e,V as f,K as g,fe as h,ye as i,he as j,ve as k,Le as l,pi as m,be as n,ci as o,Pe as p,F as q,$ as r,y as s,S as t,W as u,Y as v,R as w,Se as x,ke as y,Ee as z,xe as A,Ne as B,Me as C,te as D,ie as E,re as F,ne as G,se as H,ae as I,le as J,de as K,pe as L,ce as M,Oe as N,Be as O,He as P,Ve as Q,mn as R};
|
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
|
|
2
|
+
var _chunk4CZJODMKcjs = require('./chunk-4CZJODMK.cjs');var m=(e=>(e.Paged="paged",e.Infinite="infinite",e))(m||{});var g=(s=>(s.FiltersChanged="FiltersChanged",s.ResultsLoaded="ResultsLoaded",s.PointClicked="PointClicked",s.BoundsChanged="BoundsChanged",s.LayerToggled="LayerToggled",s))(g||{});var y= (_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 P(r,t){let e=new Set([...Object.keys(r),...Object.keys(t)]);for(let i of e)if(r[i]!==t[i])return!1;return!0}var c= (_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 e=this.toQueryFn(t.state.filters);P(e,this.history.getQuery())||this.withSyncGuard(()=>this.history.setQuery(e))}applyFiltersSafely(t,e){Promise.resolve(t.applyFilters(e)).catch(()=>{})}withSyncGuard(t){this.isSyncing=!0;try{t()}finally{this.isSyncing=!1}}}, _class2);var p=class{constructor(t={}){this.mode=_nullishCoalesce(t.mode, () => ("replace"))}getQuery(){if(typeof window>"u")return{};let t=new URLSearchParams(window.location.search),e={};for(let[i,o]of t)o!==""&&(e[i]=o);return e}setQuery(t){if(typeof window>"u")return;let e=new URLSearchParams;for(let[h,u]of Object.entries(t))u===void 0||u===""||e.set(h,u);let i=e.toString(),o=i?`?${i}`:"";if(o===window.location.search)return;let s=`${window.location.pathname}${o}${window.location.hash}`;this.mode==="push"?window.history.pushState(window.history.state,"",s):window.history.replaceState(window.history.state,"",s)}subscribe(t){return typeof window>"u"?()=>{}:(window.addEventListener("popstate",t),()=>{window.removeEventListener("popstate",t)})}};var _jsxruntime = require('react/jsx-runtime');function M({children:r}){let{Toolbar:t}=_chunk4CZJODMKcjs.q.call(void 0, );return _jsxruntime.jsx.call(void 0, t,{children:r})}var _react = require('react');function ot(){let r=_chunk4CZJODMKcjs.s.call(void 0, ),t=_chunk4CZJODMKcjs.t.call(void 0, ),e=_react.useCallback.call(void 0, o=>r.loadPoints(o),[r]),i=_react.useCallback.call(void 0, (o,s)=>r.selectPoint(o,s),[r]);return{bounds:t.bounds,points:t.points,loadPoints:e,selectPoint:i}}function yt(r){let t=_chunk4CZJODMKcjs.s.call(void 0, ),e=_chunk4CZJODMKcjs.t.call(void 0, ),i=_react.useCallback.call(void 0, ()=>t.toggleLayer(r),[t,r]);return{visible:_nullishCoalesce(e.layers[r], () => (!0)),points:_nullishCoalesce(e.points[r], () => ([])),toggle:i}}exports.BrowserHistoryPort = p; exports.DatasetRegistry = _chunk4CZJODMKcjs.c; exports.FilterRegistry = _chunk4CZJODMKcjs.b; exports.ListingApp = _chunk4CZJODMKcjs.R; exports.ListingComponentsProvider = _chunk4CZJODMKcjs.p; exports.ListingConfig = _chunk4CZJODMKcjs.f; exports.ListingEngine = _chunk4CZJODMKcjs.g; exports.ListingEngineContext = _chunk4CZJODMKcjs.r; exports.ListingEventType = g; exports.ListingFilters = _chunk4CZJODMKcjs.v; exports.ListingList = _chunk4CZJODMKcjs.x; exports.ListingMap = _chunk4CZJODMKcjs.y; exports.ListingPagination = _chunk4CZJODMKcjs.z; exports.ListingProvider = _chunk4CZJODMKcjs.C; exports.ListingResultHeader = _chunk4CZJODMKcjs.A; exports.ListingStore = _chunk4CZJODMKcjs.a; exports.ListingToolbar = M; exports.MemoryHistoryPort = y; exports.PaginationMode = m; exports.TypedEmitter = _chunk4CZJODMKcjs.d; exports.UrlSyncController = c; exports.composeListingProviders = _chunk4CZJODMKcjs.h; exports.listingDefaultConfig = _chunk4CZJODMKcjs.e; exports.useListing = _chunk4CZJODMKcjs.s; exports.useListingComponents = _chunk4CZJODMKcjs.q; exports.useListingEvent = _chunk4CZJODMKcjs.B; exports.useListingFilters = _chunk4CZJODMKcjs.u; exports.useListingLayer = yt; exports.useListingMap = ot; exports.useListingResults = _chunk4CZJODMKcjs.w; exports.useListingState = _chunk4CZJODMKcjs.t; exports.withConfig = _chunk4CZJODMKcjs.i; exports.withDataset = _chunk4CZJODMKcjs.k; exports.withFilters = _chunk4CZJODMKcjs.l; exports.withInitialFilters = _chunk4CZJODMKcjs.n; exports.withMap = _chunk4CZJODMKcjs.j; exports.withPrimaryDataset = _chunk4CZJODMKcjs.o; exports.withUrlSync = _chunk4CZJODMKcjs.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, Q as QueryParams, L as LatLng } from './map-provider.interface-DT-v1plm.cjs';
|
|
2
2
|
export { b as EntityAdapter, c as MapHandle, d as MapInitOptions, e as PageRequest, R as RenderedLayer } from './map-provider.interface-DT-v1plm.cjs';
|
|
3
|
-
import { P as PaginationMode, D as DatasetDefinition, I as IListingConfigOptions, F as FilterRegistry, a as IListingToolbarProps } from './listing-app-
|
|
4
|
-
export { C as ClusterOptions, b as FilterControlProps, c as FilterDefinition, d as IListingCardProps, e as IListingComponents, f as IListingEmptyProps, g as IListingFilterPanelProps, h as IListingLoadingProps, i as IListingMarkerProps, j as IListingPopupProps, k as IListingResultHeaderProps, l as IListingSearchProps, m as IListingSidebarProps, L as ListingApp, n as ListingAppProps, o as ListingComponentsProvider, M as MarkerRenderer, u as useListingComponents } from './listing-app-
|
|
3
|
+
import { P as PaginationMode, D as DatasetDefinition, I as IListingConfigOptions, F as FilterRegistry, a as IListingToolbarProps } from './listing-app-BtNNEkX1.cjs';
|
|
4
|
+
export { C as ClusterOptions, b as FilterControlProps, c as FilterDefinition, d as IListingCardProps, e as IListingComponents, f as IListingEmptyProps, g as IListingFilterPanelProps, h as IListingLoadingProps, i as IListingMarkerProps, j as IListingPopupProps, k as IListingResultHeaderProps, l as IListingSearchProps, m as IListingSidebarProps, L as ListingApp, n as ListingAppProps, o as ListingComponentsProvider, M as MarkerRenderer, u as useListingComponents } from './listing-app-BtNNEkX1.cjs';
|
|
5
5
|
import * as react from 'react';
|
|
6
6
|
import { ReactNode } from 'react';
|
|
7
7
|
|
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, Q as QueryParams, L as LatLng } from './map-provider.interface-DT-v1plm.js';
|
|
2
2
|
export { b as EntityAdapter, c as MapHandle, d as MapInitOptions, e as PageRequest, R as RenderedLayer } from './map-provider.interface-DT-v1plm.js';
|
|
3
|
-
import { P as PaginationMode, D as DatasetDefinition, I as IListingConfigOptions, F as FilterRegistry, a as IListingToolbarProps } from './listing-app-
|
|
4
|
-
export { C as ClusterOptions, b as FilterControlProps, c as FilterDefinition, d as IListingCardProps, e as IListingComponents, f as IListingEmptyProps, g as IListingFilterPanelProps, h as IListingLoadingProps, i as IListingMarkerProps, j as IListingPopupProps, k as IListingResultHeaderProps, l as IListingSearchProps, m as IListingSidebarProps, L as ListingApp, n as ListingAppProps, o as ListingComponentsProvider, M as MarkerRenderer, u as useListingComponents } from './listing-app-
|
|
3
|
+
import { P as PaginationMode, D as DatasetDefinition, I as IListingConfigOptions, F as FilterRegistry, a as IListingToolbarProps } from './listing-app-IG1awue3.js';
|
|
4
|
+
export { C as ClusterOptions, b as FilterControlProps, c as FilterDefinition, d as IListingCardProps, e as IListingComponents, f as IListingEmptyProps, g as IListingFilterPanelProps, h as IListingLoadingProps, i as IListingMarkerProps, j as IListingPopupProps, k as IListingResultHeaderProps, l as IListingSearchProps, m as IListingSidebarProps, L as ListingApp, n as ListingAppProps, o as ListingComponentsProvider, M as MarkerRenderer, u as useListingComponents } from './listing-app-IG1awue3.js';
|
|
5
5
|
import * as react from 'react';
|
|
6
6
|
import { ReactNode } from 'react';
|
|
7
7
|
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{A as J,B as K,C as N,R as f,a as w,b as F,c as S,d as Q,e as x,f as T,g as L,h as H,i as O,j as k,k as q,l as E,m as C,n as U,o as B,p as I,q as l,r as G,s as n,t as a,u as R,v as $,w as j,x as A,y as z,z as D}from"./chunk-
|
|
2
|
+
import{A as J,B as K,C as N,R as f,a as w,b as F,c as S,d as Q,e as x,f as T,g as L,h as H,i as O,j as k,k as q,l as E,m as C,n as U,o as B,p as I,q as l,r as G,s as n,t as a,u as R,v as $,w as j,x as A,y as z,z as D}from"./chunk-GSWGCJCO.js";var m=(e=>(e.Paged="paged",e.Infinite="infinite",e))(m||{});var g=(s=>(s.FiltersChanged="FiltersChanged",s.ResultsLoaded="ResultsLoaded",s.PointClicked="PointClicked",s.BoundsChanged="BoundsChanged",s.LayerToggled="LayerToggled",s))(g||{});var y=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 P(r,t){let e=new Set([...Object.keys(r),...Object.keys(t)]);for(let i of e)if(r[i]!==t[i])return!1;return!0}var c=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 e=this.toQueryFn(t.state.filters);P(e,this.history.getQuery())||this.withSyncGuard(()=>this.history.setQuery(e))}applyFiltersSafely(t,e){Promise.resolve(t.applyFilters(e)).catch(()=>{})}withSyncGuard(t){this.isSyncing=!0;try{t()}finally{this.isSyncing=!1}}};var p=class{mode;constructor(t={}){this.mode=t.mode??"replace"}getQuery(){if(typeof window>"u")return{};let t=new URLSearchParams(window.location.search),e={};for(let[i,o]of t)o!==""&&(e[i]=o);return e}setQuery(t){if(typeof window>"u")return;let e=new URLSearchParams;for(let[h,u]of Object.entries(t))u===void 0||u===""||e.set(h,u);let i=e.toString(),o=i?`?${i}`:"";if(o===window.location.search)return;let s=`${window.location.pathname}${o}${window.location.hash}`;this.mode==="push"?window.history.pushState(window.history.state,"",s):window.history.replaceState(window.history.state,"",s)}subscribe(t){return typeof window>"u"?()=>{}:(window.addEventListener("popstate",t),()=>{window.removeEventListener("popstate",t)})}};import{jsx as b}from"react/jsx-runtime";function M({children:r}){let{Toolbar:t}=l();return b(t,{children:r})}import{useCallback as d}from"react";function ot(){let r=n(),t=a(),e=d(o=>r.loadPoints(o),[r]),i=d((o,s)=>r.selectPoint(o,s),[r]);return{bounds:t.bounds,points:t.points,loadPoints:e,selectPoint:i}}import{useCallback as v}from"react";function yt(r){let t=n(),e=a(),i=v(()=>t.toggleLayer(r),[t,r]);return{visible:e.layers[r]??!0,points:e.points[r]??[],toggle:i}}export{p as BrowserHistoryPort,S as DatasetRegistry,F as FilterRegistry,f as ListingApp,I as ListingComponentsProvider,T as ListingConfig,L as ListingEngine,G as ListingEngineContext,g as ListingEventType,$ as ListingFilters,A as ListingList,z as ListingMap,D as ListingPagination,N as ListingProvider,J as ListingResultHeader,w as ListingStore,M as ListingToolbar,y as MemoryHistoryPort,m as PaginationMode,Q as TypedEmitter,c as UrlSyncController,H as composeListingProviders,x as listingDefaultConfig,n as useListing,l as useListingComponents,K as useListingEvent,R as useListingFilters,yt as useListingLayer,ot as useListingMap,j as useListingResults,a as useListingState,O as withConfig,q as withDataset,E as withFilters,U as withInitialFilters,k as withMap,B as withPrimaryDataset,C as withUrlSync};
|
|
@@ -48,8 +48,9 @@ interface IListingConfigOptions {
|
|
|
48
48
|
/**
|
|
49
49
|
* Framework-free registry for `FilterDefinition`s: programmatic add / remove /
|
|
50
50
|
* reorder / replace, plus folding raw control values into `TFilters`
|
|
51
|
-
* (`toFilters`)
|
|
52
|
-
* applied `TFilters` (`activeKeys`)
|
|
51
|
+
* (`toFilters`), reporting which registered filters currently affect an
|
|
52
|
+
* applied `TFilters` (`activeKeys`), and building the reset-everything patch
|
|
53
|
+
* (`clearedParams`).
|
|
53
54
|
*
|
|
54
55
|
* Defs are stored by VALUE (shallow-cloned on `add`/`replace`), never by the
|
|
55
56
|
* caller's original reference — `reorder()` rewrites `order` in place on the
|
|
@@ -69,6 +70,7 @@ declare class FilterRegistry<TFilters> {
|
|
|
69
70
|
has(key: string): boolean;
|
|
70
71
|
toFilters(values: Record<string, unknown>): TFilters;
|
|
71
72
|
activeKeys(filters: TFilters): string[];
|
|
73
|
+
clearedParams(): Partial<TFilters>;
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
interface IListingCardProps {
|
|
@@ -129,6 +131,10 @@ declare function ListingComponentsProvider(props: Partial<IListingComponents> &
|
|
|
129
131
|
declare function useListingComponents(): IListingComponents;
|
|
130
132
|
|
|
131
133
|
type BottomNavView = 'list' | 'map';
|
|
134
|
+
/**
|
|
135
|
+
* An action button in the mobile chrome (e.g. "Add"/"Save"). Despite the
|
|
136
|
+
* name (kept for API compatibility), it renders in `MobileHeader`, not here.
|
|
137
|
+
*/
|
|
132
138
|
interface IBottomNavAction {
|
|
133
139
|
label: string;
|
|
134
140
|
icon?: ReactNode;
|
|
@@ -139,8 +145,9 @@ interface IBottomNavProps {
|
|
|
139
145
|
onViewChange(view: BottomNavView): void;
|
|
140
146
|
}
|
|
141
147
|
/**
|
|
142
|
-
* Mobile-only bottom navigation (`.rle-bottom-nav`, hidden
|
|
143
|
-
* see `styles.css`
|
|
148
|
+
* Mobile-only bottom navigation (`.rle-bottom-nav`, CSS-hidden above the
|
|
149
|
+
* mobile breakpoint -- see `styles.css`'s layout-shell section, the single
|
|
150
|
+
* source of truth for it): a floating **List | Map** segmented toggle
|
|
144
151
|
* (`.rle-viewtoggle`) that drives which of `StyledListingLayout`'s two
|
|
145
152
|
* full-area panels is visible. The **Filters** button and the optional caller
|
|
146
153
|
* action (e.g. "Save") live in the mobile header (`MobileHeader`) instead, so
|
|
@@ -166,13 +173,14 @@ interface IStyledListingLayoutProps {
|
|
|
166
173
|
};
|
|
167
174
|
/** Extra content rendered in `.rle-list-header` (above the list), to the right of `ListingResultHeader` (e.g. a sort control + save-search). */
|
|
168
175
|
toolbarEnd?: ReactNode;
|
|
169
|
-
/** Optional
|
|
176
|
+
/** Optional mobile-header action button (e.g. "Save"), forwarded verbatim to `<MobileHeader action={...} />`. Omit to render just the search + Filters button there. */
|
|
170
177
|
mobileAction?: IBottomNavAction;
|
|
171
178
|
/**
|
|
172
179
|
* Whether a map is configured. When `false`, the map region is dropped and
|
|
173
180
|
* the results list fills the full width as a multi-column grid, and the
|
|
174
181
|
* mobile List|Map toggle is omitted (nothing to toggle to). Defaults to
|
|
175
|
-
* `
|
|
182
|
+
* `engine.map != null` -- the engine is the source of truth, so this only
|
|
183
|
+
* needs passing to override that (e.g. to hide a configured map).
|
|
176
184
|
*/
|
|
177
185
|
hasMap?: boolean;
|
|
178
186
|
/** Whether the layout fetches the first page itself on mount (`engine.applyFilters({})`). Defaults to `true`. */
|
|
@@ -192,8 +200,10 @@ interface IStyledListingLayoutProps {
|
|
|
192
200
|
* the `.rle-*` layout classes added to `styles.css` alongside this file --
|
|
193
201
|
* no Tailwind, no inline styles, no other stylesheet required.
|
|
194
202
|
*
|
|
195
|
-
* STRUCTURE (`.rle-app`)
|
|
196
|
-
*
|
|
203
|
+
* STRUCTURE (`.rle-app`) -- the mobile/desktop breakpoint and the grid's
|
|
204
|
+
* column sizing live in ONE place, `styles.css`'s layout-shell section; the
|
|
205
|
+
* bullets below say only which side of it each piece renders on:
|
|
206
|
+
* - `.rle-filter-bar` (desktop only, CSS-hidden below the breakpoint): the
|
|
197
207
|
* optional `Search` slot and `<ListingFilters>` laid out as a single
|
|
198
208
|
* horizontally-scrolling row (`className="rle-filters-row"`,
|
|
199
209
|
* `groupClassName="rle-filter-group"`) with edge fades. The result header +
|
|
@@ -201,29 +211,31 @@ interface IStyledListingLayoutProps {
|
|
|
201
211
|
* - `.rle-list-header` (top of `.rle-list`): `<ListingResultHeader>` (title +
|
|
202
212
|
* count) at the left, `toolbarEnd` (sort control, save-search, ...) at the
|
|
203
213
|
* right -- a heading for the results, on every viewport.
|
|
204
|
-
* - `.rle-body.rle-split`: a CSS grid from
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
* `
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
* - `<
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
+
* - `.rle-body.rle-split`: a list-majority list|map CSS grid from the
|
|
215
|
+
* breakpoint up; below it, a single full-area panel with exactly one of
|
|
216
|
+
* `.rle-list`/`.rle-map` visible at a time via `data-mobile-view` (see
|
|
217
|
+
* `styles.css`'s mobile media query). Both regions stay mounted at ALL
|
|
218
|
+
* times regardless of viewport/toggle state -- only their visibility flips
|
|
219
|
+
* -- so neither `ListingList` nor `ListingMap` remounts (and re-triggers
|
|
220
|
+
* its own mount effects) on toggle or resize.
|
|
221
|
+
* - `<MobileHeader>` (mobile only): the same search box, a **Filters** button
|
|
222
|
+
* (opens the `<BottomSheet>`, with an applied-filter count badge) and the
|
|
223
|
+
* optional `mobileAction`.
|
|
224
|
+
* - `<BottomNav>` (mobile only): the floating List|Map view toggle, wired to
|
|
225
|
+
* the same `mobileView` state as the CSS toggle. Omitted when there is no
|
|
226
|
+
* map (nothing to toggle to).
|
|
214
227
|
* - `<BottomSheet title="Filters">`: the SAME `<ListingFilters>` component,
|
|
215
228
|
* stacked vertically (`className="rle-filter-stack"`) for the sheet's
|
|
216
|
-
* narrower body, plus a footer with "Clear all" (
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
* left to commit).
|
|
229
|
+
* narrower body, plus a footer with "Clear all" (applies
|
|
230
|
+
* `engine.filters.clearedParams()` -- see that method's doc for why a reset
|
|
231
|
+
* round-trips each def's to/fromParams) and "Show N results" (just closes
|
|
232
|
+
* the sheet -- every filter control already applies live via its own
|
|
233
|
+
* `onChange`, so there is nothing left to commit).
|
|
222
234
|
* - Fetches the first page itself on mount (`engine.applyFilters({})`) by
|
|
223
235
|
* default -- pass `autoFetch={false}`
|
|
224
236
|
* to opt out and drive the first fetch yourself.
|
|
225
237
|
*/
|
|
226
|
-
declare function StyledListingLayout({ search, toolbarEnd, mobileAction, autoFetch, hasMap, mapCenter, mapZoom, className, }: IStyledListingLayoutProps): react.JSX.Element;
|
|
238
|
+
declare function StyledListingLayout({ search, toolbarEnd, mobileAction, autoFetch, hasMap: hasMapProp, mapCenter, mapZoom, className, }: IStyledListingLayoutProps): react.JSX.Element;
|
|
227
239
|
|
|
228
240
|
/**
|
|
229
241
|
* Two-shape `map` prop: pass a ready `MapProvider`, or the `{ apiKey, mapId? }`
|
|
@@ -256,14 +268,14 @@ interface ListingAppProps<TFilters> {
|
|
|
256
268
|
datasets: DatasetDefinition<any, TFilters>[];
|
|
257
269
|
/** A `(reg) => { reg.add(...); }` callback that registers your filters -- forwarded verbatim to `withFilters`. */
|
|
258
270
|
filters?: (reg: FilterRegistry<TFilters>) => void;
|
|
259
|
-
/** A ready `MapProvider`, or `{ apiKey, mapId? }` to build a `googleProvider` internally. Omit for no map
|
|
271
|
+
/** A ready `MapProvider`, or `{ apiKey, mapId? }` to build a `googleProvider` internally. Omit for no map -- the layout drops the map region and renders the list full-width. */
|
|
260
272
|
map?: ListingAppMapProp;
|
|
261
273
|
/** Slot overrides, merged OVER the `/styled` defaults -- see this file's doc comment for how the merge works. */
|
|
262
274
|
components?: Partial<IListingComponents>;
|
|
263
275
|
/**
|
|
264
|
-
* Hydrates the engine's initial filters on mount -- typically
|
|
265
|
-
* the CONSUMER's own URL (
|
|
266
|
-
* URLSearchParams(window.location.search)
|
|
276
|
+
* Hydrates the engine's initial filters on mount -- typically parsed from
|
|
277
|
+
* the CONSUMER's own URL (your own query-string parser over `new
|
|
278
|
+
* URLSearchParams(window.location.search)`), but any source works. Half
|
|
267
279
|
* of the event-based URL API this component exposes: `ListingApp` never
|
|
268
280
|
* reads `window.location` itself, it only accepts filters as a prop.
|
|
269
281
|
*/
|
|
@@ -289,7 +301,7 @@ interface ListingAppProps<TFilters> {
|
|
|
289
301
|
* they are no longer the primary/recommended path for new integrations.
|
|
290
302
|
*/
|
|
291
303
|
onFiltersChange?: (filters: TFilters) => void;
|
|
292
|
-
/** The mobile
|
|
304
|
+
/** The mobile header action (e.g. "Save"/"Add") -- forwarded verbatim to `StyledListingLayout`/`MobileHeader`. */
|
|
293
305
|
mobileAction?: IBottomNavAction;
|
|
294
306
|
search?: IStyledListingLayoutProps['search'];
|
|
295
307
|
toolbarEnd?: IStyledListingLayoutProps['toolbarEnd'];
|
|
@@ -48,8 +48,9 @@ interface IListingConfigOptions {
|
|
|
48
48
|
/**
|
|
49
49
|
* Framework-free registry for `FilterDefinition`s: programmatic add / remove /
|
|
50
50
|
* reorder / replace, plus folding raw control values into `TFilters`
|
|
51
|
-
* (`toFilters`)
|
|
52
|
-
* applied `TFilters` (`activeKeys`)
|
|
51
|
+
* (`toFilters`), reporting which registered filters currently affect an
|
|
52
|
+
* applied `TFilters` (`activeKeys`), and building the reset-everything patch
|
|
53
|
+
* (`clearedParams`).
|
|
53
54
|
*
|
|
54
55
|
* Defs are stored by VALUE (shallow-cloned on `add`/`replace`), never by the
|
|
55
56
|
* caller's original reference — `reorder()` rewrites `order` in place on the
|
|
@@ -69,6 +70,7 @@ declare class FilterRegistry<TFilters> {
|
|
|
69
70
|
has(key: string): boolean;
|
|
70
71
|
toFilters(values: Record<string, unknown>): TFilters;
|
|
71
72
|
activeKeys(filters: TFilters): string[];
|
|
73
|
+
clearedParams(): Partial<TFilters>;
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
interface IListingCardProps {
|
|
@@ -129,6 +131,10 @@ declare function ListingComponentsProvider(props: Partial<IListingComponents> &
|
|
|
129
131
|
declare function useListingComponents(): IListingComponents;
|
|
130
132
|
|
|
131
133
|
type BottomNavView = 'list' | 'map';
|
|
134
|
+
/**
|
|
135
|
+
* An action button in the mobile chrome (e.g. "Add"/"Save"). Despite the
|
|
136
|
+
* name (kept for API compatibility), it renders in `MobileHeader`, not here.
|
|
137
|
+
*/
|
|
132
138
|
interface IBottomNavAction {
|
|
133
139
|
label: string;
|
|
134
140
|
icon?: ReactNode;
|
|
@@ -139,8 +145,9 @@ interface IBottomNavProps {
|
|
|
139
145
|
onViewChange(view: BottomNavView): void;
|
|
140
146
|
}
|
|
141
147
|
/**
|
|
142
|
-
* Mobile-only bottom navigation (`.rle-bottom-nav`, hidden
|
|
143
|
-
* see `styles.css`
|
|
148
|
+
* Mobile-only bottom navigation (`.rle-bottom-nav`, CSS-hidden above the
|
|
149
|
+
* mobile breakpoint -- see `styles.css`'s layout-shell section, the single
|
|
150
|
+
* source of truth for it): a floating **List | Map** segmented toggle
|
|
144
151
|
* (`.rle-viewtoggle`) that drives which of `StyledListingLayout`'s two
|
|
145
152
|
* full-area panels is visible. The **Filters** button and the optional caller
|
|
146
153
|
* action (e.g. "Save") live in the mobile header (`MobileHeader`) instead, so
|
|
@@ -166,13 +173,14 @@ interface IStyledListingLayoutProps {
|
|
|
166
173
|
};
|
|
167
174
|
/** Extra content rendered in `.rle-list-header` (above the list), to the right of `ListingResultHeader` (e.g. a sort control + save-search). */
|
|
168
175
|
toolbarEnd?: ReactNode;
|
|
169
|
-
/** Optional
|
|
176
|
+
/** Optional mobile-header action button (e.g. "Save"), forwarded verbatim to `<MobileHeader action={...} />`. Omit to render just the search + Filters button there. */
|
|
170
177
|
mobileAction?: IBottomNavAction;
|
|
171
178
|
/**
|
|
172
179
|
* Whether a map is configured. When `false`, the map region is dropped and
|
|
173
180
|
* the results list fills the full width as a multi-column grid, and the
|
|
174
181
|
* mobile List|Map toggle is omitted (nothing to toggle to). Defaults to
|
|
175
|
-
* `
|
|
182
|
+
* `engine.map != null` -- the engine is the source of truth, so this only
|
|
183
|
+
* needs passing to override that (e.g. to hide a configured map).
|
|
176
184
|
*/
|
|
177
185
|
hasMap?: boolean;
|
|
178
186
|
/** Whether the layout fetches the first page itself on mount (`engine.applyFilters({})`). Defaults to `true`. */
|
|
@@ -192,8 +200,10 @@ interface IStyledListingLayoutProps {
|
|
|
192
200
|
* the `.rle-*` layout classes added to `styles.css` alongside this file --
|
|
193
201
|
* no Tailwind, no inline styles, no other stylesheet required.
|
|
194
202
|
*
|
|
195
|
-
* STRUCTURE (`.rle-app`)
|
|
196
|
-
*
|
|
203
|
+
* STRUCTURE (`.rle-app`) -- the mobile/desktop breakpoint and the grid's
|
|
204
|
+
* column sizing live in ONE place, `styles.css`'s layout-shell section; the
|
|
205
|
+
* bullets below say only which side of it each piece renders on:
|
|
206
|
+
* - `.rle-filter-bar` (desktop only, CSS-hidden below the breakpoint): the
|
|
197
207
|
* optional `Search` slot and `<ListingFilters>` laid out as a single
|
|
198
208
|
* horizontally-scrolling row (`className="rle-filters-row"`,
|
|
199
209
|
* `groupClassName="rle-filter-group"`) with edge fades. The result header +
|
|
@@ -201,29 +211,31 @@ interface IStyledListingLayoutProps {
|
|
|
201
211
|
* - `.rle-list-header` (top of `.rle-list`): `<ListingResultHeader>` (title +
|
|
202
212
|
* count) at the left, `toolbarEnd` (sort control, save-search, ...) at the
|
|
203
213
|
* right -- a heading for the results, on every viewport.
|
|
204
|
-
* - `.rle-body.rle-split`: a CSS grid from
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
* `
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
* - `<
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
+
* - `.rle-body.rle-split`: a list-majority list|map CSS grid from the
|
|
215
|
+
* breakpoint up; below it, a single full-area panel with exactly one of
|
|
216
|
+
* `.rle-list`/`.rle-map` visible at a time via `data-mobile-view` (see
|
|
217
|
+
* `styles.css`'s mobile media query). Both regions stay mounted at ALL
|
|
218
|
+
* times regardless of viewport/toggle state -- only their visibility flips
|
|
219
|
+
* -- so neither `ListingList` nor `ListingMap` remounts (and re-triggers
|
|
220
|
+
* its own mount effects) on toggle or resize.
|
|
221
|
+
* - `<MobileHeader>` (mobile only): the same search box, a **Filters** button
|
|
222
|
+
* (opens the `<BottomSheet>`, with an applied-filter count badge) and the
|
|
223
|
+
* optional `mobileAction`.
|
|
224
|
+
* - `<BottomNav>` (mobile only): the floating List|Map view toggle, wired to
|
|
225
|
+
* the same `mobileView` state as the CSS toggle. Omitted when there is no
|
|
226
|
+
* map (nothing to toggle to).
|
|
214
227
|
* - `<BottomSheet title="Filters">`: the SAME `<ListingFilters>` component,
|
|
215
228
|
* stacked vertically (`className="rle-filter-stack"`) for the sheet's
|
|
216
|
-
* narrower body, plus a footer with "Clear all" (
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
* left to commit).
|
|
229
|
+
* narrower body, plus a footer with "Clear all" (applies
|
|
230
|
+
* `engine.filters.clearedParams()` -- see that method's doc for why a reset
|
|
231
|
+
* round-trips each def's to/fromParams) and "Show N results" (just closes
|
|
232
|
+
* the sheet -- every filter control already applies live via its own
|
|
233
|
+
* `onChange`, so there is nothing left to commit).
|
|
222
234
|
* - Fetches the first page itself on mount (`engine.applyFilters({})`) by
|
|
223
235
|
* default -- pass `autoFetch={false}`
|
|
224
236
|
* to opt out and drive the first fetch yourself.
|
|
225
237
|
*/
|
|
226
|
-
declare function StyledListingLayout({ search, toolbarEnd, mobileAction, autoFetch, hasMap, mapCenter, mapZoom, className, }: IStyledListingLayoutProps): react.JSX.Element;
|
|
238
|
+
declare function StyledListingLayout({ search, toolbarEnd, mobileAction, autoFetch, hasMap: hasMapProp, mapCenter, mapZoom, className, }: IStyledListingLayoutProps): react.JSX.Element;
|
|
227
239
|
|
|
228
240
|
/**
|
|
229
241
|
* Two-shape `map` prop: pass a ready `MapProvider`, or the `{ apiKey, mapId? }`
|
|
@@ -256,14 +268,14 @@ interface ListingAppProps<TFilters> {
|
|
|
256
268
|
datasets: DatasetDefinition<any, TFilters>[];
|
|
257
269
|
/** A `(reg) => { reg.add(...); }` callback that registers your filters -- forwarded verbatim to `withFilters`. */
|
|
258
270
|
filters?: (reg: FilterRegistry<TFilters>) => void;
|
|
259
|
-
/** A ready `MapProvider`, or `{ apiKey, mapId? }` to build a `googleProvider` internally. Omit for no map
|
|
271
|
+
/** A ready `MapProvider`, or `{ apiKey, mapId? }` to build a `googleProvider` internally. Omit for no map -- the layout drops the map region and renders the list full-width. */
|
|
260
272
|
map?: ListingAppMapProp;
|
|
261
273
|
/** Slot overrides, merged OVER the `/styled` defaults -- see this file's doc comment for how the merge works. */
|
|
262
274
|
components?: Partial<IListingComponents>;
|
|
263
275
|
/**
|
|
264
|
-
* Hydrates the engine's initial filters on mount -- typically
|
|
265
|
-
* the CONSUMER's own URL (
|
|
266
|
-
* URLSearchParams(window.location.search)
|
|
276
|
+
* Hydrates the engine's initial filters on mount -- typically parsed from
|
|
277
|
+
* the CONSUMER's own URL (your own query-string parser over `new
|
|
278
|
+
* URLSearchParams(window.location.search)`), but any source works. Half
|
|
267
279
|
* of the event-based URL API this component exposes: `ListingApp` never
|
|
268
280
|
* reads `window.location` itself, it only accepts filters as a prop.
|
|
269
281
|
*/
|
|
@@ -289,7 +301,7 @@ interface ListingAppProps<TFilters> {
|
|
|
289
301
|
* they are no longer the primary/recommended path for new integrations.
|
|
290
302
|
*/
|
|
291
303
|
onFiltersChange?: (filters: TFilters) => void;
|
|
292
|
-
/** The mobile
|
|
304
|
+
/** The mobile header action (e.g. "Save"/"Add") -- forwarded verbatim to `StyledListingLayout`/`MobileHeader`. */
|
|
293
305
|
mobileAction?: IBottomNavAction;
|
|
294
306
|
search?: IStyledListingLayoutProps['search'];
|
|
295
307
|
toolbarEnd?: IStyledListingLayoutProps['toolbarEnd'];
|
package/dist/styled/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
|
|
2
|
-
var
|
|
2
|
+
var _chunk4CZJODMKcjs = require('../chunk-4CZJODMK.cjs');var _jsxruntime = require('react/jsx-runtime');function L({children:o}){return _jsxruntime.jsx.call(void 0, _chunk4CZJODMKcjs.p,{..._chunk4CZJODMKcjs.N,children:o})}exports.BottomNav = _chunk4CZJODMKcjs.O; exports.BottomSheet = _chunk4CZJODMKcjs.P; exports.ListingApp = _chunk4CZJODMKcjs.R; exports.StyledCard = _chunk4CZJODMKcjs.D; exports.StyledComponentsProviderWithDefaults = L; exports.StyledEmpty = _chunk4CZJODMKcjs.E; exports.StyledFilterPanel = _chunk4CZJODMKcjs.F; exports.StyledListingLayout = _chunk4CZJODMKcjs.Q; exports.StyledLoading = _chunk4CZJODMKcjs.G; exports.StyledMarker = _chunk4CZJODMKcjs.H; exports.StyledPopup = _chunk4CZJODMKcjs.I; exports.StyledResultHeader = _chunk4CZJODMKcjs.J; exports.StyledSearch = _chunk4CZJODMKcjs.K; exports.StyledSidebar = _chunk4CZJODMKcjs.L; exports.StyledToolbar = _chunk4CZJODMKcjs.M; exports.styledDefaultComponents = _chunk4CZJODMKcjs.N;
|
package/dist/styled/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { d as IListingCardProps, f as IListingEmptyProps, g as IListingFilterPanelProps, h as IListingLoadingProps, i as IListingMarkerProps, j as IListingPopupProps, k as IListingResultHeaderProps, l as IListingSearchProps, m as IListingSidebarProps, a as IListingToolbarProps, e as IListingComponents } from '../listing-app-
|
|
4
|
-
export { B as BottomNav, p as BottomNavView, q as IBottomNavAction, r as IBottomNavProps, s as IStyledListingLayoutProps, L as ListingApp, t as ListingAppMapProp, n as ListingAppProps, S as StyledListingLayout } from '../listing-app-
|
|
3
|
+
import { d as IListingCardProps, f as IListingEmptyProps, g as IListingFilterPanelProps, h as IListingLoadingProps, i as IListingMarkerProps, j as IListingPopupProps, k as IListingResultHeaderProps, l as IListingSearchProps, m as IListingSidebarProps, a as IListingToolbarProps, e as IListingComponents } from '../listing-app-BtNNEkX1.cjs';
|
|
4
|
+
export { B as BottomNav, p as BottomNavView, q as IBottomNavAction, r as IBottomNavProps, s as IStyledListingLayoutProps, L as ListingApp, t as ListingAppMapProp, n as ListingAppProps, S as StyledListingLayout } from '../listing-app-BtNNEkX1.cjs';
|
|
5
5
|
import '../map-provider.interface-DT-v1plm.cjs';
|
|
6
6
|
|
|
7
7
|
/**
|
package/dist/styled/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { d as IListingCardProps, f as IListingEmptyProps, g as IListingFilterPanelProps, h as IListingLoadingProps, i as IListingMarkerProps, j as IListingPopupProps, k as IListingResultHeaderProps, l as IListingSearchProps, m as IListingSidebarProps, a as IListingToolbarProps, e as IListingComponents } from '../listing-app-
|
|
4
|
-
export { B as BottomNav, p as BottomNavView, q as IBottomNavAction, r as IBottomNavProps, s as IStyledListingLayoutProps, L as ListingApp, t as ListingAppMapProp, n as ListingAppProps, S as StyledListingLayout } from '../listing-app-
|
|
3
|
+
import { d as IListingCardProps, f as IListingEmptyProps, g as IListingFilterPanelProps, h as IListingLoadingProps, i as IListingMarkerProps, j as IListingPopupProps, k as IListingResultHeaderProps, l as IListingSearchProps, m as IListingSidebarProps, a as IListingToolbarProps, e as IListingComponents } from '../listing-app-IG1awue3.js';
|
|
4
|
+
export { B as BottomNav, p as BottomNavView, q as IBottomNavAction, r as IBottomNavProps, s as IStyledListingLayoutProps, L as ListingApp, t as ListingAppMapProp, n as ListingAppProps, S as StyledListingLayout } from '../listing-app-IG1awue3.js';
|
|
5
5
|
import '../map-provider.interface-DT-v1plm.js';
|
|
6
6
|
|
|
7
7
|
/**
|
package/dist/styled/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{D as r,E as p,F as i,G as d,H as y,I as l,J as n,K as m,L as s,M as a,N as t,O as S,P as f,Q as P,R as u,p as e}from"../chunk-
|
|
2
|
+
import{D as r,E as p,F as i,G as d,H as y,I as l,J as n,K as m,L as s,M as a,N as t,O as S,P as f,Q as P,R as u,p as e}from"../chunk-GSWGCJCO.js";import{jsx as g}from"react/jsx-runtime";function L({children:o}){return g(e,{...t,children:o})}export{S as BottomNav,f as BottomSheet,u as ListingApp,r as StyledCard,L as StyledComponentsProviderWithDefaults,p as StyledEmpty,i as StyledFilterPanel,P as StyledListingLayout,d as StyledLoading,y as StyledMarker,l as StyledPopup,n as StyledResultHeader,m as StyledSearch,s as StyledSidebar,a as StyledToolbar,t as styledDefaultComponents};
|
package/dist/styles.css
CHANGED
|
@@ -70,33 +70,14 @@
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/* -----------------------------------------------------------------------
|
|
73
|
-
* Base -- box-sizing + font-family for every element this stylesheet owns
|
|
73
|
+
* Base -- box-sizing + font-family for every element this stylesheet owns,
|
|
74
|
+
* scoped by the `rle-` class prefix (the adapter's namespace) instead of an
|
|
75
|
+
* enumerated class list, so new components are covered automatically --
|
|
76
|
+
* including elements portaled outside `.rle-app` (sheet, backdrop).
|
|
74
77
|
* --------------------------------------------------------------------- */
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
.rle-card-body,
|
|
79
|
-
.rle-marker,
|
|
80
|
-
.rle-pin,
|
|
81
|
-
.rle-popup,
|
|
82
|
-
.rle-popup-close,
|
|
83
|
-
.rle-empty,
|
|
84
|
-
.rle-empty-icon,
|
|
85
|
-
.rle-loading,
|
|
86
|
-
.rle-loading-item,
|
|
87
|
-
.rle-skeleton,
|
|
88
|
-
.rle-result-header,
|
|
89
|
-
.rle-toolbar,
|
|
90
|
-
.rle-sidebar,
|
|
91
|
-
.rle-filter-panel,
|
|
92
|
-
.rle-input,
|
|
93
|
-
.rle-range,
|
|
94
|
-
.rle-select,
|
|
95
|
-
.rle-dropdown,
|
|
96
|
-
.rle-dropdown-panel,
|
|
97
|
-
.rle-checkbox,
|
|
98
|
-
.rle-label,
|
|
99
|
-
.rle-btn {
|
|
79
|
+
[class^='rle-'],
|
|
80
|
+
[class*=' rle-'] {
|
|
100
81
|
box-sizing: border-box;
|
|
101
82
|
font-family: var(--rle-font-sans);
|
|
102
83
|
}
|
|
@@ -576,26 +557,6 @@
|
|
|
576
557
|
font-size: var(--rle-fs-sm);
|
|
577
558
|
}
|
|
578
559
|
|
|
579
|
-
/* -----------------------------------------------------------------------
|
|
580
|
-
* Motion
|
|
581
|
-
* --------------------------------------------------------------------- */
|
|
582
|
-
|
|
583
|
-
@media (prefers-reduced-motion: reduce) {
|
|
584
|
-
.rle-card[type='button'],
|
|
585
|
-
.rle-popup-close,
|
|
586
|
-
.rle-skeleton,
|
|
587
|
-
.rle-input,
|
|
588
|
-
.rle-select,
|
|
589
|
-
.rle-dropdown,
|
|
590
|
-
.rle-btn,
|
|
591
|
-
.rle-viewtoggle__btn,
|
|
592
|
-
.rle-sheet,
|
|
593
|
-
.rle-sheet-backdrop {
|
|
594
|
-
transition: none;
|
|
595
|
-
animation: none;
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
|
|
599
560
|
/* -----------------------------------------------------------------------
|
|
600
561
|
* Layout shell -- the responsive "filter bar + list/map split" chrome
|
|
601
562
|
* `StyledListingLayout` composes the `~/react` structure-only components
|
|
@@ -606,32 +567,6 @@
|
|
|
606
567
|
* the same property, so there is exactly one source of truth per viewport.
|
|
607
568
|
* --------------------------------------------------------------------- */
|
|
608
569
|
|
|
609
|
-
.rle-app,
|
|
610
|
-
.rle-filter-bar,
|
|
611
|
-
.rle-filter-bar__end,
|
|
612
|
-
.rle-filters-row,
|
|
613
|
-
.rle-filter-stack,
|
|
614
|
-
.rle-filter-group,
|
|
615
|
-
.rle-body,
|
|
616
|
-
.rle-split,
|
|
617
|
-
.rle-list,
|
|
618
|
-
.rle-list-grid,
|
|
619
|
-
.rle-map,
|
|
620
|
-
.rle-bottom-nav,
|
|
621
|
-
.rle-viewtoggle,
|
|
622
|
-
.rle-viewtoggle__btn,
|
|
623
|
-
.rle-sheet-backdrop,
|
|
624
|
-
.rle-sheet,
|
|
625
|
-
.rle-sheet__handle,
|
|
626
|
-
.rle-sheet__header,
|
|
627
|
-
.rle-sheet__title,
|
|
628
|
-
.rle-sheet__close,
|
|
629
|
-
.rle-sheet__body,
|
|
630
|
-
.rle-sheet__footer {
|
|
631
|
-
box-sizing: border-box;
|
|
632
|
-
font-family: var(--rle-font-sans);
|
|
633
|
-
}
|
|
634
|
-
|
|
635
570
|
.rle-app {
|
|
636
571
|
display: flex;
|
|
637
572
|
flex-direction: column;
|
|
@@ -641,11 +576,16 @@
|
|
|
641
576
|
}
|
|
642
577
|
|
|
643
578
|
/* -----------------------------------------------------------------------
|
|
644
|
-
* Desktop filter bar -- hidden below 1024px in favor of the
|
|
579
|
+
* Desktop filter bar -- hidden below 1024px in favor of the mobile header's
|
|
645
580
|
* Filters button + bottom sheet.
|
|
646
581
|
* --------------------------------------------------------------------- */
|
|
647
582
|
|
|
648
|
-
|
|
583
|
+
/* Sticky top chrome shared with `.rle-mobile-header` -- the two
|
|
584
|
+
viewport-exclusive top bars. (`display: none` on whichever is inactive
|
|
585
|
+
makes the sticky properties inert, so sharing them unconditionally is
|
|
586
|
+
safe.) */
|
|
587
|
+
.rle-filter-bar,
|
|
588
|
+
.rle-mobile-header {
|
|
649
589
|
position: sticky;
|
|
650
590
|
top: 0;
|
|
651
591
|
z-index: 10;
|
|
@@ -751,15 +691,10 @@
|
|
|
751
691
|
|
|
752
692
|
@media (max-width: 1023px) {
|
|
753
693
|
.rle-mobile-header {
|
|
754
|
-
position: sticky;
|
|
755
|
-
top: 0;
|
|
756
|
-
z-index: 10;
|
|
757
694
|
display: flex;
|
|
758
695
|
align-items: center;
|
|
759
696
|
gap: 8px;
|
|
760
697
|
padding: var(--rle-space);
|
|
761
|
-
background: var(--rle-surface);
|
|
762
|
-
border-bottom: 1px solid var(--rle-border);
|
|
763
698
|
}
|
|
764
699
|
}
|
|
765
700
|
|
|
@@ -768,25 +703,16 @@
|
|
|
768
703
|
min-width: 0;
|
|
769
704
|
}
|
|
770
705
|
|
|
706
|
+
/* Modifier over `.rle-btn` (the shared button primitive -- hover, focus
|
|
707
|
+
ring, transition and reduced-motion behavior all come from there):
|
|
708
|
+
slightly taller, tighter header buttons. */
|
|
771
709
|
.rle-mobile-header__btn {
|
|
772
|
-
display: inline-flex;
|
|
773
710
|
flex-shrink: 0;
|
|
774
|
-
align-items: center;
|
|
775
|
-
justify-content: center;
|
|
776
711
|
gap: 6px;
|
|
777
712
|
height: 40px;
|
|
778
713
|
padding: 0 12px;
|
|
779
|
-
background: var(--rle-surface);
|
|
780
|
-
border: 1px solid var(--rle-border);
|
|
781
|
-
border-radius: var(--rle-radius-sm);
|
|
782
|
-
color: var(--rle-fg);
|
|
783
714
|
font-size: var(--rle-fs-sm);
|
|
784
|
-
font-weight: 500;
|
|
785
715
|
white-space: nowrap;
|
|
786
|
-
cursor: pointer;
|
|
787
|
-
transition:
|
|
788
|
-
background-color 150ms ease,
|
|
789
|
-
border-color 150ms ease;
|
|
790
716
|
}
|
|
791
717
|
|
|
792
718
|
.rle-mobile-header__btn svg {
|
|
@@ -794,15 +720,6 @@
|
|
|
794
720
|
height: 18px;
|
|
795
721
|
}
|
|
796
722
|
|
|
797
|
-
.rle-mobile-header__btn:hover {
|
|
798
|
-
background: var(--rle-muted-bg);
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
.rle-mobile-header__btn:focus-visible {
|
|
802
|
-
outline: none;
|
|
803
|
-
box-shadow: 0 0 0 3px var(--rle-ring);
|
|
804
|
-
}
|
|
805
|
-
|
|
806
723
|
.rle-mobile-header__btn--icon {
|
|
807
724
|
width: 40px;
|
|
808
725
|
padding: 0;
|
|
@@ -1097,3 +1014,18 @@
|
|
|
1097
1014
|
padding: var(--rle-space);
|
|
1098
1015
|
border-top: 1px solid var(--rle-border);
|
|
1099
1016
|
}
|
|
1017
|
+
|
|
1018
|
+
/* -----------------------------------------------------------------------
|
|
1019
|
+
* Motion -- LAST on purpose: prefix-scoped like the base reset (every
|
|
1020
|
+
* `rle-` element goes still, so a new component with a transition can't be
|
|
1021
|
+
* forgotten here), and every transition/animation above shares this rule's
|
|
1022
|
+
* single-class specificity, so it must come later in the file to win.
|
|
1023
|
+
* --------------------------------------------------------------------- */
|
|
1024
|
+
|
|
1025
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1026
|
+
[class^='rle-'],
|
|
1027
|
+
[class*=' rle-'] {
|
|
1028
|
+
transition: none;
|
|
1029
|
+
animation: none;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-listing-engine",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.7",
|
|
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": [
|
|
@@ -69,7 +69,6 @@
|
|
|
69
69
|
"peerDependencies": {
|
|
70
70
|
"@googlemaps/js-api-loader": ">=1",
|
|
71
71
|
"@googlemaps/markerclusterer": ">=2",
|
|
72
|
-
"@radix-ui/react-slot": ">=1",
|
|
73
72
|
"react": ">=18",
|
|
74
73
|
"react-dom": ">=18"
|
|
75
74
|
},
|
|
@@ -79,19 +78,8 @@
|
|
|
79
78
|
},
|
|
80
79
|
"@googlemaps/markerclusterer": {
|
|
81
80
|
"optional": true
|
|
82
|
-
},
|
|
83
|
-
"@radix-ui/react-slot": {
|
|
84
|
-
"optional": true
|
|
85
81
|
}
|
|
86
82
|
},
|
|
87
|
-
"scripts": {
|
|
88
|
-
"build": "tsup",
|
|
89
|
-
"test": "vitest run",
|
|
90
|
-
"test:watch": "vitest",
|
|
91
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
92
|
-
"lint": "eslint .",
|
|
93
|
-
"release": "changeset publish"
|
|
94
|
-
},
|
|
95
83
|
"devDependencies": {
|
|
96
84
|
"@changesets/cli": "^2.31.1",
|
|
97
85
|
"@googlemaps/js-api-loader": "^2.1.1",
|
|
@@ -105,20 +93,23 @@
|
|
|
105
93
|
"eslint": "^10.8.0",
|
|
106
94
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
107
95
|
"happy-dom": "^20.11.1",
|
|
108
|
-
"lucide-react": "^1.26.0",
|
|
109
96
|
"tsup": "^8.5.1",
|
|
110
97
|
"typescript": "^5.9.3",
|
|
111
98
|
"typescript-eslint": "^8.65.0",
|
|
112
99
|
"vitest": "^4.1.10"
|
|
113
100
|
},
|
|
114
|
-
"dependencies": {
|
|
115
|
-
"clsx": "^2.1.1",
|
|
116
|
-
"tailwind-merge": "^3.6.0"
|
|
117
|
-
},
|
|
118
101
|
"engines": {
|
|
119
102
|
"node": ">=18"
|
|
120
103
|
},
|
|
121
104
|
"publishConfig": {
|
|
122
105
|
"access": "public"
|
|
106
|
+
},
|
|
107
|
+
"scripts": {
|
|
108
|
+
"build": "tsup",
|
|
109
|
+
"test": "vitest run",
|
|
110
|
+
"test:watch": "vitest",
|
|
111
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
112
|
+
"lint": "eslint .",
|
|
113
|
+
"release": "changeset publish"
|
|
123
114
|
}
|
|
124
|
-
}
|
|
115
|
+
}
|
package/dist/chunk-OXSYNZAJ.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
var z=class{state;listeners=new Set;constructor(e){this.state=this.freezeState({filters:{...e.filters},results:{items:[],nextCursor:null},bounds:null,selection:null,pagination:{mode:e.mode??"paged",loading:!1},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})}setLayerVisible(e,i){this.setState({layers:{...this.state.layers,[e]:i}})}setLoading(e){this.setState({pagination:{...this.state.pagination,loading: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 M=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(),r=e.filter(s=>this.defs.has(s));r.forEach((s,o)=>{this.defs.get(s).order=o});let n=new Set(r);return i.filter(s=>!n.has(s.key)).forEach((s,o)=>{s.order=r.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(r=>Object.hasOwn(e,r.key)).map(r=>r.toParams(e[r.key])).reduce((r,n)=>({...r,...n}),{})}activeKeys(e){return this.list().filter(i=>i.isActive?.(e)).map(i=>i.key)}};var V=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 U=class{map=new Map;dispose(){this.map.clear()}emit(e){let i=this.map.get(e.type);if(i)for(let n of[...i])n(e);let r=this.map.get("*");if(r)for(let n of[...r])n(e)}on(e,i){let r=this.map.get(e);return r||(r=new Set,this.map.set(e,r)),r.add(i),()=>{r.delete(i)}}};var ge={pagination:"paged",pageSize:20,debounceMs:250};var K=class{options;constructor(e){this.options=Object.freeze({...ge,...e})}};var $=class{filters;map;datasets;primaryDatasetId;store;emitter=new U;config;debounceTimer=null;debounceResolve=null;queryToken=0;pointsToken=0;constructor(e){this.datasets=e.datasets,this.filters=e.filters??new M,this.map=e.map,this.config=new K(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 z({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,r=this.config.options.debounceMs;return r<=0?this.runQuery(i):new Promise(n=>{this.debounceResolve=n,this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.debounceResolve=null,n(this.runQuery(i))},r)})}async loadPage(){let e=this.state.results.nextCursor;if(e===null)return;let i=++this.queryToken,r=this.primaryDataset();this.store.setLoading(!0);try{let n=await r.adapter.list(this.currentFilters(),{cursor:e,limit:this.config.options.pageSize});if(i!==this.queryToken)return;this.config.options.pagination==="infinite"?this.store.appendResults(n):this.store.setResults(n),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:n.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(),r=++this.pointsToken;await Promise.allSettled(this.datasets.visibleIds().map(async n=>{let s=this.datasets.get(n);if(!s)return;let o=await s.adapter.getPoints(i,e);r===this.pointsToken&&this.store.setPoints(n,o)}))}selectPoint(e,i){this.store.setSelection(i);let r=this.state.points[e]?.find(n=>n.id===i);r&&this.emitter.emit({type:"PointClicked",datasetId:e,id:i,entity:r.entity})}toggleLayer(e){let r=!(this.state.layers[e]??!0);this.store.setLayerVisible(e,r),this.emitter.emit({type:"LayerToggled",datasetId:e,visible:r})}subscribe(e){return this.store.subscribe(e)}on(e,i){return this.emitter.on(e,i)}dispose(){this.clearDebounce(),this.emitter.dispose()}async runQuery(e){if(e!==this.queryToken)return;let i=this.primaryDataset();this.store.setLoading(!0);try{let r=await i.adapter.list(this.currentFilters(),{cursor:null,limit:this.config.options.pageSize});if(e!==this.queryToken)return;this.store.setResults(r),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:r.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 fe(...t){let e={config:{},filters:new M,datasets:new V};for(let i of t)i(e);return e}var ye=t=>e=>{e.config={...e.config,...t}},he=t=>e=>{e.map=t},ve=t=>e=>{e.datasets.add(t)},Le=t=>e=>{t(e.filters)},pi=t=>e=>{e.urlSync=t},be=t=>e=>{e.initialFilters=t},ci=t=>e=>{e.primaryDatasetId=t};import{createContext as Ze,useContext as Xe}from"react";import{jsx as F,jsxs as dt}from"react/jsx-runtime";function Je(t){return String(t?.title??"")}var Ye=({item:t})=>F("div",{children:Je(t)}),et=()=>F("div",{}),tt=()=>F("div",{}),it=({children:t})=>F("div",{children:t}),rt=({children:t})=>F("div",{children:t}),nt=({value:t,onChange:e,placeholder:i})=>F("input",{type:"search",value:t,placeholder:i,onChange:r=>e(r.target.value),"aria-label":i??"Search"}),st=()=>F("div",{role:"status",children:"No results"}),ot=()=>F("div",{role:"status","aria-busy":"true",children:"Loading\u2026"}),at=({count:t})=>dt("div",{children:[t," results"]}),lt=({children:t})=>F("div",{children:t}),b={Card:Ye,Marker:et,Popup:tt,Sidebar:it,FilterPanel:rt,Search:nt,Empty:st,Loading:ot,ResultHeader:at,Toolbar:lt},Te=Ze(b);function Pe(t){let{Card:e,Marker:i,Popup:r,Sidebar:n,FilterPanel:s,Search:o,Empty:a,Loading:l,ResultHeader:y,Toolbar:d,children:v}=t,T={Card:e??b.Card,Marker:i??b.Marker,Popup:r??b.Popup,Sidebar:n??b.Sidebar,FilterPanel:s??b.FilterPanel,Search:o??b.Search,Empty:a??b.Empty,Loading:l??b.Loading,ResultHeader:y??b.ResultHeader,Toolbar:d??b.Toolbar};return F(Te.Provider,{value:T,children:v})}function P(){return Xe(Te)}import{createContext as pt}from"react";var W=pt(null);import{useContext as ct}from"react";function f(){let t=ct(W);if(t===null)throw new Error("useListing must be used within a <ListingProvider>");return t}import{useCallback as Fe,useSyncExternalStore as ut}from"react";function C(){let t=f(),e=Fe(r=>t.subscribe(r),[t]),i=Fe(()=>t.state,[t]);return ut(e,i,i)}import{useCallback as Ce}from"react";function q(){let t=f(),e=C(),i=Ce(n=>t.applyFilters(n),[t]),r=Ce((n,s)=>t.applyFilters({[n]:s}),[t]);return{filters:e.filters,set:i,setField:r}}import{jsx as A,jsxs as mt}from"react/jsx-runtime";function J({className:t,groupClassName:e,hideLabels:i}={}){let r=f(),{FilterPanel:n}=P(),{filters:s}=q();return A(n,{children:A("div",{className:t??"space-y-5",children:r.filters.list().map(o=>{if(typeof o.render=="string")return A("div",{"data-filter":o.key,className:e},o.key);let a=o.render;return mt("div",{className:e,children:[o.label&&!i&&A("div",{className:"mb-1.5 text-[13px] font-medium text-foreground",children:o.label}),A(a,{value:o.fromParams(s),onChange:l=>{r.applyFilters(o.toParams(l))}})]},o.key)})})})}function D(){return C().results}import{jsx as j}from"react/jsx-runtime";function gt(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 Se({className:t}={}){let e=f(),{items:i}=D(),{pagination:r,selection:n}=C(),{Card:s,Empty:o,Loading:a}=P();return r.loading&&i.length===0?j(a,{}):i.length===0?j(o,{}):j("div",{role:"list",className:t,children:i.map((l,y)=>{let d=gt(l,y);return j(s,{item:l,selected:n===d,onSelect:()=>e.selectPoint(e.primaryDatasetId,d)},d)})})}import{useEffect as Y,useRef as H,useState as ft}from"react";import{jsx as vt}from"react/jsx-runtime";var yt={west:-179.9,south:-85,east:179.9,north:85},Ie=.1,we=.02;function ht(t){if(t.length===0)return null;let e=t[0].lng,i=t[0].lng,r=t[0].lat,n=t[0].lat;for(let{lat:a,lng:l}of t)l<e&&(e=l),l>i&&(i=l),a<r&&(r=a),a>n&&(n=a);let s=n>r?(n-r)*Ie:we,o=i>e?(i-e)*Ie:we;return{west:e-o,east:i+o,south:r-s,north:n+s}}function ke(t){let{center:e,zoom:i,fallback:r}=t,n=f(),s=C(),o=H(null),a=H(null),[l,y]=ft(!1),d=H(!1),v=H(!1),T=H(!1),u=n.map;return Y(()=>{let L=a.current;if(!u||!L)return;let c=[];for(let m of Object.keys(s.points)){if(s.layers[m]===!1)continue;let h=n.datasets.get(m),S=s.points[m]??[],x={id:m,markers:S.map(k=>({id:k.id,position:k.position,iconUrl:h?.marker.iconUrl?.(k.entity),element:h?.marker.element?.(k.entity)})),clustering:h?.clustering,onMarkerClick:k=>n.selectPoint(m,k)};c.push(u.renderLayer(L,x))}return()=>{c.forEach(m=>m())}},[n,u,l,s.points,s.layers]),Y(()=>{if(!o.current||!u)return;let L=o.current,c=!1,m=null;return(async()=>{let h=await u.mount(L,{center:e,zoom:i});if(c){u.destroy(h);return}a.current=h,m=u.onBoundsChange(h,S=>{T.current?T.current=!1:v.current=!0,n.loadPoints(S)}),y(!0),n.loadPoints(yt)})(),()=>{c=!0,m?.(),a.current&&(u.destroy(a.current),a.current=null),y(!1)}},[n,u]),Y(()=>{let L=a.current;if(!u||!L||e||d.current||v.current)return;let c=[];for(let h of Object.keys(s.points))if(s.layers[h]!==!1)for(let S of s.points[h]??[])c.push(S.position);let m=ht(c);m&&(d.current=!0,T.current=!0,u.fitBounds(L,m))},[u,e,l,s.points,s.layers]),vt("div",{ref:o,className:!u&&r?"flex h-full min-h-0 w-full items-center justify-center":"h-full min-h-0 w-full",children:!u&&r})}import{jsx as Lt}from"react/jsx-runtime";function Ee(){let t=f(),{results:e,pagination:i}=C();return e.nextCursor==null?null:Lt("button",{type:"button",disabled:i.loading,onClick:()=>{t.loadPage()},children:"Load more"})}import{jsx as bt}from"react/jsx-runtime";function xe(){let{items:t,total:e}=D(),{ResultHeader:i}=P();return bt(i,{count:t.length,total:e})}import{useEffect as Tt,useRef as Pt}from"react";function Ne(t,e){let i=f(),r=Pt(e);r.current=e,Tt(()=>i.on(t,n=>r.current(n)),[i,t])}import{useEffect as Ft,useState as Re}from"react";import{jsx as Ct}from"react/jsx-runtime";function Me(t){let{children:e,...i}=t,[r]=Re(()=>i),[n,s]=Re(null);return Ft(()=>{let o=new $({datasets:r.datasets,filters:r.filters,config:r.config,map:r.map,initialFilters:r.initialFilters,primaryDatasetId:r.primaryDatasetId});return r.urlSync&&r.urlSync.start(o),s(o),()=>{r.urlSync&&r.urlSync.stop(),o.dispose(),s(a=>a===o?null:a)}},[r]),n?Ct(W.Provider,{value:n,children:e}):null}function _(t){return typeof t!="number"?t:new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(t)}import{Fragment as It,jsx as I,jsxs as De}from"react/jsx-runtime";function St(t){return t?"rle-card rle-card--selected":"rle-card"}function ee({item:t,selected:e,onSelect:i}){let r=t??{},n=St(e),s=De(It,{children:[r.imageUrl?I("img",{src:r.imageUrl,alt:r.title??"",className:"rle-card-media"}):I("div",{className:"rle-card-media rle-card-media--placeholder","aria-hidden":"true"}),De("div",{className:"rle-card-body",children:[r.title&&I("span",{className:"rle-card-title",children:r.title}),r.subtitle&&I("span",{className:"rle-card-address",children:r.subtitle}),r.badge&&I("div",{className:"rle-card-info",children:I("span",{className:"rle-card-info-item",children:r.badge})}),r.price!=null&&I("span",{className:"rle-card-price",children:_(r.price)})]})]});return i?I("button",{type:"button",onClick:i,"aria-pressed":e??!1,className:n,children:s}):I("article",{className:n,children:s})}import{jsx as Q,jsxs as _e}from"react/jsx-runtime";function te(t){return _e("div",{role:"status",className:"rle-empty",children:[_e("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:[Q("circle",{cx:"11",cy:"11",r:"7"}),Q("path",{d:"m21 21-4.3-4.3"})]}),Q("p",{className:"rle-empty-title",children:"No results"}),Q("p",{className:"rle-empty-hint",children:"Try adjusting your filters or search terms."})]})}import{jsx as wt}from"react/jsx-runtime";function ie({children:t}){return wt("div",{className:"rle-filter-panel",children:t})}import{jsx as G,jsxs as kt}from"react/jsx-runtime";function re(t){return G("div",{className:"rle-loading",role:"status","aria-busy":"true","aria-label":"Loading results",children:Array.from({length:3}).map((e,i)=>kt("div",{className:"rle-loading-item",children:[G("div",{className:"rle-skeleton",style:{aspectRatio:"4 / 3",width:"100%"}}),G("div",{className:"rle-skeleton",style:{height:16,width:"65%"}}),G("div",{className:"rle-skeleton",style:{height:12,width:"35%"}})]},i))})}import{jsx as Et}from"react/jsx-runtime";function ne({point:t}){let e=t.entity??{};return Et("span",{className:"rle-pin",children:e.price!=null?_(e.price):""})}import{jsx as O,jsxs as se}from"react/jsx-runtime";function oe({entity:t,onClose:e}){let i=t??{};return se("div",{className:"rle-popup",role:"group","aria-label":"Location details",children:[O("button",{type:"button",onClick:e,"aria-label":"Close",className:"rle-popup-close",children:se("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:[O("path",{d:"M18 6 6 18"}),O("path",{d:"m6 6 12 12"})]})}),se("div",{children:[i.title&&O("div",{className:"rle-card-title",children:i.title}),i.subtitle&&O("div",{className:"rle-card-address",children:i.subtitle}),i.price!=null&&O("div",{className:"rle-card-price",children:_(i.price)})]})]})}import{jsx as xt}from"react/jsx-runtime";function ae({count:t,total:e}){let i=e!=null&&e!==t?`${t} of ${e} results`:`${t} results`;return xt("div",{className:"rle-result-header",children:i})}import{jsx as Nt}from"react/jsx-runtime";function le({value:t,onChange:e,placeholder:i}){return Nt("input",{type:"search",value:t,placeholder:i,onChange:r=>e(r.target.value),"aria-label":i??"Search",className:"rle-input"})}import{jsx as Rt}from"react/jsx-runtime";function de({children:t}){return Rt("aside",{className:"rle-sidebar",children:t})}import{jsx as Mt}from"react/jsx-runtime";function pe({children:t}){return Mt("div",{className:"rle-toolbar",children:t})}var Oe={Card:ee,Marker:ne,Popup:oe,Sidebar:de,FilterPanel:ie,Search:le,Empty:te,Loading:re,ResultHeader:ae,Toolbar:pe};import{jsx as p,jsxs as N}from"react/jsx-runtime";function Be({view:t,onViewChange:e}){return p("nav",{className:"rle-bottom-nav","aria-label":"Listing navigation",children:N("div",{className:"rle-viewtoggle",role:"group","aria-label":"View",children:[N("button",{type:"button",className:`rle-viewtoggle__btn${t==="list"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":t==="list",onClick:()=>e("list"),children:[p(Dt,{}),"List"]}),N("button",{type:"button",className:`rle-viewtoggle__btn${t==="map"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":t==="map",onClick:()=>e("map"),children:[p(_t,{}),"Map"]})]})})}function Ae(){return N("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 Dt(){return N("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:[p("line",{x1:"8",y1:"6",x2:"20",y2:"6"}),p("line",{x1:"8",y1:"12",x2:"20",y2:"12"}),p("line",{x1:"8",y1:"18",x2:"20",y2:"18"}),p("line",{x1:"4",y1:"6",x2:"4.01",y2:"6"}),p("line",{x1:"4",y1:"12",x2:"4.01",y2:"12"}),p("line",{x1:"4",y1:"18",x2:"4.01",y2:"18"})]})}function _t(){return N("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:[p("polygon",{points:"1 6 8 3 16 6 23 3 23 18 16 21 8 18 1 21 1 6"}),p("line",{x1:"8",y1:"3",x2:"8",y2:"18"}),p("line",{x1:"16",y1:"6",x2:"16",y2:"21"})]})}function He(){return N("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{useEffect as ce,useRef as Ot,useState as ze}from"react";import{createPortal as Bt}from"react-dom";import{Fragment as Ht,jsx as w,jsxs as Z}from"react/jsx-runtime";function Ve({open:t,onOpenChange:e,title:i,children:r,footer:n}){let s=Ot(null),[o,a]=ze(!1),[l,y]=ze(!1);return ce(()=>{if(!t){y(!1),a(!1);return}a(!0);let d=requestAnimationFrame(()=>y(!0));return()=>cancelAnimationFrame(d)},[t]),ce(()=>{if(!o)return;let d=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=d}},[o]),ce(()=>{if(!o)return;s.current?.focus();function d(v){v.key==="Escape"&&e(!1)}return document.addEventListener("keydown",d),()=>document.removeEventListener("keydown",d)},[o,e]),!o||typeof document>"u"?null:Bt(Z(Ht,{children:[w("div",{className:`rle-sheet-backdrop${l?" rle-sheet-backdrop--open":""}`,onClick:()=>e(!1),"aria-hidden":"true"}),Z("div",{ref:s,className:`rle-sheet${l?" rle-sheet--open":""}`,role:"dialog","aria-modal":"true","aria-label":i,tabIndex:-1,children:[w("div",{className:"rle-sheet__handle","aria-hidden":"true"}),Z("div",{className:"rle-sheet__header",children:[i&&w("div",{className:"rle-sheet__title",children:i}),w("button",{type:"button",className:"rle-sheet__close",onClick:()=>e(!1),"aria-label":"Close",children:w(At,{})})]}),w("div",{className:"rle-sheet__body",children:r}),n&&w("div",{className:"rle-sheet__footer",children:n})]})]}),document.body)}function At(){return Z("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:[w("path",{d:"M18 6 6 18"}),w("path",{d:"m6 6 12 12"})]})}import{useEffect as $e,useRef as zt,useState as X}from"react";import{jsx as R,jsxs as Ue}from"react/jsx-runtime";function Ke({search:t,onFiltersClick:e,filterCount:i=0,action:r}){let{Search:n}=P();return Ue("header",{className:"rle-mobile-header",children:[t&&R("div",{className:"rle-mobile-header__search",children:R(n,{value:t.value,onChange:t.onChange,placeholder:t.placeholder})}),Ue("button",{type:"button",className:"rle-mobile-header__btn",onClick:e,children:[R(Ae,{}),R("span",{children:"Filters"}),i>0&&R("span",{className:"rle-mobile-header__count",children:i})]}),r&&R("button",{type:"button",className:"rle-mobile-header__btn rle-mobile-header__btn--icon",onClick:r.onClick,"aria-label":r.label,children:r.icon??R(He,{})})]})}import{Fragment as Kt,jsx as g,jsxs as E}from"react/jsx-runtime";var Vt=g("div",{className:"rle-empty",children:"Map unavailable"});function Ut(){let t=zt(null),[e,i]=X(!0),[r,n]=X(!0);return $e(()=>{let s=t.current;if(!s)return;let o=()=>{let{clientWidth:y,scrollLeft:d,scrollWidth:v}=s;i(d<=0),n(d+y>=v-1)};o(),s.addEventListener("scroll",o,{passive:!0});let a,l;return typeof ResizeObserver<"u"&&(a=new ResizeObserver(o),a.observe(s)),typeof MutationObserver<"u"&&(l=new MutationObserver(o),l.observe(s,{characterData:!0,childList:!0,subtree:!0})),()=>{s.removeEventListener("scroll",o),a?.disconnect(),l?.disconnect()}},[]),{atEnd:r,atStart:e,ref:t}}function We({search:t,toolbarEnd:e,mobileAction:i,autoFetch:r=!0,hasMap:n=!0,mapCenter:s,mapZoom:o,className:a}){let l=f(),{Search:y}=P(),d=D(),{filters:v}=q(),[T,u]=X("list"),[L,c]=X(!1),{atEnd:m,atStart:h,ref:S}=Ut(),x=t?{value:String(v[t.filterKey]??""),onChange:B=>{l.applyFilters({[t.filterKey]:B||void 0})},placeholder:t.placeholder}:void 0;$e(()=>{r!==!1&&l.applyFilters({})},[l,r]);let k=()=>{let B=l.filters.list().reduce((Ge,me)=>Object.assign(Ge,me.toParams(me.fromParams({}))),{});l.applyFilters(B)},je=l.filters.list().filter(B=>B.isActive?.(v)).length,Qe=d.total??d.items.length;return E("div",{className:a?`rle-app ${a}`:"rle-app",children:[E("div",{className:"rle-filter-bar",children:[E("div",{className:"rle-filter-bar__scroll",ref:S,children:[x&&g("div",{className:"rle-filter-bar__search",children:g(y,{value:x.value,onChange:x.onChange,placeholder:x.placeholder})}),g(J,{className:"rle-filters-row",groupClassName:"rle-filter-group",hideLabels:!0})]}),!h&&g("div",{className:"rle-filter-bar__fade rle-filter-bar__fade--start","aria-hidden":"true"}),!m&&g("div",{className:"rle-filter-bar__fade rle-filter-bar__fade--end","aria-hidden":"true"})]}),g(Ke,{search:x,onFiltersClick:()=>c(!0),filterCount:je,action:i}),E("div",{className:`rle-body ${n?"rle-split":"rle-body--list-only"}`,"data-mobile-view":T,children:[E("div",{className:"rle-list",children:[E("div",{className:"rle-list-header",children:[g(xe,{}),e&&g("div",{className:"rle-list-header__toolbar",children:e})]}),g(Se,{className:"rle-list-grid"}),g(Ee,{})]}),n&&g("div",{className:"rle-map",children:g(ke,{center:s,zoom:o,fallback:Vt})})]}),n&&g(Be,{view:T,onViewChange:u}),g(Ve,{title:"Filters",open:L,onOpenChange:c,footer:E(Kt,{children:[g("button",{type:"button",className:"rle-btn rle-btn--ghost",onClick:k,children:"Clear all"}),E("button",{type:"button",className:"rle-btn rle-btn--primary",onClick:()=>c(!1),children:["Show ",Qe," results"]})]}),children:g(J,{className:"rle-filter-stack",groupClassName:"rle-filter-group"})})]})}import{useEffect as $t,useRef as Wt,useState as qt}from"react";import{jsx as ue,jsxs as Gt}from"react/jsx-runtime";function qe(t){return"provider"in t}function jt(t){let e=t!=null&&!qe(t),i=e?t.apiKey:void 0,r=e?t.mapId:void 0,[n,s]=qt(()=>!t||qe(t)?{ready:!0,provider:t?.provider}:{ready:!1});return $t(()=>{if(!i)return;let o=!1;return import("./maps/google/index.js").then(({googleProvider:a})=>{o||s({ready:!0,provider:a({apiKey:i,mapId:r})})}),()=>{o=!0}},[i,r]),n}function Qt({onFiltersChange:t}){let e=Wt(t);return e.current=t,Ne("FiltersChanged",i=>{i.type==="FiltersChanged"&&e.current(i.filters)}),null}function gn(t){let{datasets:e,filters:i,map:r,components:n,initialFilters:s,onFiltersChange:o,mobileAction:a,search:l,toolbarEnd:y,config:d,autoFetch:v,className:T}=t,{ready:u,provider:L}=jt(r);if(!u)return null;let c=[];for(let S of e)c.push(ve(S));i&&c.push(Le(i)),L&&c.push(he(L)),s&&c.push(be(s)),d&&c.push(ye(d));let m=fe(...c),h={...Oe,...n};return Gt(Me,{...m,children:[o&&ue(Qt,{onFiltersChange:o}),ue(Pe,{...h,children:ue(We,{className:T,search:l,toolbarEnd:y,mobileAction:a,autoFetch:v,hasMap:r!=null,mapCenter:r?.center,mapZoom:r?.zoom})})]})}export{z as a,M as b,V as c,U as d,ge as e,K as f,$ as g,fe as h,ye as i,he as j,ve as k,Le as l,pi as m,be as n,ci as o,Pe as p,P as q,W as r,f as s,C as t,q as u,J as v,D as w,Se as x,ke as y,Ee as z,xe as A,Ne as B,Me as C,ee as D,te as E,ie as F,re as G,ne as H,oe as I,ae as J,le as K,de as L,pe as M,Oe as N,Be as O,Ve as P,We as Q,gn as R};
|
package/dist/chunk-PE27NATS.cjs
DELETED
|
@@ -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 z= (_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,pagination:{mode:_nullishCoalesce(e.mode, () => ("paged")),loading:!1},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})}setLayerVisible(e,i){this.setState({layers:{...this.state.layers,[e]:i}})}setLoading(e){this.setState({pagination:{...this.state.pagination,loading: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 M= (_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(),r=e.filter(s=>this.defs.has(s));r.forEach((s,o)=>{this.defs.get(s).order=o});let n=new Set(r);return i.filter(s=>!n.has(s.key)).forEach((s,o)=>{s.order=r.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(r=>Object.hasOwn(e,r.key)).map(r=>r.toParams(e[r.key])).reduce((r,n)=>({...r,...n}),{})}activeKeys(e){return this.list().filter(i=>_optionalChain([i, 'access', _2 => _2.isActive, 'optionalCall', _3 => _3(e)])).map(i=>i.key)}}, _class2);var V= (_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 U= (_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 n of[...i])n(e);let r=this.map.get("*");if(r)for(let n of[...r])n(e)}on(e,i){let r=this.map.get(e);return r||(r=new Set,this.map.set(e,r)),r.add(i),()=>{r.delete(i)}}}, _class4);var ge={pagination:"paged",pageSize:20,debounceMs:250};var K=class{constructor(e){this.options=Object.freeze({...ge,...e})}};var $= (_class5 =class{__init5() {this.emitter=new U}__init6() {this.debounceTimer=null}__init7() {this.debounceResolve=null}__init8() {this.queryToken=0}__init9() {this.pointsToken=0}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);this.datasets=e.datasets,this.filters=_nullishCoalesce(e.filters, () => (new M)),this.map=e.map,this.config=new K(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 z({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,r=this.config.options.debounceMs;return r<=0?this.runQuery(i):new Promise(n=>{this.debounceResolve=n,this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.debounceResolve=null,n(this.runQuery(i))},r)})}async loadPage(){let e=this.state.results.nextCursor;if(e===null)return;let i=++this.queryToken,r=this.primaryDataset();this.store.setLoading(!0);try{let n=await r.adapter.list(this.currentFilters(),{cursor:e,limit:this.config.options.pageSize});if(i!==this.queryToken)return;this.config.options.pagination==="infinite"?this.store.appendResults(n):this.store.setResults(n),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:n.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(),r=++this.pointsToken;await Promise.allSettled(this.datasets.visibleIds().map(async n=>{let s=this.datasets.get(n);if(!s)return;let o=await s.adapter.getPoints(i,e);r===this.pointsToken&&this.store.setPoints(n,o)}))}selectPoint(e,i){this.store.setSelection(i);let r=_optionalChain([this, 'access', _11 => _11.state, 'access', _12 => _12.points, 'access', _13 => _13[e], 'optionalAccess', _14 => _14.find, 'call', _15 => _15(n=>n.id===i)]);r&&this.emitter.emit({type:"PointClicked",datasetId:e,id:i,entity:r.entity})}toggleLayer(e){let r=!(_nullishCoalesce(this.state.layers[e], () => (!0)));this.store.setLayerVisible(e,r),this.emitter.emit({type:"LayerToggled",datasetId:e,visible:r})}subscribe(e){return this.store.subscribe(e)}on(e,i){return this.emitter.on(e,i)}dispose(){this.clearDebounce(),this.emitter.dispose()}async runQuery(e){if(e!==this.queryToken)return;let i=this.primaryDataset();this.store.setLoading(!0);try{let r=await i.adapter.list(this.currentFilters(),{cursor:null,limit:this.config.options.pageSize});if(e!==this.queryToken)return;this.store.setResults(r),this.emitter.emit({type:"ResultsLoaded",datasetId:this.primaryDatasetId,count:r.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 fe(...t){let e={config:{},filters:new M,datasets:new V};for(let i of t)i(e);return e}var ye=t=>e=>{e.config={...e.config,...t}},he= exports.j =t=>e=>{e.map=t},ve= exports.k =t=>e=>{e.datasets.add(t)},Le= exports.l =t=>e=>{t(e.filters)},pi= exports.m =t=>e=>{e.urlSync=t},be= exports.n =t=>e=>{e.initialFilters=t},ci= exports.o =t=>e=>{e.primaryDatasetId=t};var _react = require('react');var _jsxruntime = require('react/jsx-runtime');function Je(t){return String(_nullishCoalesce(_optionalChain([t, 'optionalAccess', _16 => _16.title]), () => ("")))}var Ye=({item:t})=>_jsxruntime.jsx.call(void 0, "div",{children:Je(t)}),et=()=>_jsxruntime.jsx.call(void 0, "div",{}),tt=()=>_jsxruntime.jsx.call(void 0, "div",{}),it=({children:t})=>_jsxruntime.jsx.call(void 0, "div",{children:t}),rt=({children:t})=>_jsxruntime.jsx.call(void 0, "div",{children:t}),nt=({value:t,onChange:e,placeholder:i})=>_jsxruntime.jsx.call(void 0, "input",{type:"search",value:t,placeholder:i,onChange:r=>e(r.target.value),"aria-label":_nullishCoalesce(i, () => ("Search"))}),st=()=>_jsxruntime.jsx.call(void 0, "div",{role:"status",children:"No results"}),ot=()=>_jsxruntime.jsx.call(void 0, "div",{role:"status","aria-busy":"true",children:"Loading\u2026"}),at=({count:t})=>_jsxruntime.jsxs.call(void 0, "div",{children:[t," results"]}),lt=({children:t})=>_jsxruntime.jsx.call(void 0, "div",{children:t}),b={Card:Ye,Marker:et,Popup:tt,Sidebar:it,FilterPanel:rt,Search:nt,Empty:st,Loading:ot,ResultHeader:at,Toolbar:lt},Te=_react.createContext.call(void 0, b);function Pe(t){let{Card:e,Marker:i,Popup:r,Sidebar:n,FilterPanel:s,Search:o,Empty:a,Loading:l,ResultHeader:y,Toolbar:d,children:v}=t,T={Card:_nullishCoalesce(e, () => (b.Card)),Marker:_nullishCoalesce(i, () => (b.Marker)),Popup:_nullishCoalesce(r, () => (b.Popup)),Sidebar:_nullishCoalesce(n, () => (b.Sidebar)),FilterPanel:_nullishCoalesce(s, () => (b.FilterPanel)),Search:_nullishCoalesce(o, () => (b.Search)),Empty:_nullishCoalesce(a, () => (b.Empty)),Loading:_nullishCoalesce(l, () => (b.Loading)),ResultHeader:_nullishCoalesce(y, () => (b.ResultHeader)),Toolbar:_nullishCoalesce(d, () => (b.Toolbar))};return _jsxruntime.jsx.call(void 0, Te.Provider,{value:T,children:v})}function P(){return _react.useContext.call(void 0, Te)}var W=_react.createContext.call(void 0, null);function f(){let t=_react.useContext.call(void 0, W);if(t===null)throw new Error("useListing must be used within a <ListingProvider>");return t}function C(){let t=f(),e=_react.useCallback.call(void 0, r=>t.subscribe(r),[t]),i=_react.useCallback.call(void 0, ()=>t.state,[t]);return _react.useSyncExternalStore.call(void 0, e,i,i)}function q(){let t=f(),e=C(),i=_react.useCallback.call(void 0, n=>t.applyFilters(n),[t]),r=_react.useCallback.call(void 0, (n,s)=>t.applyFilters({[n]:s}),[t]);return{filters:e.filters,set:i,setField:r}}function J({className:t,groupClassName:e,hideLabels:i}={}){let r=f(),{FilterPanel:n}=P(),{filters:s}=q();return _jsxruntime.jsx.call(void 0, n,{children:_jsxruntime.jsx.call(void 0, "div",{className:_nullishCoalesce(t, () => ("space-y-5")),children:r.filters.list().map(o=>{if(typeof o.render=="string")return _jsxruntime.jsx.call(void 0, "div",{"data-filter":o.key,className:e},o.key);let a=o.render;return _jsxruntime.jsxs.call(void 0, "div",{className:e,children:[o.label&&!i&&_jsxruntime.jsx.call(void 0, "div",{className:"mb-1.5 text-[13px] font-medium text-foreground",children:o.label}),_jsxruntime.jsx.call(void 0, a,{value:o.fromParams(s),onChange:l=>{r.applyFilters(o.toParams(l))}})]},o.key)})})})}function D(){return C().results}function gt(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 Se({className:t}={}){let e=f(),{items:i}=D(),{pagination:r,selection:n}=C(),{Card:s,Empty:o,Loading:a}=P();return r.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,y)=>{let d=gt(l,y);return _jsxruntime.jsx.call(void 0, s,{item:l,selected:n===d,onSelect:()=>e.selectPoint(e.primaryDatasetId,d)},d)})})}var yt={west:-179.9,south:-85,east:179.9,north:85},Ie=.1,we=.02;function ht(t){if(t.length===0)return null;let e=t[0].lng,i=t[0].lng,r=t[0].lat,n=t[0].lat;for(let{lat:a,lng:l}of t)l<e&&(e=l),l>i&&(i=l),a<r&&(r=a),a>n&&(n=a);let s=n>r?(n-r)*Ie:we,o=i>e?(i-e)*Ie:we;return{west:e-o,east:i+o,south:r-s,north:n+s}}function ke(t){let{center:e,zoom:i,fallback:r}=t,n=f(),s=C(),o=_react.useRef.call(void 0, null),a=_react.useRef.call(void 0, null),[l,y]=_react.useState.call(void 0, !1),d=_react.useRef.call(void 0, !1),v=_react.useRef.call(void 0, !1),T=_react.useRef.call(void 0, !1),u=n.map;return _react.useEffect.call(void 0, ()=>{let L=a.current;if(!u||!L)return;let c=[];for(let m of Object.keys(s.points)){if(s.layers[m]===!1)continue;let h=n.datasets.get(m),S=_nullishCoalesce(s.points[m], () => ([])),x={id:m,markers:S.map(k=>({id:k.id,position:k.position,iconUrl:_optionalChain([h, 'optionalAccess', _17 => _17.marker, 'access', _18 => _18.iconUrl, 'optionalCall', _19 => _19(k.entity)]),element:_optionalChain([h, 'optionalAccess', _20 => _20.marker, 'access', _21 => _21.element, 'optionalCall', _22 => _22(k.entity)])})),clustering:_optionalChain([h, 'optionalAccess', _23 => _23.clustering]),onMarkerClick:k=>n.selectPoint(m,k)};c.push(u.renderLayer(L,x))}return()=>{c.forEach(m=>m())}},[n,u,l,s.points,s.layers]),_react.useEffect.call(void 0, ()=>{if(!o.current||!u)return;let L=o.current,c=!1,m=null;return(async()=>{let h=await u.mount(L,{center:e,zoom:i});if(c){u.destroy(h);return}a.current=h,m=u.onBoundsChange(h,S=>{T.current?T.current=!1:v.current=!0,n.loadPoints(S)}),y(!0),n.loadPoints(yt)})(),()=>{c=!0,_optionalChain([m, 'optionalCall', _24 => _24()]),a.current&&(u.destroy(a.current),a.current=null),y(!1)}},[n,u]),_react.useEffect.call(void 0, ()=>{let L=a.current;if(!u||!L||e||d.current||v.current)return;let c=[];for(let h of Object.keys(s.points))if(s.layers[h]!==!1)for(let S of _nullishCoalesce(s.points[h], () => ([])))c.push(S.position);let m=ht(c);m&&(d.current=!0,T.current=!0,u.fitBounds(L,m))},[u,e,l,s.points,s.layers]),_jsxruntime.jsx.call(void 0, "div",{ref:o,className:!u&&r?"flex h-full min-h-0 w-full items-center justify-center":"h-full min-h-0 w-full",children:!u&&r})}function Ee(){let t=f(),{results:e,pagination:i}=C();return e.nextCursor==null?null:_jsxruntime.jsx.call(void 0, "button",{type:"button",disabled:i.loading,onClick:()=>{t.loadPage()},children:"Load more"})}function xe(){let{items:t,total:e}=D(),{ResultHeader:i}=P();return _jsxruntime.jsx.call(void 0, i,{count:t.length,total:e})}function Ne(t,e){let i=f(),r=_react.useRef.call(void 0, e);r.current=e,_react.useEffect.call(void 0, ()=>i.on(t,n=>r.current(n)),[i,t])}function Me(t){let{children:e,...i}=t,[r]=_react.useState.call(void 0, ()=>i),[n,s]=_react.useState.call(void 0, null);return _react.useEffect.call(void 0, ()=>{let o=new $({datasets:r.datasets,filters:r.filters,config:r.config,map:r.map,initialFilters:r.initialFilters,primaryDatasetId:r.primaryDatasetId});return r.urlSync&&r.urlSync.start(o),s(o),()=>{r.urlSync&&r.urlSync.stop(),o.dispose(),s(a=>a===o?null:a)}},[r]),n?_jsxruntime.jsx.call(void 0, W.Provider,{value:n,children:e}):null}function _(t){return typeof t!="number"?t:new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(t)}function St(t){return t?"rle-card rle-card--selected":"rle-card"}function ee({item:t,selected:e,onSelect:i}){let r=_nullishCoalesce(t, () => ({})),n=St(e),s=_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[r.imageUrl?_jsxruntime.jsx.call(void 0, "img",{src:r.imageUrl,alt:_nullishCoalesce(r.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:[r.title&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-title",children:r.title}),r.subtitle&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-address",children:r.subtitle}),r.badge&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-info",children:_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-info-item",children:r.badge})}),r.price!=null&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-price",children:_(r.price)})]})]});return i?_jsxruntime.jsx.call(void 0, "button",{type:"button",onClick:i,"aria-pressed":_nullishCoalesce(e, () => (!1)),className:n,children:s}):_jsxruntime.jsx.call(void 0, "article",{className:n,children:s})}function te(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 ie({children:t}){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-panel",children:t})}function re(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 ne({point:t}){let e=_nullishCoalesce(t.entity, () => ({}));return _jsxruntime.jsx.call(void 0, "span",{className:"rle-pin",children:e.price!=null?_(e.price):""})}function oe({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:_(i.price)})]})]})}function ae({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 le({value:t,onChange:e,placeholder:i}){return _jsxruntime.jsx.call(void 0, "input",{type:"search",value:t,placeholder:i,onChange:r=>e(r.target.value),"aria-label":_nullishCoalesce(i, () => ("Search")),className:"rle-input"})}function de({children:t}){return _jsxruntime.jsx.call(void 0, "aside",{className:"rle-sidebar",children:t})}function pe({children:t}){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-toolbar",children:t})}var Oe={Card:ee,Marker:ne,Popup:oe,Sidebar:de,FilterPanel:ie,Search:le,Empty:te,Loading:re,ResultHeader:ae,Toolbar:pe};function Be({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, Dt,{}),"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, _t,{}),"Map"]})]})})}function Ae(){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 Dt(){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 _t(){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 He(){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 _reactdom = require('react-dom');function Ve({open:t,onOpenChange:e,title:i,children:r,footer:n}){let s=_react.useRef.call(void 0, null),[o,a]=_react.useState.call(void 0, !1),[l,y]=_react.useState.call(void 0, !1);return _react.useEffect.call(void 0, ()=>{if(!t){y(!1),a(!1);return}a(!0);let d=requestAnimationFrame(()=>y(!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', _25 => _25.current, 'optionalAccess', _26 => _26.focus, 'call', _27 => _27()]);function d(v){v.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, At,{})})]}),_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__body",children:r}),n&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__footer",children:n})]})]}),document.body)}function At(){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 Ke({search:t,onFiltersClick:e,filterCount:i=0,action:r}){let{Search:n}=P();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, n,{value:t.value,onChange:t.onChange,placeholder:t.placeholder})}),_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:"rle-mobile-header__btn",onClick:e,children:[_jsxruntime.jsx.call(void 0, Ae,{}),_jsxruntime.jsx.call(void 0, "span",{children:"Filters"}),i>0&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-mobile-header__count",children:i})]}),r&&_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-mobile-header__btn rle-mobile-header__btn--icon",onClick:r.onClick,"aria-label":r.label,children:_nullishCoalesce(r.icon, () => (_jsxruntime.jsx.call(void 0, He,{})))})]})}var Vt=_jsxruntime.jsx.call(void 0, "div",{className:"rle-empty",children:"Map unavailable"});function Ut(){let t=_react.useRef.call(void 0, null),[e,i]=_react.useState.call(void 0, !0),[r,n]=_react.useState.call(void 0, !0);return _react.useEffect.call(void 0, ()=>{let s=t.current;if(!s)return;let o=()=>{let{clientWidth:y,scrollLeft:d,scrollWidth:v}=s;i(d<=0),n(d+y>=v-1)};o(),s.addEventListener("scroll",o,{passive:!0});let a,l;return typeof ResizeObserver<"u"&&(a=new ResizeObserver(o),a.observe(s)),typeof MutationObserver<"u"&&(l=new MutationObserver(o),l.observe(s,{characterData:!0,childList:!0,subtree:!0})),()=>{s.removeEventListener("scroll",o),_optionalChain([a, 'optionalAccess', _28 => _28.disconnect, 'call', _29 => _29()]),_optionalChain([l, 'optionalAccess', _30 => _30.disconnect, 'call', _31 => _31()])}},[]),{atEnd:r,atStart:e,ref:t}}function We({search:t,toolbarEnd:e,mobileAction:i,autoFetch:r=!0,hasMap:n=!0,mapCenter:s,mapZoom:o,className:a}){let l=f(),{Search:y}=P(),d=D(),{filters:v}=q(),[T,u]=_react.useState.call(void 0, "list"),[L,c]=_react.useState.call(void 0, !1),{atEnd:m,atStart:h,ref:S}=Ut(),x=t?{value:String(_nullishCoalesce(v[t.filterKey], () => (""))),onChange:B=>{l.applyFilters({[t.filterKey]:B||void 0})},placeholder:t.placeholder}:void 0;_react.useEffect.call(void 0, ()=>{r!==!1&&l.applyFilters({})},[l,r]);let k=()=>{let B=l.filters.list().reduce((Ge,me)=>Object.assign(Ge,me.toParams(me.fromParams({}))),{});l.applyFilters(B)},je=l.filters.list().filter(B=>_optionalChain([B, 'access', _32 => _32.isActive, 'optionalCall', _33 => _33(v)])).length,Qe=_nullishCoalesce(d.total, () => (d.items.length));return _jsxruntime.jsxs.call(void 0, "div",{className:a?`rle-app ${a}`:"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:S,children:[x&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__search",children:_jsxruntime.jsx.call(void 0, y,{value:x.value,onChange:x.onChange,placeholder:x.placeholder})}),_jsxruntime.jsx.call(void 0, J,{className:"rle-filters-row",groupClassName:"rle-filter-group",hideLabels:!0})]}),!h&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__fade rle-filter-bar__fade--start","aria-hidden":"true"}),!m&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__fade rle-filter-bar__fade--end","aria-hidden":"true"})]}),_jsxruntime.jsx.call(void 0, Ke,{search:x,onFiltersClick:()=>c(!0),filterCount:je,action:i}),_jsxruntime.jsxs.call(void 0, "div",{className:`rle-body ${n?"rle-split":"rle-body--list-only"}`,"data-mobile-view":T,children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-list",children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-list-header",children:[_jsxruntime.jsx.call(void 0, xe,{}),e&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-list-header__toolbar",children:e})]}),_jsxruntime.jsx.call(void 0, Se,{className:"rle-list-grid"}),_jsxruntime.jsx.call(void 0, Ee,{})]}),n&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-map",children:_jsxruntime.jsx.call(void 0, ke,{center:s,zoom:o,fallback:Vt})})]}),n&&_jsxruntime.jsx.call(void 0, Be,{view:T,onViewChange:u}),_jsxruntime.jsx.call(void 0, Ve,{title:"Filters",open:L,onOpenChange:c,footer:_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-btn rle-btn--ghost",onClick:k,children:"Clear all"}),_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:"rle-btn rle-btn--primary",onClick:()=>c(!1),children:["Show ",Qe," results"]})]}),children:_jsxruntime.jsx.call(void 0, J,{className:"rle-filter-stack",groupClassName:"rle-filter-group"})})]})}function qe(t){return"provider"in t}function jt(t){let e=t!=null&&!qe(t),i=e?t.apiKey:void 0,r=e?t.mapId:void 0,[n,s]=_react.useState.call(void 0, ()=>!t||qe(t)?{ready:!0,provider:_optionalChain([t, 'optionalAccess', _34 => _34.provider])}:{ready:!1});return _react.useEffect.call(void 0, ()=>{if(!i)return;let o=!1;return Promise.resolve().then(() => _interopRequireWildcard(require("./maps/google/index.cjs"))).then(({googleProvider:a})=>{o||s({ready:!0,provider:a({apiKey:i,mapId:r})})}),()=>{o=!0}},[i,r]),n}function Qt({onFiltersChange:t}){let e=_react.useRef.call(void 0, t);return e.current=t,Ne("FiltersChanged",i=>{i.type==="FiltersChanged"&&e.current(i.filters)}),null}function gn(t){let{datasets:e,filters:i,map:r,components:n,initialFilters:s,onFiltersChange:o,mobileAction:a,search:l,toolbarEnd:y,config:d,autoFetch:v,className:T}=t,{ready:u,provider:L}=jt(r);if(!u)return null;let c=[];for(let S of e)c.push(ve(S));i&&c.push(Le(i)),L&&c.push(he(L)),s&&c.push(be(s)),d&&c.push(ye(d));let m=fe(...c),h={...Oe,...n};return _jsxruntime.jsxs.call(void 0, Me,{...m,children:[o&&_jsxruntime.jsx.call(void 0, Qt,{onFiltersChange:o}),_jsxruntime.jsx.call(void 0, Pe,{...h,children:_jsxruntime.jsx.call(void 0, We,{className:T,search:l,toolbarEnd:y,mobileAction:a,autoFetch:v,hasMap:r!=null,mapCenter:_optionalChain([r, 'optionalAccess', _35 => _35.center]),mapZoom:_optionalChain([r, 'optionalAccess', _36 => _36.zoom])})})]})}exports.a = z; exports.b = M; exports.c = V; exports.d = U; exports.e = ge; exports.f = K; exports.g = $; exports.h = fe; exports.i = ye; exports.j = he; exports.k = ve; exports.l = Le; exports.m = pi; exports.n = be; exports.o = ci; exports.p = Pe; exports.q = P; exports.r = W; exports.s = f; exports.t = C; exports.u = q; exports.v = J; exports.w = D; exports.x = Se; exports.y = ke; exports.z = Ee; exports.A = xe; exports.B = Ne; exports.C = Me; exports.D = ee; exports.E = te; exports.F = ie; exports.G = re; exports.H = ne; exports.I = oe; exports.J = ae; exports.K = le; exports.L = de; exports.M = pe; exports.N = Oe; exports.O = Be; exports.P = Ve; exports.Q = We; exports.R = gn;
|